From 12fccad3f6921719a27575e6e04dbf527020abf1 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Thu, 27 Nov 2025 00:26:29 +1100 Subject: [PATCH 001/462] DOC Add info on 'array-like' array API inputs when `array_api_dispatch=False` (#32676) --- doc/glossary.rst | 6 ++++++ doc/modules/array_api.rst | 21 ++++++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/doc/glossary.rst b/doc/glossary.rst index 9ff1eb001c8e5..1f214a11b7320 100644 --- a/doc/glossary.rst +++ b/doc/glossary.rst @@ -63,6 +63,12 @@ General Concepts * a :class:`pandas.DataFrame` with all columns numeric * a numeric :class:`pandas.Series` + Other array API inputs, but see :ref:`array_api` for the preferred way of + using these: + + * a `PyTorch `_ tensor on 'cpu' device + * a `JAX `_ array + It excludes: * a :term:`sparse matrix` diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index b9b46f99f3cae..cf3d9d5890c3a 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -42,15 +42,26 @@ and how it facilitates interoperability between array libraries: - `Scikit-learn on GPUs with Array API `_ by :user:`Thomas Fan ` at PyData NYC 2023. -Example usage -============= +Enabling array API support +========================== The configuration `array_api_dispatch=True` needs to be set to `True` to enable array API support. We recommend setting this configuration globally to ensure consistent behaviour and prevent accidental mixing of array namespaces. -Note that we set it with :func:`config_context` below to avoid having to call -:func:`set_config(array_api_dispatch=False)` at the end of every code snippet -that uses the array API. +Note that in the examples below, we use a context manager (:func:`config_context`) +to avoid having to reset it to `False` at the end of every code snippet, so as to +not affect the rest of the documentation. + +Scikit-learn accepts :term:`array-like` inputs for all :mod:`metrics` +and some estimators. When `array_api_dispatch=False`, these inputs are converted +into NumPy arrays using :func:`numpy.asarray` (or :func:`numpy.array`). +While this will successfully convert some array API inputs (e.g., JAX array), +we generally recommend setting `array_api_dispatch=True` when using array API inputs. +This is because NumPy conversion can often fail, e.g., torch tensor allocated on GPU. + +Example usage +============= + The example code snippet below demonstrates how to use `CuPy `_ to run :class:`~discriminant_analysis.LinearDiscriminantAnalysis` on a GPU:: From 4f79388d953152ddb5e92bf07da5a1b46107f607 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Wed, 26 Nov 2025 23:49:55 +0100 Subject: [PATCH 002/462] MNT Bump version to 1.9.dev0 on main (#32794) --- doc/whats_new.rst | 1 + doc/whats_new/v1.9.rst | 34 ++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- sklearn/__init__.py | 2 +- 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 doc/whats_new/v1.9.rst diff --git a/doc/whats_new.rst b/doc/whats_new.rst index 1e9d0316691e1..85331dba43e42 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -15,6 +15,7 @@ Changelogs and release notes for all scikit-learn releases are linked in this pa .. toctree:: :maxdepth: 2 + whats_new/v1.9.rst whats_new/v1.8.rst whats_new/v1.7.rst whats_new/v1.6.rst diff --git a/doc/whats_new/v1.9.rst b/doc/whats_new/v1.9.rst new file mode 100644 index 0000000000000..0b7a15ba62292 --- /dev/null +++ b/doc/whats_new/v1.9.rst @@ -0,0 +1,34 @@ +.. include:: _contributors.rst + +.. currentmodule:: sklearn + +.. _release_notes_1_9: + +=========== +Version 1.9 +=========== + +.. + -- UNCOMMENT WHEN 1.9.0 IS RELEASED -- + For a short description of the main highlights of the release, please refer to + :ref:`sphx_glr_auto_examples_release_highlights_plot_release_highlights_1_9_0.py`. + + +.. + DELETE WHEN 1.9.0 IS RELEASED + Since October 2024, DO NOT add your changelog entry in this file. +.. + Instead, create a file named `..rst` in the relevant sub-folder in + `doc/whats_new/upcoming_changes/`. For full details, see: + https://github.com/scikit-learn/scikit-learn/blob/main/doc/whats_new/upcoming_changes/README.md + +.. include:: changelog_legend.inc + +.. towncrier release notes start + +.. rubric:: Code and documentation contributors + +Thanks to everyone who has contributed to the maintenance and improvement of +the project since version 1.8, including: + +TODO: update at the time of the release. diff --git a/pyproject.toml b/pyproject.toml index 4e0e4417c2d7f..f5259bb277b48 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -290,7 +290,7 @@ ignore-words = "build_tools/codespell_ignore_words.txt" [tool.towncrier] package = "sklearn" - filename = "doc/whats_new/v1.8.rst" + filename = "doc/whats_new/v1.9.rst" single_file = true directory = "doc/whats_new/upcoming_changes" issue_format = ":pr:`{issue}`" diff --git a/sklearn/__init__.py b/sklearn/__init__.py index 2bb31200ed1a5..12d63dd8b6739 100644 --- a/sklearn/__init__.py +++ b/sklearn/__init__.py @@ -42,7 +42,7 @@ # Dev branch marker is: 'X.Y.dev' or 'X.Y.devN' where N is an integer. # 'X.Y.dev0' is the canonical version of 'X.Y.dev' # -__version__ = "1.8.dev0" +__version__ = "1.9.dev0" # On OSX, we can get a runtime error due to multiple OpenMP libraries loaded From f78e850342bf92b9542bf7a4d7e2224d223c5c58 Mon Sep 17 00:00:00 2001 From: Arthur Date: Fri, 21 Nov 2025 11:38:34 +0100 Subject: [PATCH 003/462] TST: increase tolerance in `test_mcd` --- sklearn/covariance/tests/test_robust_covariance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/covariance/tests/test_robust_covariance.py b/sklearn/covariance/tests/test_robust_covariance.py index 4a7590ef2c18c..f1aa5da88655e 100644 --- a/sklearn/covariance/tests/test_robust_covariance.py +++ b/sklearn/covariance/tests/test_robust_covariance.py @@ -19,7 +19,7 @@ def test_mcd(global_random_seed): # Tests the FastMCD algorithm implementation # Small data set # test without outliers (random independent normal data) - launch_mcd_on_dataset(100, 5, 0, 0.02, 0.1, 75, global_random_seed) + launch_mcd_on_dataset(100, 5, 0, 0.02, 0.1, 74, global_random_seed) # test with a contaminated data set (medium contamination) launch_mcd_on_dataset(100, 5, 20, 0.3, 0.3, 65, global_random_seed) # test with a contaminated data set (strong contamination) From c915bbeef157989371cbc25f9d5cd923c0641f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Thu, 27 Nov 2025 14:08:09 +0100 Subject: [PATCH 004/462] CI Run unit-tests with random seed on schedule and open automated issue (#32797) --- .github/workflows/unit-tests.yml | 18 ++++++++++++++++++ maint_tools/update_tracking_issue.py | 1 + 2 files changed, 19 insertions(+) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 2a2ce57eaefb7..01801e1d4df6b 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -5,6 +5,11 @@ permissions: on: push: pull_request: + schedule: + # Nightly build at 02:30 UTC + - cron: "30 2 * * *" + # Manual run + workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -152,6 +157,10 @@ jobs: - name: Build scikit-learn run: bash -l build_tools/azure/install.sh + - name: Set random seed for nightly/manual runs + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + run: echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 100))" >> $GITHUB_ENV + - name: Run tests env: COMMIT_MESSAGE: ${{ needs.retrieve-commit-message.outputs.message }} @@ -178,3 +187,12 @@ jobs: files: ./coverage.xml token: ${{ secrets.CODECOV_TOKEN }} disable_search: true + + update-tracker: + uses: ./.github/workflows/update_tracking_issue.yml + if: ${{ always() }} + needs: [unit-tests] + with: + job_status: ${{ needs.unit-tests.result }} + secrets: + BOT_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} diff --git a/maint_tools/update_tracking_issue.py b/maint_tools/update_tracking_issue.py index b40e8222fefae..6a02c48d24bf6 100644 --- a/maint_tools/update_tracking_issue.py +++ b/maint_tools/update_tracking_issue.py @@ -67,6 +67,7 @@ def get_issue(): login = gh.get_user().login issues = gh.search_issues( f"repo:{args.issue_repo} {title_query} in:title state:open author:{login}" + " is:issue" ) first_page = issues.get_page(0) # Return issue if it exist From 88ae38004c68b5b61ad92356640710056a46bdf3 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Fri, 28 Nov 2025 00:16:59 +1100 Subject: [PATCH 005/462] DOC Shorten PR template and improve PR attention FAQ (#32734) --- .github/PULL_REQUEST_TEMPLATE.md | 11 +++------ doc/faq.rst | 42 ++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index dda65568b4a29..df26bf21907c3 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -29,13 +29,10 @@ is merged. See https://github.com/blog/1506-closing-issues-via-pull-requests +I used AI assistance for: +- [ ] Code generation (e.g., when writing an implementation or fixing a bug) +- [ ] Test/benchmark generation +- [ ] Documentation (including examples) +- [ ] Research and understanding + + #### Any other comments? @@ -37,18 +50,3 @@ https://scikit-learn.org/dev/faq.html#why-is-my-pull-request-not-getting-any-att Thanks for contributing! --> - - diff --git a/doc/developers/contributing.rst b/doc/developers/contributing.rst index 1d582255f6c11..f722b035618d8 100644 --- a/doc/developers/contributing.rst +++ b/doc/developers/contributing.rst @@ -152,22 +152,26 @@ look. Automated Contributions Policy ============================== +Contributing to scikit-learn requires human judgment, contextual understanding, and +familiarity with scikit-learn's structure and goals. It is not suitable for +automatic processing by AI tools. + Please refrain from submitting issues or pull requests generated by fully-automated tools. Maintainers reserve the right, at their sole discretion, to close such submissions and to block any account responsible for them. -Ideally, contributions should follow from a human-to-human discussion in the -form of an issue. In particular, please do not paste AI generated text in the -description of issues, PRs or in comments as it makes it significantly harder for -reviewers to assess the relevance of your contribution and the potential value it -brings to future end-users of the library. Note that it's fine to use AI tools -to proofread or improve your draft text if you are not a native English speaker, -but reviewers are not interested in unknowingly interacting back and forth with -automated chatbots that fundamentally do not care about the value of our open -source project. - -Please self review all code or documentation changes made by AI tools before -submitting them under your name. +Review all code or documentation changes made by AI tools and +make sure you understand all changes and can explain them on request, before +submitting them under your name. Do not submit any AI-generated code that you haven't +personally reviewed, understood and tested, as this wastes maintainers' time. + +Please do not paste AI generated text in the description of issues, PRs or in comments +as this makes it harder for reviewers to assess your contribution. We are happy for it +to be used to improve grammar or if you are not a native English speaker. + +If you used AI tools, please state so in your PR description. + +PRs that appear to violate this policy will be closed without review. Submitting a bug report or a feature request ============================================ From 7d82819d30888f098f7c446388cf13b0e2908e99 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 1 Dec 2025 10:08:02 +0100 Subject: [PATCH 018/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#32823) Co-authored-by: Lock file bot --- ...a_forge_cuda_array-api_linux-64_conda.lock | 118 +++++++++--------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index d3a632653ce31..392461bfb0ceb 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -15,15 +15,14 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#9430 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda#3036ca5b895b7f5146c5a25486234a68 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.6-h4922eb0_0.conda#7a0b9ce502e0ed62195e02891dfcd704 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_8.conda#1bad93f0aa428d618875ef3a588a889e -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-6_kmp_llvm.conda#197811678264cb9da0d2ea0726a70661 +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda#c0374badb3a5d4b1372db28d19462c53 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.0-hb9d3cd8_0.conda#f65c946f28f0518f41ced702f44c52b7 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc @@ -33,15 +32,15 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb03c661_4 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda#280ea6eee9e2ddefde25ff799c4f0363 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda#f116940d825ffc9104400f0d7f1a4551 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda#5b767048b1b3ee9a954b06f4084f93dc +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.10.0-h202a827_0.conda#0f98f3e95272d118f7931b6bef69bfe5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 @@ -68,10 +67,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda#8621a450add4e231f676646880703f49 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda#f627678cf829bd70bccf141a19c3ad3e +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -86,8 +86,8 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.con https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.2.5-hde8ca8f_0.conda#1920c3502e7f6688d650ab81cd3775fd -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.17.0-h3dad3f2_6.conda#3a127d28266cdc0da93384d1f59fe8df https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb03c661_4.conda#ca4ed8015764937c81b830f7f5b68543 https://conda.anaconda.org/conda-forge/linux-64/cudatoolkit-11.8.0-h4ba93d1_13.conda#eb43f5f1f16e2fad2eba22219c3e499b @@ -95,9 +95,10 @@ https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff86 https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_7.conda#beeb74a6fe5ff118451cf0581bfe2642 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.28.3-h6128344_1.conda#d8703f1ffe5a06356f06467f1d0b9464 @@ -115,7 +116,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.4-h04a3f9 https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.9.4-hb9b18c6_4.conda#773c99d0dbe2b3704af165f97ff399e5 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb03c661_4.conda#eaf3fbd2aa97c212336de38a51fe404e https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda#679616eb5ad4e521c83da4650860aba7 +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.1.4-h7d33bf5_0.conda#93fe78190bc6fe40d5e7a737c8065286 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e @@ -123,11 +124,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda#729a572a3ebb8c43933b30edcc628ceb https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.9-h04c0eec_0.conda#35eeb0a2add53b1e50218ed230fa6a02 https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.1.1-h2271f48_0.conda#67075ef2cb33079efee3abfe58127a3b +https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda#4780fe896e961722d0623fa91d0d3378 https://conda.anaconda.org/conda-forge/linux-64/re2-2024.07.02-h9925aae_2.conda#e84ddf12bde691e8ec894b00ea829ddf https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 @@ -138,7 +139,17 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.8.6-hd08a7f5_4.cond https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.12.2-h108da3e_2.conda#90e07c8bac8da6378ee1882ef0a9374a https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.14.0-h5cfcd09_0.conda#0a8838771cc2e985cd295e01ae83baf1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a +https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda#367133808e89325690562099851529c8 +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py313hc80a56d_0.conda#a14fa0e1f58e2fce8d6fddf8f54ed500 +https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 +https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda#9bcbd351966dc56a24fc0c368da5ad99 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda#66b8b26023b8efdf8fcb23bac4b6325d https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda#d18004c37182f83b9818b714825a7627 +https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 https://conda.anaconda.org/conda-forge/linux-64/libcudnn-dev-9.10.1.4-h0fdc2d1_0.conda#a0c0b44d26a4710e6ea577fcddbe09d1 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.67.1-h25350d4_2.conda#bfcedaf5f9b003029cc6abe9431f66bf @@ -146,10 +157,29 @@ https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h3d81e11 https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.conda#9ad637a7ac380c442be142dfb0b1b955 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda#74e91c36d0eef3557915c68b6c2bef96 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h7a3aeb2_0.conda#31059dc620fa57d787e3899ed0421e6d +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf +https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b +https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6-pyhcf101f3_0.conda#6725bfdf8ea7a8bf6415f096f3f1ffa5 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 +https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h80991f8_2.conda#37ca27d2f726f29a068230d8f6917ce4 +https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda#4780fe896e961722d0623fa91d0d3378 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 +https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 +https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f +https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py313h07c4f96_2.conda#7824f18e343d1f846dcde7b23c9bf31a +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b @@ -160,81 +190,51 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.7.13-h822ba82_2.conda#9cf2c3c13468f2209ee814be2c88655f https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.10.0-h113e628_0.conda#73f73f60854f325a55f1d31459f2ab73 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.8.0-h736e048_1.conda#13de36be8de3ae3f05ba127631599213 -https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda#367133808e89325690562099851529c8 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.12.0-py313h3dea7bd_0.conda#8ef99d298907bfd688a95cc714662ae7 https://conda.anaconda.org/conda-forge/linux-64/cudnn-9.10.1.4-haad7af6_0.conda#8382d957333e0d3280dcbf5691516dc1 -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.1-py313hc80a56d_0.conda#1617960e1d8164f837ed5d0996603b88 -https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda#9bcbd351966dc56a24fc0c368da5ad99 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda#66b8b26023b8efdf8fcb23bac4b6325d +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee -https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda#d18004c37182f83b9818b714825a7627 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py313h3dea7bd_0.conda#92f09729a821c52943d4b0b3749a2380 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 -https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.0-default_h99862b1_1.conda#d599b346638b9216c1e8f9146713df05 https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.0-default_h746c552_1.conda#327c78a8ce710782425a89df851392f7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.36.0-h2b5623c_0.conda#c96ca58ad3352a964bfcb85de6cd1496 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.18.0-hfcad708_1.conda#1f5a5d66e77a39dc5bd639ec953705cf https://conda.anaconda.org/conda-forge/linux-64/libpq-17.7-h5c52fec_1.conda#a4769024afeab4b32ac8167c2f92c7ac -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 -https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b -https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda#16bff3d37a4f99e3aa089c36c2b8d650 -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h50355cd_0.conda#8a96eab78687362de3e102a15c4747a8 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 -https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e -https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.9-h4df99d1_101.conda#f41e3c1125e292e6bfcea8392a3de3d8 https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-h8d10470_4.conda#e6d46d70c68d0eb69b9a040ebe3acddf -https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_2.conda#00d80af3a7bf27729484e786a68aafff -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py313h07c4f96_2.conda#7824f18e343d1f846dcde7b23c9bf31a -https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f +https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.31.0-h55f77e1_4.conda#0627af705ed70681f5bede31e72348e5 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.13.0-h3cf044e_1.conda#7eb66060455c7a47d9dcdbfa9f46579b https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.12.0-py313h3dea7bd_0.conda#8ef99d298907bfd688a95cc714662ae7 -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.60.1-py313h3dea7bd_0.conda#904860fc0d57532d28e9c6c4501f19a9 -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.36.0-h0121fbd_0.conda#fc5efe1833a4d709953964037985bb72 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha770c72_17.conda#e4ab075598123e783b788b995afbdad0 -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 -https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.9-h4df99d1_101.conda#f41e3c1125e292e6bfcea8392a3de3d8 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.510-h37a5c72_3.conda#beb8577571033140c6897d257acc7724 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.12.0-ha633028_1.conda#7c1980f89dd41b097549782121a73490 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-37_h5875eb1_mkl.conda#888c2ae634bce09709dffd739ba9f1bc -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2024.2.2-ha770c72_17.conda#e67269e07e58be5672f06441316f05f2 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-19.0.1-hc7b3859_3_cpu.conda#9ed3ded6da29dec8417f2e1db68798f2 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-37_hfef963f_mkl.conda#f66eb9a9396715013772b8a3ef7396be -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-37_h5e43f62_mkl.conda#0c4af651539e79160cd3f0783391e918 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.35.2-py310hffdcd12_0.conda#2b90c3aaf73a5b6028b068cf3c76e0b7 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-19.0.1-hc7b3859_3_cpu.conda#9ed3ded6da29dec8417f2e1db68798f2 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-37_hfef963f_mkl.conda#f66eb9a9396715013772b8a3ef7396be +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-37_h5e43f62_mkl.conda#0c4af651539e79160cd3f0783391e918 +https://conda.anaconda.org/conda-forge/noarch/polars-1.35.2-pyh6a1acc5_0.conda#24e8f78d79881b3c035f89f4b83c565c https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.2-h5bd77bc_1.conda#f7bfe5b8e7641ce7d11ea10cfd9f33cc https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-19.0.1-hcb10f89_3_cpu.conda#8f8dc214d89e06933f1bc1dcd2310b9c https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-37_hdba1596_mkl.conda#4e76080972d13c913f178c90726b21ce https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-h45b15fe_0.conda#703a1ab01e36111d8bb40bc7517e900b https://conda.anaconda.org/conda-forge/linux-64/libparquet-19.0.1-h081d1f1_3_cpu.conda#1d04307cdb1d8aeb5f55b047d5d403ea https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py313hf6604e3_0.conda#15f43bcd12c90186e78801fafc53d89b -https://conda.anaconda.org/conda-forge/noarch/polars-1.35.2-pyh6a1acc5_0.conda#24e8f78d79881b3c035f89f4b83c565c https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-19.0.1-py313he5f92c8_0_cpu.conda#7d8649531c807b24295c8f9a0a396a78 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.2-py313ha3f37dd_1.conda#e2ec46ec4c607b97623e7b691ad31c54 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 From f6d75eae22b37a8b4c189f0146cbebbd17d43856 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 1 Dec 2025 10:08:38 +0100 Subject: [PATCH 019/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#32822) Co-authored-by: Lock file bot --- ...pylatest_pip_scipy_dev_linux-64_conda.lock | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 521720e99c03a..e5db81f2c3b5e 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -6,40 +6,39 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda#3036ca5b895b7f5146c5a25486234a68 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda#f7b4d76975aac7e5d9e6ad13845f92fe +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda#c0374badb3a5d4b1372db28d19462c53 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda#280ea6eee9e2ddefde25ff799c4f0363 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda#f116940d825ffc9104400f0d7f1a4551 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda#5b767048b1b3ee9a954b06f4084f93dc +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda#8621a450add4e231f676646880703f49 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda#f627678cf829bd70bccf141a19c3ad3e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 -https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_7.conda#beeb74a6fe5ff118451cf0581bfe2642 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda#729a572a3ebb8c43933b30edcc628ceb -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/linux-64/python-3.14.0-h32b2ec7_102_cp314.conda#0a19d2cc6eb15881889b0c6fa7d6a78d +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 # pip certifi @ https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl#sha256=97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b # pip charset-normalizer @ https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 # pip coverage @ https://files.pythonhosted.org/packages/d9/1d/9529d9bd44049b6b05bb319c03a3a7e4b0a8a802d28fa348ad407e10706d/coverage-7.12.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=fdba9f15849534594f60b47c9a30bc70409b54947319a7c4fd0e8e3d8d2f355d -# pip docutils @ https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl#sha256=dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 +# pip docutils @ https://files.pythonhosted.org/packages/11/a8/c6a4b901d17399c77cd81fb001ce8961e9f5e04d3daf27e8925cb012e163/docutils-0.22.3-py3-none-any.whl#sha256=bd772e4aca73aff037958d44f2be5229ded4c09927fcf8690c577b66234d6ceb # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea # pip imagesize @ https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl#sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b @@ -51,7 +50,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip platformdirs @ https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl#sha256=e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b -# pip roman-numerals-py @ https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl#sha256=9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c +# pip roman-numerals @ https://files.pythonhosted.org/packages/82/1d/7356f115a0e5faf8dc59894a3e9fc8b1821ab949163458b0072db0a12a68/roman_numerals-3.1.0-py3-none-any.whl#sha256=842ae5fd12912d62720c9aad8cab706e8c692556d01a38443e051ee6cc158d90 # pip six @ https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl#sha256=4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 # pip snowballstemmer @ https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl#sha256=6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 # pip sphinxcontrib-applehelp @ https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl#sha256=4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 @@ -72,5 +71,5 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip pooch @ https://files.pythonhosted.org/packages/a8/87/77cc11c7a9ea9fd05503def69e3d18605852cd0d4b0d3b8f15bbeb3ef1d1/pooch-1.8.2-py3-none-any.whl#sha256=3529a57096f7198778a5ceefd5ac3ef0e4d06a6ddaf9fc2d609b806f25302c47 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 -# pip sphinx @ https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl#sha256=4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3 +# pip sphinx @ https://files.pythonhosted.org/packages/fe/8b/76e2a1ce12b915399365873eef2b1197da9d032c99e661a71fd7e1490333/sphinx-9.0.0-py3-none-any.whl#sha256=3442bf635d378da2ba4e88aa8496f3a61b2d59ef145aeaf34353ab93fd79f1bf # pip numpydoc @ https://files.pythonhosted.org/packages/6c/45/56d99ba9366476cd8548527667f01869279cedb9e66b28eb4dfb27701679/numpydoc-1.8.0-py3-none-any.whl#sha256=72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541 From 910a59199d0ec23cc7a8fb6851ec87104b41f46b Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 1 Dec 2025 10:09:20 +0100 Subject: [PATCH 020/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#32821) Co-authored-by: Lock file bot --- ...pylatest_free_threaded_linux-64_conda.lock | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index 8628cfb70b54a..95f916d48d876 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -6,44 +6,42 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#3251796e09870c978e0f69fa05e38fb6 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda#3036ca5b895b7f5146c5a25486234a68 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda#f7b4d76975aac7e5d9e6ad13845f92fe +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda#c0374badb3a5d4b1372db28d19462c53 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda#280ea6eee9e2ddefde25ff799c4f0363 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda#f116940d825ffc9104400f0d7f1a4551 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda#5b767048b1b3ee9a954b06f4084f93dc +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda#8621a450add4e231f676646880703f49 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda#f627678cf829bd70bccf141a19c3ad3e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 -https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_7.conda#beeb74a6fe5ff118451cf0581bfe2642 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h4a7cf45_openblas.conda#6146bf1b7f58113d54614c6ec683c14a https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda#729a572a3ebb8c43933b30edcc628ceb -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_h0358290_openblas.conda#a84b2b7ed34206d14739fb8d29cd2799 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h47877c9_openblas.conda#9fb20e74a7436dc94dd39d9a9decddc3 https://conda.anaconda.org/conda-forge/linux-64/python-3.14.0-he1279bd_2_cp314t.conda#f82ece6dbaba8c6bf8ed6122eb273b9d +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.0-py314hd8ed1ab_2.conda#86fdc2e15c6f0efb98804a2c461f30b6 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.1-py314h3f98dc2_0.conda#eebd4c060e488edb97488858f1293190 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py314h3f98dc2_0.conda#af078f15b212d1414633e888166dd2bf https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_h0358290_openblas.conda#a84b2b7ed34206d14739fb8d29cd2799 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h47877c9_openblas.conda#9fb20e74a7436dc94dd39d9a9decddc3 https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py314hd4f4903_0.conda#f9c8cd3ab6c388232550c806379856d5 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 @@ -54,9 +52,10 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d27 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py314hd4f4903_0.conda#f9c8cd3ab6c388232550c806379856d5 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.0-h92d6c8b_2.conda#bbd6d97a4f90042d5ae148217d3110a6 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py314hf5b80f4_1.conda#b010b4d97f99c579c759996db97e53c0 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 -https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.7.1-pyhd8ed1ab_0.conda#1277cda67d2764e7b19d6b0bed02c812 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py314hf5b80f4_1.conda#b010b4d97f99c579c759996db97e53c0 +https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.0-pyhd8ed1ab_0.conda#7d545e76cfc231cf246f99963bcd27b0 From d1661f07ad31b836649044cc6befbc75ef8c1eb9 Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Mon, 1 Dec 2025 14:43:37 +0100 Subject: [PATCH 021/462] CI Move pylatest_pip_openblas_pandas to Github Actions (#32810) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- .github/workflows/unit-tests.yml | 19 ++++++++++++++++++- azure-pipelines.yml | 14 -------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 01801e1d4df6b..008e32b1acb48 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -125,6 +125,23 @@ jobs: os: ubuntu-24.04-arm DISTRIB: conda LOCK_FILE: build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock + + # Linux environment to test the latest available dependencies. + # It runs tests requiring lightgbm, pandas and PyAMG. + - name: Linux pylatest_pip_openblas_pandas + os: ubuntu-24.04 + DISTRIB: conda + LOCK_FILE: build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock + SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 3 # non-default seed + SCIPY_ARRAY_API: 1 + CHECK_PYTEST_SOFT_DEPENDENCY: true + SKLEARN_WARNINGS_AS_ERRORS: 1 + # disable pytest-xdist to have 1 job where OpenMP and BLAS are not single + # threaded because by default the tests configuration (sklearn/conftest.py) + # makes sure that they are single threaded in each xdist subprocess. + PYTEST_XDIST_VERSION: none + PIP_BUILD_ISOLATION: true + - name: macOS pylatest_conda_forge_arm os: macOS-15 DISTRIB: conda @@ -132,7 +149,7 @@ jobs: SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 5 # non-default seed SCIPY_ARRAY_API: 1 PYTORCH_ENABLE_MPS_FALLBACK: 1 - CHECK_PYTEST_SOFT_DEPENDENCY: 'true' + CHECK_PYTEST_SOFT_DEPENDENCY: true env: ${{ matrix }} diff --git a/azure-pipelines.yml b/azure-pipelines.yml index eca3683253ff7..74f2f7ea5ef82 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -183,20 +183,6 @@ jobs: SKLEARN_ENABLE_DEBUG_CYTHON_DIRECTIVES: '1' SKLEARN_RUN_FLOAT32_TESTS: '1' SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '2' # non-default seed - # Linux environment to test the latest available dependencies. - # It runs tests requiring lightgbm, pandas and PyAMG. - pylatest_pip_openblas_pandas: - DISTRIB: 'conda-pip-latest' - LOCK_FILE: './build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock' - CHECK_PYTEST_SOFT_DEPENDENCY: 'true' - SKLEARN_WARNINGS_AS_ERRORS: '1' - SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '3' # non-default seed - # disable pytest-xdist to have 1 job where OpenMP and BLAS are not single - # threaded because by default the tests configuration (sklearn/conftest.py) - # makes sure that they are single threaded in each xdist subprocess. - PYTEST_XDIST_VERSION: 'none' - PIP_BUILD_ISOLATION: 'true' - SCIPY_ARRAY_API: '1' - template: build_tools/azure/posix-docker.yml parameters: From 045224d75335213d725727e3a94800b34a4822dd Mon Sep 17 00:00:00 2001 From: "Christine P. Chai" Date: Tue, 2 Dec 2025 00:25:24 -0800 Subject: [PATCH 022/462] DOC: Correct many grammatical issues (#32820) --- doc/computing/computational_performance.rst | 2 +- doc/developers/tips.rst | 6 +++--- doc/modules/array_api.rst | 2 +- doc/modules/model_evaluation.rst | 4 ++-- examples/applications/plot_face_recognition.py | 2 +- examples/compose/plot_column_transformer.py | 2 +- examples/miscellaneous/plot_roc_curve_visualization_api.py | 4 ++-- examples/model_selection/plot_learning_curve.py | 4 ++-- examples/svm/plot_separating_hyperplane_unbalanced.py | 2 +- sklearn/cluster/_hierarchical_fast.pyx | 4 ++-- sklearn/cluster/tests/test_spectral.py | 2 +- sklearn/cross_decomposition/_pls.py | 2 +- sklearn/ensemble/_forest.py | 2 +- sklearn/ensemble/_gb.py | 2 +- .../_hist_gradient_boosting/tests/test_compare_lightgbm.py | 6 +++--- sklearn/ensemble/_iforest.py | 6 +++--- sklearn/ensemble/tests/test_gradient_boosting.py | 2 +- sklearn/linear_model/tests/test_sgd.py | 2 +- .../_pairwise_distances_reduction/_datasets_pair.pyx.tp | 4 ++-- .../_middle_term_computer.pyx.tp | 6 +++--- .../_pairwise_distances_reduction/_radius_neighbors.pyx.tp | 2 +- sklearn/metrics/pairwise.py | 2 +- sklearn/metrics/tests/test_classification.py | 2 +- sklearn/metrics/tests/test_ranking.py | 2 +- sklearn/metrics/tests/test_score_objects.py | 2 +- sklearn/model_selection/tests/test_split.py | 2 +- sklearn/preprocessing/tests/test_encoders.py | 2 +- sklearn/preprocessing/tests/test_function_transformer.py | 2 +- sklearn/tests/test_base.py | 4 ++-- sklearn/tree/tests/test_tree.py | 2 +- sklearn/utils/_arpack.py | 2 +- sklearn/utils/_random.pxd | 2 +- sklearn/utils/sparsefuncs_fast.pyx | 4 ++-- sklearn/utils/validation.py | 2 +- 34 files changed, 49 insertions(+), 49 deletions(-) diff --git a/doc/computing/computational_performance.rst b/doc/computing/computational_performance.rst index 6aa0865b54c35..d1df34551e157 100644 --- a/doc/computing/computational_performance.rst +++ b/doc/computing/computational_performance.rst @@ -178,7 +178,7 @@ non-zero coefficients. For the :mod:`sklearn.svm` family of algorithms with a non-linear kernel, the latency is tied to the number of support vectors (the fewer the faster). Latency and throughput should (asymptotically) grow linearly with the number -of support vectors in a SVC or SVR model. The kernel will also influence the +of support vectors in an SVC or SVR model. The kernel will also influence the latency as it is used to compute the projection of the input vector once per support vector. In the following graph the ``nu`` parameter of :class:`~svm.NuSVR` was used to influence the number of diff --git a/doc/developers/tips.rst b/doc/developers/tips.rst index e4f67a08a08c8..52c8ad682572b 100644 --- a/doc/developers/tips.rst +++ b/doc/developers/tips.rst @@ -339,14 +339,14 @@ tutorials and documentation on the `valgrind web site `_. .. _arm64_dev_env: -Building and testing for the ARM64 platform on a x86_64 machine -=============================================================== +Building and testing for the ARM64 platform on an x86_64 machine +================================================================ ARM-based machines are a popular target for mobile, edge or other low-energy deployments (including in the cloud, for instance on Scaleway or AWS Graviton). Here are instructions to setup a local dev environment to reproduce -ARM-specific bugs or test failures on a x86_64 host laptop or workstation. This +ARM-specific bugs or test failures on an x86_64 host laptop or workstation. This is based on QEMU user mode emulation using docker for convenience (see https://github.com/multiarch/qemu-user-static). diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index c820621d5b313..7771cc92f338c 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -87,7 +87,7 @@ After the model is trained, fitted attributes that are arrays will also be from the same Array API namespace as the training data. For example, if CuPy's Array API namespace was used for training, then fitted attributes will be on the GPU. We provide an experimental `_estimator_with_converted_arrays` utility that -transfers an estimator attributes from Array API to a ndarray:: +transfers an estimator attributes from Array API to an ndarray:: >>> from sklearn.utils._array_api import _estimator_with_converted_arrays >>> cupy_to_ndarray = lambda array : array.get() diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index c86fae1b6688b..a5e32336da38c 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -1302,7 +1302,7 @@ is defined by: - w_{i, y_i}, 0\right\} Here is a small example demonstrating the use of the :func:`hinge_loss` function -with a svm classifier in a binary class problem:: +with an svm classifier in a binary class problem:: >>> from sklearn import svm >>> from sklearn.metrics import hinge_loss @@ -1318,7 +1318,7 @@ with a svm classifier in a binary class problem:: 0.3 Here is an example demonstrating the use of the :func:`hinge_loss` function -with a svm classifier in a multiclass problem:: +with an svm classifier in a multiclass problem:: >>> X = np.array([[0], [1], [2], [3]]) >>> Y = np.array([0, 1, 2, 3]) diff --git a/examples/applications/plot_face_recognition.py b/examples/applications/plot_face_recognition.py index add219aed1610..e14c2686514ef 100644 --- a/examples/applications/plot_face_recognition.py +++ b/examples/applications/plot_face_recognition.py @@ -83,7 +83,7 @@ # %% -# Train a SVM classification model +# Train an SVM classification model print("Fitting the classifier to the training set") t0 = time() diff --git a/examples/compose/plot_column_transformer.py b/examples/compose/plot_column_transformer.py index 8f779d085614a..f61b3b04b0195 100644 --- a/examples/compose/plot_column_transformer.py +++ b/examples/compose/plot_column_transformer.py @@ -171,7 +171,7 @@ def text_stats(posts): }, ), ), - # Use a SVC classifier on the combined features + # Use an SVC classifier on the combined features ("svc", LinearSVC(dual=False)), ], verbose=True, diff --git a/examples/miscellaneous/plot_roc_curve_visualization_api.py b/examples/miscellaneous/plot_roc_curve_visualization_api.py index 1aacbd9de3631..2a9b14fdeabcf 100644 --- a/examples/miscellaneous/plot_roc_curve_visualization_api.py +++ b/examples/miscellaneous/plot_roc_curve_visualization_api.py @@ -13,8 +13,8 @@ # SPDX-License-Identifier: BSD-3-Clause # %% -# Load Data and Train a SVC -# ------------------------- +# Load Data and Train an SVC +# -------------------------- # First, we load the wine dataset and convert it to a binary classification # problem. Then, we train a support vector classifier on a training dataset. import matplotlib.pyplot as plt diff --git a/examples/model_selection/plot_learning_curve.py b/examples/model_selection/plot_learning_curve.py index d8060c67cbe15..876c70c0d901e 100644 --- a/examples/model_selection/plot_learning_curve.py +++ b/examples/model_selection/plot_learning_curve.py @@ -24,8 +24,8 @@ # process. The effect is depicted by checking the statistical performance of # the model in terms of training score and testing score. # -# Here, we compute the learning curve of a naive Bayes classifier and a SVM -# classifier with a RBF kernel using the digits dataset. +# Here, we compute the learning curve of a naive Bayes classifier and an SVM +# classifier with an RBF kernel using the digits dataset. from sklearn.datasets import load_digits from sklearn.naive_bayes import GaussianNB from sklearn.svm import SVC diff --git a/examples/svm/plot_separating_hyperplane_unbalanced.py b/examples/svm/plot_separating_hyperplane_unbalanced.py index d0814e1af065f..d92735fc91a82 100644 --- a/examples/svm/plot_separating_hyperplane_unbalanced.py +++ b/examples/svm/plot_separating_hyperplane_unbalanced.py @@ -17,7 +17,7 @@ This example will also work by replacing ``SVC(kernel="linear")`` with ``SGDClassifier(loss="hinge")``. Setting the ``loss`` parameter of the :class:`SGDClassifier` equal to ``hinge`` will yield behaviour - such as that of a SVC with a linear kernel. + such as that of an SVC with a linear kernel. For example try instead of the ``SVC``:: diff --git a/sklearn/cluster/_hierarchical_fast.pyx b/sklearn/cluster/_hierarchical_fast.pyx index f20b1359f46e2..8d7c363daef37 100644 --- a/sklearn/cluster/_hierarchical_fast.pyx +++ b/sklearn/cluster/_hierarchical_fast.pyx @@ -351,7 +351,7 @@ cdef class UnionFind(object): def _single_linkage_label(const float64_t[:, :] L): """ - Convert an linkage array or MST to a tree by labelling clusters at merges. + Convert a linkage array or MST to a tree by labelling clusters at merges. This is done by using a Union find structure to keep track of merges efficiently. This is the private version of the function that assumes that ``L`` has been properly validated. See ``single_linkage_label`` for the @@ -399,7 +399,7 @@ def _single_linkage_label(const float64_t[:, :] L): @cython.wraparound(True) def single_linkage_label(L): """ - Convert an linkage array or MST to a tree by labelling clusters at merges. + Convert a linkage array or MST to a tree by labelling clusters at merges. This is done by using a Union find structure to keep track of merges efficiently. diff --git a/sklearn/cluster/tests/test_spectral.py b/sklearn/cluster/tests/test_spectral.py index 71b11c9fe151c..85c9c1c04d9ab 100644 --- a/sklearn/cluster/tests/test_spectral.py +++ b/sklearn/cluster/tests/test_spectral.py @@ -311,7 +311,7 @@ def test_verbose(assign_labels, capsys): def test_spectral_clustering_np_matrix_raises(): """Check that spectral_clustering raises an informative error when passed - a np.matrix. See #10993""" + an np.matrix. See #10993""" X = np.matrix([[0.0, 2.0], [2.0, 0.0]]) msg = r"np\.matrix is not supported. Please convert to a numpy array" diff --git a/sklearn/cross_decomposition/_pls.py b/sklearn/cross_decomposition/_pls.py index 756af41e97290..bb720c9ab503b 100644 --- a/sklearn/cross_decomposition/_pls.py +++ b/sklearn/cross_decomposition/_pls.py @@ -903,7 +903,7 @@ def __init__( class PLSSVD(ClassNamePrefixFeaturesOutMixin, TransformerMixin, BaseEstimator): """Partial Least Square SVD. - This transformer simply performs a SVD on the cross-covariance matrix + This transformer simply performs an SVD on the cross-covariance matrix `X'y`. It is able to project both the training data `X` and the targets `y`. The training data `X` is projected on the left singular vectors, while the targets are projected on the right singular vectors. diff --git a/sklearn/ensemble/_forest.py b/sklearn/ensemble/_forest.py index 54ecdec5e977e..dd72224107f37 100644 --- a/sklearn/ensemble/_forest.py +++ b/sklearn/ensemble/_forest.py @@ -578,7 +578,7 @@ def _compute_oob_predictions(self, X, y): n_samples = y.shape[0] n_outputs = self.n_outputs_ if is_classifier(self) and hasattr(self, "n_classes_"): - # n_classes_ is a ndarray at this stage + # n_classes_ is an ndarray at this stage # all the supported type of target will have the same number of # classes in all outputs oob_pred_shape = (n_samples, self.n_classes_[0], n_outputs) diff --git a/sklearn/ensemble/_gb.py b/sklearn/ensemble/_gb.py index e64763123f270..ba515b4bbcea9 100644 --- a/sklearn/ensemble/_gb.py +++ b/sklearn/ensemble/_gb.py @@ -274,7 +274,7 @@ def compute_update(y_, indices, neg_gradient, raw_prediction, k): def set_huber_delta(loss, y_true, raw_prediction, sample_weight=None): """Calculate and set self.closs.delta based on self.quantile.""" abserr = np.abs(y_true - raw_prediction.squeeze()) - # sample_weight is always a ndarray, never None. + # sample_weight is always an ndarray, never None. delta = _weighted_percentile(abserr, sample_weight, 100 * loss.quantile) loss.closs.delta = float(delta) diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_compare_lightgbm.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_compare_lightgbm.py index bbdcb38ef013a..0891457a0475d 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_compare_lightgbm.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_compare_lightgbm.py @@ -93,7 +93,7 @@ def test_same_predictions_regression( est_lightgbm.fit(X_train, y_train) est_sklearn.fit(X_train, y_train) - # We need X to be treated an numerical data, not pre-binned data. + # We need X to be treated a numerical data, not pre-binned data. X_train, X_test = X_train.astype(np.float32), X_test.astype(np.float32) pred_lightgbm = est_lightgbm.predict(X_train) @@ -170,7 +170,7 @@ def test_same_predictions_classification( est_lightgbm.fit(X_train, y_train) est_sklearn.fit(X_train, y_train) - # We need X to be treated an numerical data, not pre-binned data. + # We need X to be treated a numerical data, not pre-binned data. X_train, X_test = X_train.astype(np.float32), X_test.astype(np.float32) pred_lightgbm = est_lightgbm.predict(X_train) @@ -245,7 +245,7 @@ def test_same_predictions_multiclass_classification( est_lightgbm.fit(X_train, y_train) est_sklearn.fit(X_train, y_train) - # We need X to be treated an numerical data, not pre-binned data. + # We need X to be treated a numerical data, not pre-binned data. X_train, X_test = X_train.astype(np.float32), X_test.astype(np.float32) pred_lightgbm = est_lightgbm.predict(X_train) diff --git a/sklearn/ensemble/_iforest.py b/sklearn/ensemble/_iforest.py index 9c709927d7bbc..578fbd1fab073 100644 --- a/sklearn/ensemble/_iforest.py +++ b/sklearn/ensemble/_iforest.py @@ -441,7 +441,7 @@ def decision_function(self, X): of the leaf containing this observation, which is equivalent to the number of splittings required to isolate this point. In case of several observations n_left in the leaf, the average path length of - a n_left samples isolation tree is added. + an n_left samples isolation tree is added. Parameters ---------- @@ -492,7 +492,7 @@ def score_samples(self, X): of the leaf containing this observation, which is equivalent to the number of splittings required to isolate this point. In case of several observations n_left in the leaf, the average path length of - a n_left samples isolation tree is added. + an n_left samples isolation tree is added. Parameters ---------- @@ -647,7 +647,7 @@ def __sklearn_tags__(self): def _average_path_length(n_samples_leaf): """ - The average path length in a n_samples iTree, which is equal to + The average path length in an n_samples iTree, which is equal to the average path length of an unsuccessful BST search since the latter has the same structure as an isolation tree. Parameters diff --git a/sklearn/ensemble/tests/test_gradient_boosting.py b/sklearn/ensemble/tests/test_gradient_boosting.py index 20866348697f6..22b455f4adbb5 100644 --- a/sklearn/ensemble/tests/test_gradient_boosting.py +++ b/sklearn/ensemble/tests/test_gradient_boosting.py @@ -963,7 +963,7 @@ def test_warm_start_sparse(Cls, sparse_container): @pytest.mark.parametrize("Cls", GRADIENT_BOOSTING_ESTIMATORS) def test_warm_start_fortran(Cls, global_random_seed): - # Test that feeding a X in Fortran-ordered is giving the same results as + # Test that feeding an X in Fortran-ordered is giving the same results as # in C-ordered X, y = datasets.make_hastie_10_2(n_samples=100, random_state=global_random_seed) est_c = Cls(n_estimators=1, random_state=global_random_seed, warm_start=True) diff --git a/sklearn/linear_model/tests/test_sgd.py b/sklearn/linear_model/tests/test_sgd.py index 87284f117d0e4..ad48cfec3938c 100644 --- a/sklearn/linear_model/tests/test_sgd.py +++ b/sklearn/linear_model/tests/test_sgd.py @@ -1006,7 +1006,7 @@ def test_balanced_weight(klass): # to use "balanced" assert_array_almost_equal(clf.coef_, clf_balanced.coef_, 6) - # build an very very imbalanced dataset out of iris data + # build a very very imbalanced dataset out of iris data X_0 = X[y == 0, :] y_0 = y[y == 0] diff --git a/sklearn/metrics/_pairwise_distances_reduction/_datasets_pair.pyx.tp b/sklearn/metrics/_pairwise_distances_reduction/_datasets_pair.pyx.tp index 67ed362c05884..f5615b49fb01a 100644 --- a/sklearn/metrics/_pairwise_distances_reduction/_datasets_pair.pyx.tp +++ b/sklearn/metrics/_pairwise_distances_reduction/_datasets_pair.pyx.tp @@ -64,12 +64,12 @@ cdef class DatasetsPair{{name_suffix}}: ---------- X : {ndarray, sparse matrix} of shape (n_samples_X, n_features) Input data. - If provided as a ndarray, it must be C-contiguous. + If provided as an ndarray, it must be C-contiguous. If provided as a sparse matrix, it must be in CSR format. Y : {ndarray, sparse matrix} of shape (n_samples_Y, n_features) Input data. - If provided as a ndarray, it must be C-contiguous. + If provided as an ndarray, it must be C-contiguous. If provided as a sparse matrix, it must be in CSR format. metric : str or DistanceMetric object, default='euclidean' diff --git a/sklearn/metrics/_pairwise_distances_reduction/_middle_term_computer.pyx.tp b/sklearn/metrics/_pairwise_distances_reduction/_middle_term_computer.pyx.tp index 04c1b61310bb7..48216f27f4261 100644 --- a/sklearn/metrics/_pairwise_distances_reduction/_middle_term_computer.pyx.tp +++ b/sklearn/metrics/_pairwise_distances_reduction/_middle_term_computer.pyx.tp @@ -129,11 +129,11 @@ cdef class MiddleTermComputer{{name_suffix}}: ---------- X : ndarray or CSR sparse matrix of shape (n_samples_X, n_features) Input data. - If provided as a ndarray, it must be C-contiguous. + If provided as an ndarray, it must be C-contiguous. Y : ndarray or CSR sparse matrix of shape (n_samples_Y, n_features) Input data. - If provided as a ndarray, it must be C-contiguous. + If provided as an ndarray, it must be C-contiguous. Returns ------- @@ -534,7 +534,7 @@ cdef class SparseSparseMiddleTermComputer{{name_suffix}}(MiddleTermComputer{{nam return dist_middle_terms cdef class SparseDenseMiddleTermComputer{{name_suffix}}(MiddleTermComputer{{name_suffix}}): - """Middle term of the Euclidean distance between chunks of a CSR matrix and a np.ndarray. + """Middle term of the Euclidean distance between chunks of a CSR matrix and an np.ndarray. The logic of the computation is wrapped in the routine _middle_term_sparse_dense_{{name_suffix}}. This routine iterates over the data, indices and indptr arrays of the sparse matrices diff --git a/sklearn/metrics/_pairwise_distances_reduction/_radius_neighbors.pyx.tp b/sklearn/metrics/_pairwise_distances_reduction/_radius_neighbors.pyx.tp index 5e56cde30e5cd..6003e570ef003 100644 --- a/sklearn/metrics/_pairwise_distances_reduction/_radius_neighbors.pyx.tp +++ b/sklearn/metrics/_pairwise_distances_reduction/_radius_neighbors.pyx.tp @@ -26,7 +26,7 @@ cnp.import_array() cdef cnp.ndarray[object, ndim=1] coerce_vectors_to_nd_arrays( shared_ptr[vector_vector_double_intp_t] vecs ): - """Coerce a std::vector of std::vector to a ndarray of ndarray.""" + """Coerce a std::vector of std::vector to an ndarray of ndarray.""" cdef: intp_t n = deref(vecs).size() cnp.ndarray[object, ndim=1] nd_arrays_of_nd_arrays = np.empty(n, dtype=np.ndarray) diff --git a/sklearn/metrics/pairwise.py b/sklearn/metrics/pairwise.py index 005a353b8d778..80ce9fd89bfd6 100644 --- a/sklearn/metrics/pairwise.py +++ b/sklearn/metrics/pairwise.py @@ -973,7 +973,7 @@ def pairwise_distances_argmin(X, Y, *, axis=1, metric="euclidean", metric_kwargs with config_context(assume_finite=True): indices = np.concatenate( list( - # This returns a np.ndarray generator whose arrays we need + # This returns an np.ndarray generator whose arrays we need # to flatten into one. pairwise_distances_chunked( X, Y, reduce_func=_argmin_reduce, metric=metric, **metric_kwargs diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index b8dc67b298be7..958dfa5fd86f6 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -69,7 +69,7 @@ def make_prediction(dataset=None, binary=False): - """Make some classification predictions on a toy dataset using a SVC + """Make some classification predictions on a toy dataset using an SVC If binary is True restrict to a binary classification problem instead of a multiclass classification problem diff --git a/sklearn/metrics/tests/test_ranking.py b/sklearn/metrics/tests/test_ranking.py index 81d14b0265276..0a108ecfb1cca 100644 --- a/sklearn/metrics/tests/test_ranking.py +++ b/sklearn/metrics/tests/test_ranking.py @@ -56,7 +56,7 @@ def make_prediction(dataset=None, binary=False): - """Make some classification predictions on a toy dataset using a SVC + """Make some classification predictions on a toy dataset using an SVC If binary is True restrict to a binary classification problem instead of a multiclass classification problem diff --git a/sklearn/metrics/tests/test_score_objects.py b/sklearn/metrics/tests/test_score_objects.py index 17df56846a664..7f1c60c691c43 100644 --- a/sklearn/metrics/tests/test_score_objects.py +++ b/sklearn/metrics/tests/test_score_objects.py @@ -1521,7 +1521,7 @@ def raising_scorer(estimator, X, y): X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0) clf = LogisticRegression().fit(X_train, y_train) - # "raising_scorer" is raising ValueError and should return an string representation + # "raising_scorer" is raising ValueError and should return a string representation # of the error of the last scorer: scoring = { "accuracy": make_scorer(accuracy_score), diff --git a/sklearn/model_selection/tests/test_split.py b/sklearn/model_selection/tests/test_split.py index a4b6b21470061..c4be05b695dd7 100644 --- a/sklearn/model_selection/tests/test_split.py +++ b/sklearn/model_selection/tests/test_split.py @@ -249,7 +249,7 @@ def check_valid_split(train, test, n_samples=None): assert train.intersection(test) == set() if n_samples is not None: - # Check that the union of train an test split cover all the indices + # Check that the union of train and test split cover all the indices assert train.union(test) == set(range(n_samples)) diff --git a/sklearn/preprocessing/tests/test_encoders.py b/sklearn/preprocessing/tests/test_encoders.py index 9dbd9952bc017..d7632ab2f09d1 100644 --- a/sklearn/preprocessing/tests/test_encoders.py +++ b/sklearn/preprocessing/tests/test_encoders.py @@ -1942,7 +1942,7 @@ def test_ordinal_encoder_unknown_missing_interaction(): @pytest.mark.parametrize("with_pandas", [True, False]) def test_ordinal_encoder_encoded_missing_value_error(with_pandas): """Check OrdinalEncoder errors when encoded_missing_value is used by - an known category.""" + a known category.""" X = np.array([["a", "dog"], ["b", "cat"], ["c", np.nan]], dtype=object) # The 0-th feature has no missing values so it is not included in the list of diff --git a/sklearn/preprocessing/tests/test_function_transformer.py b/sklearn/preprocessing/tests/test_function_transformer.py index 6bfb5d1367c8d..c4d6867fc66ab 100644 --- a/sklearn/preprocessing/tests/test_function_transformer.py +++ b/sklearn/preprocessing/tests/test_function_transformer.py @@ -468,7 +468,7 @@ def test_set_output_func(): assert isinstance(X_trans, pd.DataFrame) assert_array_equal(X_trans.columns, ["a", "b"]) - # Warning is raised when func returns a ndarray + # Warning is raised when func returns an ndarray ft_np = FunctionTransformer(lambda x: np.asarray(x)) for transform in ("pandas", "polars"): diff --git a/sklearn/tests/test_base.py b/sklearn/tests/test_base.py index cf55bb71c6987..66830a3d57b21 100644 --- a/sklearn/tests/test_base.py +++ b/sklearn/tests/test_base.py @@ -760,7 +760,7 @@ def transform(self, X): with pytest.raises(ValueError, match=msg): trans.transform(df_bad) - # warns when fitted on dataframe and transforming a ndarray + # warns when fitted on dataframe and transforming an ndarray msg = ( "X does not have valid feature names, but NoOpTransformer was " "fitted with feature names" @@ -768,7 +768,7 @@ def transform(self, X): with pytest.warns(UserWarning, match=msg): trans.transform(X_np) - # warns when fitted on a ndarray and transforming dataframe + # warns when fitted on an ndarray and transforming dataframe msg = "X has feature names, but NoOpTransformer was fitted without feature names" trans = NoOpTransformer().fit(X_np) with pytest.warns(UserWarning, match=msg): diff --git a/sklearn/tree/tests/test_tree.py b/sklearn/tree/tests/test_tree.py index bb5dcde356d32..fc1094d2555b9 100644 --- a/sklearn/tree/tests/test_tree.py +++ b/sklearn/tree/tests/test_tree.py @@ -291,7 +291,7 @@ def test_regression_toy(Tree, criterion): def test_xor(): - # Check on a XOR problem + # Check on an XOR problem y = np.zeros((10, 10)) y[:5, :5] = 1 y[5:, 5:] = 1 diff --git a/sklearn/utils/_arpack.py b/sklearn/utils/_arpack.py index 04457b71db10a..227de76c006c0 100644 --- a/sklearn/utils/_arpack.py +++ b/sklearn/utils/_arpack.py @@ -7,7 +7,7 @@ def _init_arpack_v0(size, random_state): """Initialize the starting vector for iteration in ARPACK functions. - Initialize a ndarray with values sampled from the uniform distribution on + Initialize an ndarray with values sampled from the uniform distribution on [-1, 1]. This initialization model has been chosen to be consistent with the ARPACK one as another initialization can lead to convergence issues. diff --git a/sklearn/utils/_random.pxd b/sklearn/utils/_random.pxd index ecb9f80361409..376446b066ad1 100644 --- a/sklearn/utils/_random.pxd +++ b/sklearn/utils/_random.pxd @@ -18,7 +18,7 @@ cdef enum: # rand_r replacement using a 32bit XorShift generator # See http://www.jstatsoft.org/v08/i14/paper for details cdef inline uint32_t our_rand_r(uint32_t* seed) nogil: - """Generate a pseudo-random np.uint32 from a np.uint32 seed""" + """Generate a pseudo-random np.uint32 from an np.uint32 seed""" # seed shouldn't ever be 0. if (seed[0] == 0): seed[0] = DEFAULT_SEED diff --git a/sklearn/utils/sparsefuncs_fast.pyx b/sklearn/utils/sparsefuncs_fast.pyx index 0e9f75a18a542..2859b4d127f11 100644 --- a/sklearn/utils/sparsefuncs_fast.pyx +++ b/sklearn/utils/sparsefuncs_fast.pyx @@ -50,7 +50,7 @@ def _sqeuclidean_row_norms_sparse( def csr_mean_variance_axis0(X, weights=None, return_sum_weights=False): """Compute mean and variance along axis 0 on a CSR matrix - Uses a np.float64 accumulator. + Uses an np.float64 accumulator. Parameters ---------- @@ -184,7 +184,7 @@ def _csr_mean_variance_axis0( def csc_mean_variance_axis0(X, weights=None, return_sum_weights=False): """Compute mean and variance along axis 0 on a CSC matrix - Uses a np.float64 accumulator. + Uses an np.float64 accumulator. Parameters ---------- diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index ed9b5e20e40bb..a112ec4adba61 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -1437,7 +1437,7 @@ def column_or_1d(y, *, dtype=None, input_name="y", warn=False, device=None): def check_random_state(seed): - """Turn seed into a np.random.RandomState instance. + """Turn seed into an np.random.RandomState instance. Parameters ---------- From 6d602baf5553b659d3b4545d3c528889d5b4bf1f Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Tue, 2 Dec 2025 11:03:18 +0100 Subject: [PATCH 023/462] FIX: move_to should handle BufferError and ValueError to support PyTorch 2.9 with array API enabled (#32827) --- sklearn/utils/_array_api.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 46f4bb576fa44..e3ba6b58149c5 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -527,7 +527,15 @@ def move_to(*arrays, xp, device): # kwargs in the from_dlpack method and their expected # meaning by namespaces implementing the array API spec. # TODO: try removing this once DLPack v1 more widely supported - except (AttributeError, TypeError, NotImplementedError): + # TODO: ValueError should not be needed but is in practice: + # https://github.com/numpy/numpy/issues/30341 + except ( + AttributeError, + TypeError, + NotImplementedError, + BufferError, + ValueError, + ): # Converting to numpy is tricky, handle this via dedicated function if _is_numpy_namespace(xp): array_converted = _convert_to_numpy(array, xp_array) From 19dbd540cd61b215ee8b29c2d5181f8b6412c23b Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Tue, 2 Dec 2025 12:38:14 +0100 Subject: [PATCH 024/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#32824) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lock file bot Co-authored-by: Loïc Estève --- build_tools/azure/debian_32bit_lock.txt | 2 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 167 ++++++++-------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 42 ++-- .../pylatest_conda_forge_osx-arm64_conda.lock | 102 +++++----- ...st_pip_openblas_pandas_linux-64_conda.lock | 35 ++-- ...nblas_min_dependencies_linux-64_conda.lock | 114 +++++------ ...e_openblas_ubuntu_2204_linux-64_conda.lock | 51 +++-- ...min_conda_forge_openblas_win-64_conda.lock | 30 +-- build_tools/circle/doc_linux-64_conda.lock | 184 +++++++++--------- .../doc_min_dependencies_linux-64_conda.lock | 157 ++++++++------- ...n_conda_forge_arm_linux-aarch64_conda.lock | 48 ++--- 11 files changed, 467 insertions(+), 465 deletions(-) diff --git a/build_tools/azure/debian_32bit_lock.txt b/build_tools/azure/debian_32bit_lock.txt index d78b1d3cde84f..545879de75099 100644 --- a/build_tools/azure/debian_32bit_lock.txt +++ b/build_tools/azure/debian_32bit_lock.txt @@ -6,7 +6,7 @@ # coverage[toml]==7.12.0 # via pytest-cov -cython==3.2.1 +cython==3.2.2 # via -r build_tools/azure/debian_32bit_requirements.txt execnet==2.1.2 # via pytest-xdist diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index 9f3b309640118..b39c5c199a0a6 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -9,38 +9,37 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.co https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_1.conda#9e298d76f543deb06eb0f3413675e13a https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_462.conda#0ec3505e9b16acc124d1ec6e5ae8207c https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 -https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-4-hd8ed1ab_3.tar.bz2#878f923dd6acc8aeb47a75da6c4098be +https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda#3036ca5b895b7f5146c5a25486234a68 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.6-h4922eb0_0.conda#7a0b9ce502e0ed62195e02891dfcd704 -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-6_kmp_llvm.conda#197811678264cb9da0d2ea0726a70661 +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda#c0374badb3a5d4b1372db28d19462c53 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.5-hb03c661_1.conda#f1d45413e1c41a7eff162bf702c02cea https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda#f7f0d6cc2dc986d42ac2689ec88192be https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 -https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-h09219d5_0.conda#9b3117ec960b823815b02190b41c0484 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda#280ea6eee9e2ddefde25ff799c4f0363 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda#f116940d825ffc9104400f0d7f1a4551 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda#5b767048b1b3ee9a954b06f4084f93dc -https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.1-hfe17d71_0.conda#765c7e0005659d5154cdd33dc529e0a5 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 +https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.2-hfe17d71_0.conda#5641725dfad698909ec71dac80d16736 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -56,20 +55,22 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h7e655bb https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h7e655bb_3.conda#70e83d2429b7edb595355316927dfbea https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h7e655bb_4.conda#83a6e0fc73a7f18a8024fc89455da81c https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda#bfd56492d8346d669010eccafe0ba058 +https://conda.anaconda.org/conda-forge/linux-64/fmt-12.0.0-h2b0788b_0.conda#d90bf58b03d9a958cb4f9d3de539af17 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20250512.1-cxx17_hba17884_0.conda#83b160d4da3e1e847bf044997621ed63 -https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hd53d788_0.conda#c183787d2b228775dece45842abbbe53 -https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-h02bd7ab_0.conda#b7a924e3e9ebc7938ffc7d94fe603ed3 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda#8621a450add4e231f676646880703f49 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda#f627678cf829bd70bccf141a19c3ad3e +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -84,17 +85,18 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.con https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.2.5-hde8ca8f_0.conda#1920c3502e7f6688d650ab81cd3775fd -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-ha76f1cc_3.conda#14d9fc6b1c7a823fca6cf65f595ff70d -https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hf2c8021_0.conda#5304333319a6124a2737d9f128cbc4ed +https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_7.conda#beeb74a6fe5ff118451cf0581bfe2642 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_2.conda#94cb88daa0892171457d9fdc69f43eca @@ -109,21 +111,21 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.6-h3cb25bf_6.conda#874d910adf3debe908b1e8e5847e0014 https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-hc5c8343_4.conda#b6fdadda34f2a60870980607ef469e39 -https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-h41a2e66_0.conda#4ddfd44e473c676cb8e80548ba4aa704 +https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda#679616eb5ad4e521c83da4650860aba7 +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_0.conda#01e149d4a53185622dc2e788281961f2 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda#729a572a3ebb8c43933b30edcc628ceb https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.9.0-heeeca48_0.conda#8a2a73951c1ea275e76fb1b92d97ff3e https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.1-hd747db4_0.conda#ddab8b2af55b88d63469c040377bd37e +https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda#4780fe896e961722d0623fa91d0d3378 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_0.conda#0227d04521bc3d28c7995c7e1f99a721 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 @@ -133,62 +135,41 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_ https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.1-h7ca4310_7.conda#6e91a9182506f6715c25c3ab80990653 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-h3a25ec9_10.conda#f329cc15f3b4559cab20646245c3fc9b https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda#1d4e0d37da5f3c22ecd44033f673feba +https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda#6c4d3597cf43f3439a51b2b13e29a4ba https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda#ff63bb12ac31c176ff257e3289f20770 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f -https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 -https://conda.anaconda.org/conda-forge/linux-64/playwright-1.56.1-h5585027_0.conda#5e6fc54576b97242f1eb5a5deb411eca -https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda#4780fe896e961722d0623fa91d0d3378 -https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.10.1-hcb69869_2.conda#3bcec65152e70e02e8d17d296c056a82 -https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda#4e921d9c85e6559c60215497978b3cdb -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.11.0-h3d7a050_1.conda#89985ba2a3742f34be6aafd6a8f3af8c -https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313h09d1b84_0.conda#dfd94363b679c74937b3926731ee861a https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda#367133808e89325690562099851529c8 -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.1-py313hc80a56d_0.conda#1617960e1d8164f837ed5d0996603b88 +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py313hc80a56d_0.conda#a14fa0e1f58e2fce8d6fddf8f54ed500 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda#66b8b26023b8efdf8fcb23bac4b6325d -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda#d18004c37182f83b9818b714825a7627 -https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.2.4-py313h7033f15_1.conda#54e4dec31235bbc794d091af9afcd845 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h7f8ec31_1002.conda#c01021ae525a76fe62720c7346212d74 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_1.conda#638350cf5da41f3651958876a2104992 -https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c -https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 +https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda#ff63bb12ac31c176ff257e3289f20770 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda#16bff3d37a4f99e3aa089c36c2b8d650 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6-pyhcf101f3_0.conda#6725bfdf8ea7a8bf6415f096f3f1ffa5 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h50355cd_0.conda#8a96eab78687362de3e102a15c4747a8 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h80991f8_2.conda#37ca27d2f726f29a068230d8f6917ce4 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 +https://conda.anaconda.org/conda-forge/linux-64/playwright-1.57.0-h5585027_0.conda#0a2e773b5c3f67325d1733d2b7ca0ffb https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-2.13.6-pyh217bc35_3.conda#730a5284e26d6bdb73332dafb26aec82 +https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 @@ -199,77 +180,97 @@ https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.con https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda#23b4ba5619c4752976eb7ba1f5acb7e8 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_2.conda#00d80af3a7bf27729484e786a68aafff +https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py313h07c4f96_2.conda#7824f18e343d1f846dcde7b23c9bf31a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.2-h2ceb62e_4.conda#363b3e12e49cecf931338d10114945e9 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.15.0-h2a74896_1.conda#ffd553ff98ce5d74d3d89ac269153149 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.10.1-hcb69869_2.conda#3bcec65152e70e02e8d17d296c056a82 +https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda#4e921d9c85e6559c60215497978b3cdb +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.11.0-h3d7a050_1.conda#89985ba2a3742f34be6aafd6a8f3af8c https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda#d0616e7935acab407d1543b28c446f6f https://conda.anaconda.org/conda-forge/linux-64/coverage-7.12.0-py313h3dea7bd_0.conda#8ef99d298907bfd688a95cc714662ae7 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.60.1-py313h3dea7bd_0.conda#904860fc0d57532d28e9c6c4501f19a9 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py313h3dea7bd_0.conda#92f09729a821c52943d4b0b3749a2380 +https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 -https://conda.anaconda.org/conda-forge/noarch/pybind11-2.13.6-pyhc790b64_3.conda#1594696beebf1ecb6d29a1136f859a74 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h7f8ec31_1002.conda#c01021ae525a76fe62720c7346212d74 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb +https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c +https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.0-pyhd8ed1ab_0.conda#ec33a030c3bc90f0131305a8eba5f8a3 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.9-h4df99d1_101.conda#f41e3c1125e292e6bfcea8392a3de3d8 https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda#a4059bc12930bddeb41aef71537ffaed -https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-hd6e39bc_7.conda#0f7a1d2e2c6cdfc3864c4c0b16ade511 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.13.0-hf38f1be_1.conda#f10b9303c7239fbce3580a60a92bcf97 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.2-h2ceb62e_4.conda#363b3e12e49cecf931338d10114945e9 +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.15.0-h2a74896_1.conda#ffd553ff98ce5d74d3d89ac269153149 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.56.0-pyhcf101f3_0.conda#d0753cdc3baeacf68e697f457749a58b https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.2-pyhcf101f3_1.conda#da0c42269086f5170e2b296878ec13a6 +https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 +https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py313h54dd161_1.conda#710d4663806d0f72b2fb414e936223b5 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-h773bc41_4_cpu.conda#9d89be0b1ca8be7eedf821a365926338 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h5875eb1_mkl.conda#6a1a4ec47263069b2dae3cfba106320c -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-hd6e39bc_7.conda#0f7a1d2e2c6cdfc3864c4c0b16ade511 +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.13.0-hf38f1be_1.conda#f10b9303c7239fbce3580a60a92bcf97 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.35.2-py310hffdcd12_0.conda#2b90c3aaf73a5b6028b068cf3c76e0b7 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.3-h5c1c036_1.conda#762af6d08fdfa7a45346b1466740bacd https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a +https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-h773bc41_4_cpu.conda#9d89be0b1ca8be7eedf821a365926338 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h5875eb1_mkl.conda#6a1a4ec47263069b2dae3cfba106320c +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 +https://conda.anaconda.org/conda-forge/noarch/polars-1.35.2-pyh6a1acc5_0.conda#24e8f78d79881b3c035f89f4b83c565c +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.3-h5c1c036_1.conda#762af6d08fdfa7a45346b1466740bacd +https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-22.0.0-h8c2c5c3_4_cpu.conda#fdecd3d6168561098fa87d767de05171 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_hfef963f_mkl.conda#62ffd188ee5c953c2d6ac54662c158a7 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h5e43f62_mkl.conda#4f33d79eda3c82c95a54e8c2981adddb https://conda.anaconda.org/conda-forge/linux-64/libparquet-22.0.0-h7376487_4_cpu.conda#5e9383b1d25179787aff71aaad8208aa -https://conda.anaconda.org/conda-forge/noarch/polars-1.35.2-pyh6a1acc5_0.conda#24e8f78d79881b3c035f89f4b83c565c https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.3-py313h85046ba_1.conda#bb7ac52bfa917611096023598a7df152 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 +https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-22.0.0-h635bf11_4_cpu.conda#20f1a4625bce6e9b41e01232895450d9 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_hdba1596_mkl.conda#96dea51ff1435bd823020e25fd02da59 -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.8.0-cpu_mkl_h09b866c_102.conda#0194f4ea9e74964548ddb220b61d4712 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.9.1-cpu_mkl_hf3ca1bf_100.conda#d449787ee0ce676437bcaa48a20fa3c1 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py313hf6604e3_0.conda#15f43bcd12c90186e78801fafc53d89b https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-22.0.0-py313he109ebe_0_cpu.conda#0b4a0a9ab270b275eb6da8671edb9458 -https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e +https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_0.conda#e6475f566489789e65ebd5544db36b3e https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-2_hcf00494_mkl.conda#77b464e7c3b853268dec4c82b21dca5a https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda#6186382cb34a9953bf2a18fc763dc346 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-22.0.0-h635bf11_4_cpu.conda#6389644214f7707ab05f17f464863ed3 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_1.conda#9e87d4bda0c2711161d765332fa38781 -https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_0.conda#e6475f566489789e65ebd5544db36b3e -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.8.0-cpu_mkl_py313_h19d87ba_102.conda#755f7ca398f27fdab5c5842cdd7b0e89 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.9.1-cpu_mkl_py313_h5a1586b_100.conda#2230e60bae8b12369db0381e59324c0b https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h11c21cd_1.conda#26b089b9e5fcdcdca714b01f8008d808 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.0.1-pyhe01879c_0.conda#303ec962addf1b6016afd536e9db6bc6 https://conda.anaconda.org/conda-forge/linux-64/blas-2.302-mkl.conda#9c83adee9e1069446e6cc92b8ea19797 https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-22.0.0-h3f74fd7_4_cpu.conda#6f07bf204431fb87d8f827807d752662 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed -https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.8.0-cpu_mkl_hc60beec_102.conda#2b401c2d6c6b2f0d6c4e1862b4291247 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.9.1-cpu_mkl_hd61e0f4_100.conda#b56ab3c41a86a46bd1efdb33cf3752e0 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b https://conda.anaconda.org/conda-forge/linux-64/pyarrow-22.0.0-py313h78bf25f_0.conda#dfe7289ae9ad7aa091979a7c5e6a55c7 diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 8743a76f7e824..bd7a985b866fb 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -7,7 +7,8 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda#97c4b3bd8a90722104798175a1bdddbf https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h105ed1c_0.conda#61c2b02435758f1c6926b3733d34ea08 +https://conda.anaconda.org/conda-forge/osx-64/icu-75.1-h120a0e1_0.conda#d68d48a3060eb5abdc1cdc8e2a3a5966 +https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.6-h3d58e20_0.conda#866af4d7269cd8c9b70f5b49ad6173aa https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda#222e0732a1d0780a622926265bee14ef @@ -23,38 +24,37 @@ https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda#ced34 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda#47f1b8b4a76ebd0cd22bd7153e54a4dc https://conda.anaconda.org/conda-forge/osx-64/xorg-libxdmcp-1.1.5-h8616949_1.conda#435446d9d7db8e094d2c989766cfb146 -https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-6_kmp_llvm.conda#f699f090723c4948e11bfbb4a23e87f9 +https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda#eaac87c21aff3ed21ad9656697bb8326 https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda#21f765ced1a0ef4070df53cb425e1967 -https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h660c9da_0.conda#c8f29cbebccb17826d805c15282c7e8b -https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h2338291_0.conda#57b746e8ed03d56fe908fd050c517299 -https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-h336fb69_1.conda#b6331e2dcc025fc79cd578f4c181d6f2 +https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda#63186ac7a8a24b3528b4b14f21c03f54 +https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.51-h380d223_0.conda#d54babdd92ec19c27af739b53e189335 -https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.0-h86bffb9_0.conda#1ee9b74571acd6dd87e6a0f783989426 +https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.1-h6cc646a_0.conda#f71213ed0c51030cb17a77fc60a757f1 https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc -https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-h0ad03eb_0.conda#8487998051f3d300fef701a49c27f282 +https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-ha1d9b0f_0.conda#453807a4b94005e7148f89f9327eb1b7 https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda#afda563484aa0017278866707807a335 https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda#3f50cdf9a97d0280655758b735781096 https://conda.anaconda.org/conda-forge/osx-64/qhull-2020.2-h3c5361c_5.conda#dd1ea9ff27c93db7c01a7b7656bd4ad4 https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda#342570f8e02f2f022147a7f841475784 https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda#bd9f1de651dbd80b51281c694827f78f -https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.2.5-h55e386d_0.conda#692a62051af2270eb9c24e8f09e88db6 -https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h8210216_2.conda#cd60a4a5a8d6a476b30d8aa4bb49251a -https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h5c1846c_0.conda#e3b4a50ddfcda3835379b10c5b0c951b +https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.1-h55e386d_0.conda#a74905e66f8d64c939c1010f1ade58f9 +https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h281d3d1_4.conda#40d8b69d4ab5b315e615ac0bdb650613 +https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.conda#dfbdc8fd781dc3111541e4234c19fdbd -https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h306097a_1.conda#cd5393330bff47a00d37a117c65b65d0 +https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_14.conda#ad31de7df92caf04a70d0d8dc48d9ecd https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 -https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h23bb396_0.conda#65dd26de1eea407dda59f0da170aed22 +https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h7b7ecba_0.conda#e7ed73b34f9d43d80b7e80eba9bce9f3 https://conda.anaconda.org/conda-forge/osx-64/python-3.14.0-hf88997e_102_cp314.conda#7917d1205eed3e72366a3397dca8a2af -https://conda.anaconda.org/conda-forge/osx-64/brotli-1.2.0-hb27157a_0.conda#01fd35c4b0b4641d3174d5ebb6065d96 +https://conda.anaconda.org/conda-forge/osx-64/brotli-1.2.0-hf139dec_1.conda#149d8ee7d6541a02a6117d8814fd9413 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 -https://conda.anaconda.org/conda-forge/osx-64/cython-3.2.1-py314h9fad922_0.conda#ed199501ba2943766cc51a898650cccd +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/osx-64/cython-3.2.2-py314h9fad922_0.conda#4e8210b53b2a0cb9d397c6cc025d0fec https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.9-py314hf3ac25a_2.conda#28a77c52c425fa9c6d914c609c626b1a https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.17-h72f5680_0.conda#bf210d0c63f2afb9e414a858b79f0eaa https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.1-h694c41f_0.conda#e0e2edaf5e0c71b843e25a7ecc451cc9 -https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.0.2-h2beb688_0.tar.bz2#524282b2c46c9dedf051b3bc2ae05494 +https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_14.conda#0f4173df0120daf2b2084a55960048e8 https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.1-default_h094e1f9_1002.conda#4d9e9610b6a16291168144842cd9cae2 https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 @@ -69,24 +69,26 @@ https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_2.conda#00d80af3a7bf27729484e786a68aafff +https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.2-py314h6482030_2.conda#d97f0d30ffb1b03fa8d09ef8ba0fdd7c https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.0-py314h6482030_1.conda#d69097de15cbad36f1eaafda0bad598a -https://conda.anaconda.org/conda-forge/osx-64/ccache-4.11.3-h33566b8_0.conda#b65cad834bd6c1f660c101cca09430bf https://conda.anaconda.org/conda-forge/osx-64/coverage-7.12.0-py314hb9c7d66_0.conda#d8805ca5ce27c9a2182baf03a16209ab https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.60.1-pyh7db6752_0.conda#85c6b2f3ae5044dd279dc0970f882cd9 +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.0-pyh7db6752_0.conda#2ae6c63938d6dd000e940673df75419c https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.1-h694c41f_0.conda#ca641fdf8b7803f4b7212b6d66375930 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/osx-64/pillow-12.0.0-py314h0a84944_0.conda#95252d1cf079f62c4d0ea90eb5cd7219 +https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_14.conda#c11e0acbe6ba3df9a30dbe7f839cbd99 +https://conda.anaconda.org/conda-forge/osx-64/pillow-12.0.0-py314hedf0282_2.conda#399177697c7225b64edeaeb373a8c98b https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.13.0-hf0c99ee_4.conda#411c95470bff187ae555120702f28c0e +https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.0.2-h2beb688_0.tar.bz2#524282b2c46c9dedf051b3bc2ae05494 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/osx-64/mkl-2023.2.0-h694c41f_50502.conda#0bdfc939c8542e0bc6041cbd9a900219 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/osx-64/ccache-4.11.3-h33566b8_0.conda#b65cad834bd6c1f660c101cca09430bf https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-20_osx64_mkl.conda#160fdc97a51d66d51dc782fb67d35205 https://conda.anaconda.org/conda-forge/osx-64/mkl-devel-2023.2.0-h694c41f_50502.conda#045f993e4434eaa02518d780fdca34ae https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock index 9aa61ae3d9577..fa1eff93c7b1a 100644 --- a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock @@ -4,13 +4,13 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/libgfortran-devel_osx-arm64-14.3.0-hc965647_1.conda#c1b69e537b3031d0f5af780b432ce511 https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a66894dfd07c4510beb6b3f9672ccc0 -https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-4-hd8ed1ab_3.tar.bz2#878f923dd6acc8aeb47a75da6c4098be +https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 +https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-14.5-hfa17104_3.conda#3351af6c29661d56d7ef9ea9699d1314 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda#58fd217444c2a5701a44244faf518206 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda#5eb22c1d7b3fc4abb50d92d621583137 -https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-h87ba0bc_0.conda#07d43b5e2b6f4a73caed8238b60fabf5 +https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.6-hf598326_0.conda#3ea79e55a64bff6c3cbd4588c89a527a https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda#b79875dbb5b1db9a4a22a4520f918e1a @@ -27,63 +27,63 @@ https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda#06 https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda#415816daf82e0b23a736a069a75e9da7 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda#78b548eed8227a689f93775d5d23ae09 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxdmcp-1.1.5-hc919400_1.conda#9d1299ace1924aa8f4e0bc8e71dd0cf7 +https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda#a44032f282e7d2acdeb1c240308052dd +https://conda.anaconda.org/conda-forge/osx-arm64/fmt-12.0.0-h669d743_0.conda#364025d9b6f6305a73f8a5e84a2310d5 https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-h7bae524_2.conda#eed7278dfbab727b56f2c0b64330814b https://conda.anaconda.org/conda-forge/osx-arm64/isl-0.26-imath32_h347afa1_101.conda#e80e44a3f4862b1da870dc0557f8cf3b https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda#a74332d9b60b62905e3d30709df08bf1 https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20250512.1-cxx17_hd41c47c_0.conda#360dbb413ee2c170a0a684a33c4fc6b8 -https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-h95a88de_0.conda#39d47dac85038e73b5f199f2b594a547 -https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hb1b9735_0.conda#4e3fec2238527187566e26a5ddbc2f83 +https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda#079e88933963f3f149054eec2c487bc2 +https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_1.conda#1399af81db60d441e7c6577307d5cf82 -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-h742603c_1.conda#afccf412b03ce2f309f875ff88419173 https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.51-hfab5511_0.conda#06efb9eace7676738ced2f9661c59fb8 -https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.0-h8adb53f_0.conda#5fb1945dbc6380e6fe7e939a62267772 +https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.1-h9a5124b_0.conda#67e50e5bd4e5e2310d66b88c4da50096 https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 -https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h0ff4647_0.conda#438c97d1e9648dd7342f86049dd44638 +https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h8eac4d7_0.conda#cf7291a970b93fe3bb726879f2037af8 https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda#175809cc57b2c67f27a0f238bd7f069d https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda#b34dc4172653c13dcf453862f251af2b https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda#6483b1f59526e05d7d894e466b5b6924 https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda#63ef3f6e6d6d5c589e64f11263dc5676 https://conda.anaconda.org/conda-forge/osx-arm64/sleef-3.9.0-hb028509_0.conda#68f833178f171cfffdd18854c0e9b7f9 -https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1300.6.5-h03f4b80_0.conda#b703bc3e6cba5943acf0e5f987b5d0e2 +https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_0.conda#347261d575a245cb6111fb2cb5a79fc7 https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_3.conda#a73d54a5abba6543cb2f0af1bfbd6851 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda#e3170d898ca6cb48f1bb567afb92f775 -https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.2.5-h3470cca_0.conda#c86493f35e79c93b04ff0279092b53e2 -https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-h6491c7d_2.conda#e6f69c7bcccdefa417f056fa593b40f0 -https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hce9b42c_0.conda#2695046c2e5875fee19438aa752924a5 +https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.1-h3470cca_0.conda#30c613d957b652b9604c5eaf8532562d +https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hd0aec43_4.conda#93345396269a7f456f2e80de6bda540d +https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda#6d4ede03e2a8e20eb51f7f681d2a2550 -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-hfcf01ff_1.conda#f699348e3f4f924728e33551b1920f79 +https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_14.conda#1b3fb17dd26afdafe0bf30fafcb900a2 https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.31.1-h658db43_2.conda#155d3d17eaaf49ddddfe6c73842bc671 https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 -https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-h9329255_0.conda#fb5ce61da27ee937751162f86beba6d1 +https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-hba2cd1d_0.conda#a53d5f7fff38853ddb6bdc8fb609c039 https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.1-hb693164_3.conda#4e4ea852d54cc2b869842de5044662fb https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.9-hfc2f54d_101_cp313.conda#a4241bce59eecc74d4d2396e108c93b8 https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-0.1.3-h44b9a77_0.tar.bz2#4a2cac04f86a4540b8c9b8d8f597848f -https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-hca488c2_0.conda#3673e631cdf1fa81c9f5cc3da763a07e +https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda#48ece20aa479be6ac9a284772827d00c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda#367133808e89325690562099851529c8 -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 -https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.1-py313h66a7184_0.conda#e9970e29bc5029e981fedcd31cff310a +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.2-py313h66a7184_0.conda#e5fd9ec2e9f89306a3f48302b29df4e1 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda#66b8b26023b8efdf8fcb23bac4b6325d https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda#d18004c37182f83b9818b714825a7627 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py313h7add70c_2.conda#9583687276aaa393e723f3b7970be69f https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda#92a61fd30b19ebd5c1621a5bfe6d8b5f -https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-2_h8d724d3_accelerate.conda#143e99fafc3cdd43c917ff8183f6a219 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda#f35fb38e89e2776994131fbf961fa44b -https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.0.2-hbec66e7_0.tar.bz2#37ca71a16015b17397da4a5e6883f66f +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_14.conda#4fa9de90ec33234997aed5871d20f14e https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h7d74516_0.conda#3df5979cc0b761dda0053ffdb0bca3ea https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.3.1-h8f1351a_1.conda#a5635df796b71f6ca400fc7026f50701 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda#16bff3d37a4f99e3aa089c36c2b8d650 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6-pyhcf101f3_0.conda#6725bfdf8ea7a8bf6415f096f3f1ffa5 https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hbfb3c88_0.conda#6bf3d24692c157a41c01ce0bd17daeea https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-2.13.6-pyh217bc35_3.conda#730a5284e26d6bdb73332dafb26aec82 +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 @@ -91,64 +91,68 @@ https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_2.conda#00d80af3a7bf27729484e786a68aafff +https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.2-py313h6535dbc_2.conda#c7fea1e31871009ff882a327ba4b7d9a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.11.3-hd7c7cec_0.conda#7fe1ee81492f43731ea583b4bee50b8b https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.12.0-py313h7d74516_0.conda#35d87ef273c80581a7f73172b757e4e2 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.60.1-py313h7d74516_0.conda#107233e5dccf267cfc6fd551a10aea4e +https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.61.0-py313h7d74516_0.conda#4c69b2b96797e459051f24ae70d22220 https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.1-hce30654_0.conda#1ec9a1ee7a2c9339774ad9bb6fe6caec https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.2.1-py313hc1c22ca_2.conda#08bbc47d90ccee895465f61b8692e236 -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-955.13-llvm19_1_h6922315_9.conda#6725e9298bc2bc60c2dd48cc470db59b -https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-2_h752f6bc_accelerate.conda#e0e6e7e33c7bc6b61471ee1014b7d4a9 +https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_h6922315_1.conda#66697cc97d32afa29c17855b3d56680e https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_h73dfc95_5.conda#0b1110de04b80ea62e93fef6f8056fbb -https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-2_hcb0d94e_accelerate.conda#cc5238dd60dec488f46a164cdba0a0f5 +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_14.conda#3187356c87594c3ebc3b8c0bd72a7e9f https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef -https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.0.0-py313h54da0cd_0.conda#fe80ca21c7be92922c5718a46ec50959 -https://conda.anaconda.org/conda-forge/noarch/pybind11-2.13.6-pyhc790b64_3.conda#1594696beebf1ecb6d29a1136f859a74 +https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.0.0-py313ha86496b_2.conda#d52bb6207093e90d6b70649728257e3f +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_h73dfc95_5.conda#561b822bdb2c1bb41e16e59a090f1e36 -https://conda.anaconda.org/conda-forge/osx-arm64/ld64-955.13-he86490a_9.conda#279533a0a5e350ee3c736837114f9aaf -https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-2_hbdd07e9_accelerate.conda#790ab9dc92e3f2374a848a27d3ea3be1 +https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_1.conda#3a3ff7c8991ea2807eb13425733491c2 +https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-2_h8d724d3_accelerate.conda#143e99fafc3cdd43c917ff8183f6a219 +https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.0.2-hbec66e7_0.tar.bz2#37ca71a16015b17397da4a5e6883f66f https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.3.5-py313h9771d21_0.conda#3f8330206033158d3e443120500af416 https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.18.0-py313ha61f8ec_0.conda#08c825d0a6cde154eb8c4729563114e7 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 -https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-2_h55bc449_accelerate.conda#a9d1c17bf0b35053727c05235be9b7ba -https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1024.3-llvm19_1_h8c76c84_9.conda#89b4c077857b4cfd7220a32e7f96f8e1 +https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.11.3-hd7c7cec_0.conda#7fe1ee81492f43731ea583b4bee50b8b +https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_h8c76c84_1.conda#296de61644a3372f5cf13f266eb6ad88 https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_5.conda#6773a2b7d7d1b0a8d0e0f3bf4e928936 -https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313ha61f8ec_3.conda#5643cff3e9ab77999fba139465156e35 -https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.8.0-cpu_generic_hf67e7d3_2.conda#cebb78a08e92e7a1639d6e0a645c917a -https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.3-py313h7d16b84_1.conda#5ddddcc319d3aee21cc4fe4640a61f8a +https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-2_h752f6bc_accelerate.conda#e0e6e7e33c7bc6b61471ee1014b7d4a9 +https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-2_hcb0d94e_accelerate.conda#cc5238dd60dec488f46a164cdba0a0f5 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.16.3-py313h0d10b07_1.conda#55c947938346fb644c2752383c40f935 -https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.302-accelerate.conda#cce50d5ad6fc1de3752d42d71af96b6c -https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1024.3-hd01ab73_9.conda#3819ebcafd8ade70c3c20dd3e368b699 +https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_1.conda#4df7fec2dac84a966f9de8addd561561 +https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_1.conda#e9d1109b5313ca4969210c3bedec6f0b https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_h36137df_5.conda#c11a3a5a0cdb74d8ce58c6eac8d1f662 https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda#8d99c82e0f5fed6cc36fcf66a11e03f0 +https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-2_hbdd07e9_accelerate.conda#790ab9dc92e3f2374a848a27d3ea3be1 +https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.9.1-cpu_generic_h040b7fb_0.conda#73bf235baaa1d1528f8f48bbbdfde1a3 +https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.3.5-py313h9771d21_0.conda#3f8330206033158d3e443120500af416 +https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 +https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-2_h55bc449_accelerate.conda#a9d1c17bf0b35053727c05235be9b7ba +https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 +https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313ha61f8ec_3.conda#5643cff3e9ab77999fba139465156e35 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_impl_osx-arm64-14.3.0-h6d03799_1.conda#1e9ec88ecc684d92644a45c6df2399d0 +https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.3-py313h7d16b84_1.conda#5ddddcc319d3aee21cc4fe4640a61f8a +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.9.1-cpu_generic_py313_h6bf06e3_0.conda#5d3ce52595cf76e7352aee892ace4a6c +https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.16.3-py313h0d10b07_1.conda#55c947938346fb644c2752383c40f935 +https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.302-accelerate.conda#cce50d5ad6fc1de3752d42d71af96b6c +https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-h76e6a08_26.conda#f872a20e3b1d19aa054f113ae3804372 https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py313h58042b9_0.conda#745c18472bc6d3dc9146c3dec18bb740 https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py313h28ea3aa_1.conda#51a353d043e612a8f520627cf0e73653 -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.8.0-cpu_generic_py313_h1ee2325_2.conda#fce43a59b1180cdcb1ca67f5f45b72ac -https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.9.1-cpu_generic_hcc7c195_0.conda#317359fedeb03a60ac1831166eff601d +https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h07b0088_26.conda#bae6f596e3ce534c6a23922711510228 https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py313h39782a4_0.conda#bae471007cbebf097a19e851c219d56a -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.8.0-cpu_generic_py313_h510b526_2.conda#a8282f13e5e3abcc96a78154f0f25ae3 -https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-h76e6a08_25.conda#a4e2f211f7c3cf582a6cb447bee2cad9 -https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h07b0088_25.conda#1b53cb5305ae53b5aeba20e58c625d96 https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda#148516e0c9edf4e9331a4d53ae806a9b -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-h276745f_25.conda#5eeaa7b2dd32f62eb3beb0d6ba1e664f +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-h276745f_26.conda#7654ab743ef26bf8018f510f918665d4 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_osx-arm64-14.3.0-h3c33bd0_0.conda#8db8c0061c0f3701444b7b9cc9966511 -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h07b0088_25.conda#4e09188aa8def7d8b3ae149aa856c0e5 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h07b0088_26.conda#51cfb178328f60dbaad16fa06b0f20c2 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran-14.3.0-h3ef1dbf_0.conda#e148e0bc9bbc90b6325a479a5501786d https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda#043afed05ca5a0f2c18252ae4378bdee https://conda.anaconda.org/conda-forge/osx-arm64/fortran-compiler-1.11.0-h81a4f41_0.conda#d221c62af175b83186f96d8b0880bff6 diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index d9fcd7de5fc54..319d62e6fda92 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -6,33 +6,32 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda#3036ca5b895b7f5146c5a25486234a68 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda#f7b4d76975aac7e5d9e6ad13845f92fe +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda#c0374badb3a5d4b1372db28d19462c53 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda#280ea6eee9e2ddefde25ff799c4f0363 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda#f116940d825ffc9104400f0d7f1a4551 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda#5b767048b1b3ee9a954b06f4084f93dc +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda#8621a450add4e231f676646880703f49 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda#f627678cf829bd70bccf141a19c3ad3e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 -https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_7.conda#beeb74a6fe5ff118451cf0581bfe2642 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda#729a572a3ebb8c43933b30edcc628ceb -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda#4780fe896e961722d0623fa91d0d3378 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 @@ -40,10 +39,10 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip charset-normalizer @ https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 # pip coverage @ https://files.pythonhosted.org/packages/76/b6/67d7c0e1f400b32c883e9342de4a8c2ae7c1a0b57c5de87622b7262e2309/coverage-7.12.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=bc13baf85cd8a4cfcf4a35c7bc9d795837ad809775f782f697bf630b7e200211 # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 -# pip cython @ https://files.pythonhosted.org/packages/f9/33/5d9ca6abba0e77e1851b843dd1b3c4095fbc6373166935e83c4414f80e88/cython-3.2.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=f5a54a757d01ca6a260b02ce5baf17d9db1c2253566ab5844ee4966ff2a69c19 -# pip docutils @ https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl#sha256=dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2 +# pip cython @ https://files.pythonhosted.org/packages/57/c1/76928c07176a4402c74d5b304936ad8ee167dd04a07cf7dca545e8c25f9b/cython-3.2.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=a473df474ba89e9fee81ee82b31062a267f9e598096b222783477e56d02ad12c +# pip docutils @ https://files.pythonhosted.org/packages/11/a8/c6a4b901d17399c77cd81fb001ce8961e9f5e04d3daf27e8925cb012e163/docutils-0.22.3-py3-none-any.whl#sha256=bd772e4aca73aff037958d44f2be5229ded4c09927fcf8690c577b66234d6ceb # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec -# pip fonttools @ https://files.pythonhosted.org/packages/2d/8b/371ab3cec97ee3fe1126b3406b7abd60c8fec8975fd79a3c75cdea0c3d83/fonttools-4.60.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl#sha256=b33a7884fabd72bdf5f910d0cf46be50dce86a0362a65cfc746a4168c67eb96c +# pip fonttools @ https://files.pythonhosted.org/packages/4e/80/c87bc524a90dbeb2a390eea23eae448286983da59b7e02c67fa0ca96a8c5/fonttools-4.61.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl#sha256=b2b734d8391afe3c682320840c8191de9bd24e7eb85768dd4dc06ed1b63dbb1b # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea # pip imagesize @ https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl#sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 @@ -59,7 +58,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b # pip pyparsing @ https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl#sha256=e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e # pip pytz @ https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl#sha256=5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 -# pip roman-numerals-py @ https://files.pythonhosted.org/packages/53/97/d2cbbaa10c9b826af0e10fdf836e1bf344d9f0abb873ebc34d1f49642d3f/roman_numerals_py-3.1.0-py3-none-any.whl#sha256=9da2ad2fb670bcf24e81070ceb3be72f6c11c440d73bd579fbeca1e9f330954c +# pip roman-numerals @ https://files.pythonhosted.org/packages/82/1d/7356f115a0e5faf8dc59894a3e9fc8b1821ab949163458b0072db0a12a68/roman_numerals-3.1.0-py3-none-any.whl#sha256=842ae5fd12912d62720c9aad8cab706e8c692556d01a38443e051ee6cc158d90 # pip six @ https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl#sha256=4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 # pip snowballstemmer @ https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl#sha256=6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 # pip sphinxcontrib-applehelp @ https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl#sha256=4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 @@ -88,5 +87,5 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 # pip scipy-doctest @ https://files.pythonhosted.org/packages/f5/99/a17f725f45e57efcf5a84494687bba7176e0b5cba7ca0f69161a063fa86d/scipy_doctest-2.0.1-py3-none-any.whl#sha256=7725b1cb5f4722ab2a77b39f0aadd39726266e682b19e40f96663d7afb2d46b1 -# pip sphinx @ https://files.pythonhosted.org/packages/31/53/136e9eca6e0b9dc0e1962e2c908fbea2e5ac000c2a2fbd9a35797958c48b/sphinx-8.2.3-py3-none-any.whl#sha256=4405915165f13521d875a8c29c8970800a0141c14cc5416a38feca4ea5d9b9c3 +# pip sphinx @ https://files.pythonhosted.org/packages/fe/8b/76e2a1ce12b915399365873eef2b1197da9d032c99e661a71fd7e1490333/sphinx-9.0.0-py3-none-any.whl#sha256=3442bf635d378da2ba4e88aa8496f3a61b2d59ef145aeaf34353ab93fd79f1bf # pip numpydoc @ https://files.pythonhosted.org/packages/6c/45/56d99ba9366476cd8548527667f01869279cedb9e66b28eb4dfb27701679/numpydoc-1.8.0-py3-none-any.whl#sha256=72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541 diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 9f881ff559fc7..ed5d6b562fb93 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -10,14 +10,13 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda#3036ca5b895b7f5146c5a25486234a68 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.6-h4922eb0_0.conda#7a0b9ce502e0ed62195e02891dfcd704 -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-6_kmp_llvm.conda#197811678264cb9da0d2ea0726a70661 +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda#c0374badb3a5d4b1372db28d19462c53 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc @@ -26,8 +25,8 @@ https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda#280ea6eee9e2ddefde25ff799c4f0363 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda#f116940d825ffc9104400f0d7f1a4551 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc @@ -37,7 +36,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb9d3cd8_3.conda# https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda#b64523fb87ac6f87f0790f324ad43046 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda#5b767048b1b3ee9a954b06f4084f93dc +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -63,10 +62,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.25.1-h3f43e3d_1.conda#2f4de899028319b27eb7a4023be5dfd2 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda#8621a450add4e231f676646880703f49 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda#f627678cf829bd70bccf141a19c3ad3e +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -80,8 +80,8 @@ https://conda.anaconda.org/conda-forge/linux-64/s2n-1.3.46-h06160fa_0.conda#413d https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.2.5-hde8ca8f_0.conda#1920c3502e7f6688d650ab81cd3775fd -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda#580a52a05f5be28ce00764149017c6d4 https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 @@ -89,6 +89,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1. https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda#d1db1b8be7c3a8983dcbbbfe4f0765de https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.25.1-h3f43e3d_1.conda#fd9cf4a11d07f0ef3e44fc061611b1ed https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.conda#081aa22f4581c08e4372b0b6c2f8478e @@ -96,7 +97,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.co https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.25.1-h3f43e3d_1.conda#3f7a43b3160ec0345c9535a9f0d7908e -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_7.conda#beeb74a6fe5ff118451cf0581bfe2642 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h6548e54_1.conda#f01292fb36b6d00d5c51e5d46b513bcf https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 @@ -104,6 +105,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_2.co https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h8fd135c_2.conda#bbf65f7688512872f063810623b755dc https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318b08df404f9c9be5712aaa5a6f0bb0 +https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/rdma-core-28.9-h59595ed_1.conda#aeffb7c06b5f65e55e6c637408dc4100 https://conda.anaconda.org/conda-forge/linux-64/re2-2023.03.02-h8c504da_0.conda#206f8fa808748f6e90599c3368a1114e https://conda.anaconda.org/conda-forge/linux-64/snappy-1.1.10-hdb0a2a9_1.conda#78b8b85bdf1f42b8a2b3cb577d8742d1 @@ -115,7 +117,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.co https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.13.27-h3870b5a_0.conda#b868db6b48436bdbda71aa8576f4a44d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.conda#d47dee1856d9cb955b8076eeff304a5b https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda#679616eb5ad4e521c83da4650860aba7 +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/gettext-0.25.1-h3f43e3d_1.conda#c42356557d7f2e37676e121515417e3b https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.2-hf516916_1.conda#495c262933b7c5b8c09413d44fa5974b https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 @@ -126,10 +128,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda#729a572a3ebb8c43933b30edcc628ceb https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-1.8.4-h2f23424_0.conda#4bb92585a250e67d49b46c073d29f9dd +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 https://conda.anaconda.org/conda-forge/linux-64/ucx-1.14.1-h64cca9d_5.conda#39aa3b356d10d7e5add0c540945a0944 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 @@ -139,45 +141,31 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_ https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.3.1-h1e03375_0.conda#3082be841420d6288bc1268a9be45b75 https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.7.10-h9ab9c9b_2.conda#cf49873da2e59f876a2ad4794b05801b https://conda.anaconda.org/conda-forge/linux-64/brotli-1.0.9-h166bdaf_9.conda#4601544b4982ba1861fa9b9c607b2c06 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc -https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda#ee48bf17cc83a00f59ca1494d5646869 -https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f -https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee -https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.0-h435f46f_0.conda#c7726f96aab024855ede05e0ca6e94a0 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.8.13-hd4f18eb_5.conda#860fb8c0efec64a4a678eb2ea066ff65 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.0.9-py311ha362b79_9.conda#ced5340f5dc6cff43a80deac8d0e398f +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_1.conda#638350cf5da41f3651958876a2104992 -https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda#ef1910918dd895516a769ed36b5b3a4e -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc +https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda#ee48bf17cc83a00f59ca1494d5646869 +https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 +https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311h07c5bb8_0.conda#51f505a537b2d216a1b36b823df80995 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda#5c7a868f8241e64e1cf5fdf4962f23e2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e @@ -188,54 +176,66 @@ https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#4 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda#978d03388b62173b8e6f79162cf52b86 -https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_2.conda#00d80af3a7bf27729484e786a68aafff +https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py311h49ec1c0_2.conda#8d7a63fc9653ed0bdc253a51d9a5c371 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.0-h435f46f_0.conda#c7726f96aab024855ede05e0ca6e94a0 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.8.13-hd4f18eb_5.conda#860fb8c0efec64a4a678eb2ea066ff65 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b https://conda.anaconda.org/conda-forge/linux-64/coverage-7.12.0-py311h3778330_0.conda#4ef5919a315f5c2834fc8da49044156d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.60.1-py311h3778330_0.conda#91f834f85ac92978cfc3c1c178573e85 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py311h3778330_0.conda#f5ee391df23b7f50676ebe79fc53ee03 https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.2-h5192d8d_1.conda#7071a9745767777b4be235f8c164ea75 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae -https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb +https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda#ef1910918dd895516a769ed36b5b3a4e +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 -https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.20.2-h2a5cb19_18.conda#7313674073496cec938f73b71163bc31 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-20_linux64_openblas.conda#9932a1d4e9ecf2d35fb19475446e361e -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 -https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 +https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 +https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h7b9373a_16.conda#54db1af780a69493a2e0675113a027f9 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.20.2-h2a5cb19_18.conda#7313674073496cec938f73b71163bc31 +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-20_linux64_openblas.conda#9932a1d4e9ecf2d35fb19475446e361e +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.11-h651a532_0.conda#d8d8894f8ced2c9be76dc9ad1ae531ce -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c +https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a -https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h7b9373a_16.conda#54db1af780a69493a2e0675113a027f9 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h3c3fd16_6.conda#5aab84b9d164509b5bbe3af660518606 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_3.conda#d2bbbd293097e664ffb01fc4cdaf5729 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.0-py311h39c9aba_9_cpu.conda#c35fe329bcc51a1a3a254c990ba8f738 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.0-py311h39c9aba_9_cpu.conda#c35fe329bcc51a1a3a254c990ba8f738 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b # pip pytz @ https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl#sha256=5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index a6903bbe4eef5..58890b5886d00 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -6,20 +6,19 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda#3036ca5b895b7f5146c5a25486234a68 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda#f7b4d76975aac7e5d9e6ad13845f92fe +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda#c0374badb3a5d4b1372db28d19462c53 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda#280ea6eee9e2ddefde25ff799c4f0363 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda#f116940d825ffc9104400f0d7f1a4551 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda#5b767048b1b3ee9a954b06f4084f93dc +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 @@ -29,38 +28,36 @@ https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002. https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda#8621a450add4e231f676646880703f49 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda#f627678cf829bd70bccf141a19c3ad3e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.2.5-hde8ca8f_0.conda#1920c3502e7f6688d650ab81cd3775fd -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 -https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_7.conda#beeb74a6fe5ff118451cf0581bfe2642 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h4a7cf45_openblas.conda#6146bf1b7f58113d54614c6ec683c14a https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda#729a572a3ebb8c43933b30edcc628ceb https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_h0358290_openblas.conda#a84b2b7ed34206d14739fb8d29cd2799 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h47877c9_openblas.conda#9fb20e74a7436dc94dd39d9a9decddc3 https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a -https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h7c6b74e_0.conda#645bc783bc723d67a294a51bc860762d +https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.1-py311h0daaf2c_0.conda#1be85c7845e9ba143f3cef9fd5780dc3 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py311h0daaf2c_0.conda#93f275715239f0ad95343a75fb15dbd7 https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e @@ -68,12 +65,12 @@ https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_h6ae95b6_openblas.conda#35d16498d50b73886cb30014c2741726 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_h0358290_openblas.conda#a84b2b7ed34206d14739fb8d29cd2799 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h47877c9_openblas.conda#9fb20e74a7436dc94dd39d9a9decddc3 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py311h2e04523_0.conda#01da92ddaf561cabebd06019ae521510 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311h07c5bb8_0.conda#51f505a537b2d216a1b36b823df80995 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 @@ -91,22 +88,24 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d27 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-2_h1ea3ea9_openblas.conda#7cee1860b6bf5a1deb8a62a6b2dfcfbd https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_h6ae95b6_openblas.conda#35d16498d50b73886cb30014c2741726 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py311h2e04523_0.conda#01da92ddaf561cabebd06019ae521510 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311h1e13796_1.conda#e1947291b713cb0afa949e1bcda1f935 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.302-openblas.conda#fa34398c7f1c68bec5f00b0a841d2d05 +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-2_h1ea3ea9_openblas.conda#7cee1860b6bf5a1deb8a62a6b2dfcfbd https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_1.conda#72e3452bf0ff08132e86de0272f2fbb0 -https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311h1e13796_1.conda#e1947291b713cb0afa949e1bcda1f935 https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.302-openblas.conda#fa34398c7f1c68bec5f00b0a841d2d05 +https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock index 507b357f67636..797799b84cad9 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock @@ -14,7 +14,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda#8a86073cf3b343b87d03f41790d8b4e5 https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda#58f67b437acbf2764317ba273d731f1d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h1383e82_7.conda#7f970a7f9801622add7746aa3cbc24d5 +https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_14.conda#c21643058895b399fd413e6ba17f587f https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda#378d5dcec45eaea8d303da6f00447ac0 https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda#37e16618af5c4851a3f3d66dd0e11141 https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_32.conda#ef02bbe151253a72b8eda264a935db66 @@ -23,16 +23,16 @@ https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.3.1-he0c23c2_0 https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda#b785694dd3ec77a011ccf0c24725382b https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda#8579b6bb8d18be7c0b27fb08adeeeb40 https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda#c1b81da6d29a14b542da14a36c9fbf3f -https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hc82b238_0.conda#a5607006c2135402ca3bb96ff9b87896 +https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda#444b0a45bbd1cb24f82eedb56721b9c4 https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda#8c9e4f1a0e688eef2e95711178061a0f https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda#ba4ad812d2afc22b9a34ce8327a0930f -https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h1383e82_7.conda#926a82fc4fa5b284b1ca1fb74f20dee2 +https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_14.conda#b39b17a9f5ec5f3a395dbf0f5ee13b66 https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#64571d1dd6cdcfa25d0664a5950fdaa2 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda#56a686f92ac0273c0f6af58858a3f013 https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda#c15148b2e18da456f5108ccb5e411446 https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.30-pthreads_h877e47f_4.conda#f551f8ae0ae6535be1ffde181f9377f3 -https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.0-hf5d6505_0.conda#d2c9300ebd2848862929b18c264d1b1e +https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.1-hf5d6505_0.conda#f92bef2f8e523bb0eabe60099683617a https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.328.1-h477610d_0.conda#4403eae6c81f448d63a7f66c0b330536 https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda#f9bbae5e2537e3b06e0f7310ba76c893 https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda#41fbfac52c601159df6c01f875de31b9 @@ -41,11 +41,11 @@ https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda#84f https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda#08c8fa3b419df480d985e304f7884d35 https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda#854fbdff64b572b5c0b470f334d34c11 https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_3.conda#7cb36e506a7dba4817970f8adb6396f9 -https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.2.5-h32d8bfd_0.conda#dec092b1a069abafc38655ded65a7b29 +https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.1-h32d8bfd_0.conda#de8426202e7a7de6cc431835224f7551 https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda#31aec030344e962fbd7dbbbbd68e60a9 https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-2_h0adab6e_openblas.conda#95fa206f4ffdc2993fa6a48b07b4c77d -https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-h431afc6_0.conda#edc47a5d0ec6d95efefab3e99d0f4df0 -https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-ha521d6b_0.conda#f780291507a3f91d93a7147daea082f8 +https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda#450e3ae947fc46b60f1d8f8f318b40d4 +https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda#ccd93cfa8e54fd9df4e83dbe55ff6e8c https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda#2cf0cf76cc15d360dfa2f17fd6cf9772 https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.51-h7351971_0.conda#5b98079b7e86c25c7e70ed7fd7da7da5 https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h06f855e_0.conda#4a5ea6ec2055ab0dfd09fd0c498f834a @@ -55,11 +55,11 @@ https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.co https://conda.anaconda.org/conda-forge/win-64/python-3.11.14-h0159041_2_cpython.conda#02a9ba5950d8b78e6c9862d6ba7a5045 https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda#8436cab9a76015dfe7208d3c9f97c156 https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda#a7c03e38aa9c0e84d41881b9236eacfb -https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-hbeecb71_2.conda#21f56217d6125fb30c3c3f10c786d751 -https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-h6910e44_0.conda#c3a73d78af195cb2621e9e16426f7bba +https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h1b5488d_4.conda#4fcccc053a113f5711dddf64401e9010 +https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hfd05255_1.conda#6abd7089eb3f0c790235fe469558d190 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 -https://conda.anaconda.org/conda-forge/win-64/cython-3.2.1-py311h9990397_0.conda#012d47877f130af0cf3434dbda810e96 +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/win-64/cython-3.2.2-py311h9990397_0.conda#c146d51910e29a6d6060ecf84ba7978d https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py311h275cad7_2.conda#e9eb24a8d111be48179bf82a9e0e13ca @@ -80,13 +80,13 @@ https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_2.conda#00d80af3a7bf27729484e786a68aafff +https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.2-py311h3485c13_2.conda#56b468f7a48593bc555c35e4a610d1f2 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.0-py311h3485c13_1.conda#a30a6a70ab7754dbf0b06fe1a96af9cb https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 -https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h17ff524_0.conda#60c575ea855a6aa03393aa3be2af0414 +https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda#bc58fdbced45bb096364de0fba1637af https://conda.anaconda.org/conda-forge/win-64/coverage-7.12.0-py311h3f79411_0.conda#5eb14cad407cb102cc678fcaba4b0ee3 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 @@ -101,10 +101,10 @@ https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-2_ha590de0_openblas.conda#2faff8da7caa95fedbebd4029c815910 https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h3fd045d_3.conda#5e7e380c470e9f4683b3129fedafbcdf -https://conda.anaconda.org/conda-forge/win-64/fonttools-4.60.1-py311h3f79411_0.conda#00f530a3767510908b89b6c0f2698479 +https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.0-py311h3f79411_0.conda#448f4a9f042eec9a840e3a0090e9a6d8 https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda#d69c21967f35eb2ce7f1f85d6b6022d3 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/win-64/pillow-12.0.0-py311hf7ee305_0.conda#c1e7a1806f85aac047cbadd6d4dfae41 +https://conda.anaconda.org/conda-forge/win-64/pillow-12.0.0-py311h17b8079_2.conda#a80f6ec79f4ea2bf7572f4f8e8b467f7 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 https://conda.anaconda.org/conda-forge/win-64/scipy-1.16.3-py311hf127856_1.conda#48d562b3a3fb120d7c3f5e6af6d4b3e9 https://conda.anaconda.org/conda-forge/win-64/blas-2.302-openblas.conda#9a3d6e4359ba0ce36b6dea7b6c32bd94 diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 7aa32a4589b35..c037ab9ddde16 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -12,37 +12,33 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda#3036ca5b895b7f5146c5a25486234a68 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-h85bb3a7_107.conda#84915638a998fae4d495fa038683a73e +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_114.conda#5addcb22be964dc0df75bbd4649fee59 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda#f7b4d76975aac7e5d9e6ad13845f92fe -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h85bb3a7_107.conda#eaf0f047b048c4d86a4b8c60c0e95f38 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_114.conda#c88929e13f56dac9233cdf615502e5f3 https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.6-h4922eb0_0.conda#7a0b9ce502e0ed62195e02891dfcd704 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_8.conda#1bad93f0aa428d618875ef3a588a889e -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-6_kmp_llvm.conda#197811678264cb9da0d2ea0726a70661 -https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-bootstrap_h59bd682_3.conda#5f1f949fc9c875458b5bc02a0c856f18 +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-bootstrap_h8a22499_3.conda#e39cc547941ee90dd512bfbe3d2a02d7 -https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-bootstrap_h8a22499_3.conda#c990e32bb7fce8b93d78b67f5eb26117 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda#c0374badb3a5d4b1372db28d19462c53 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 -https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-h09219d5_0.conda#9b3117ec960b823815b02190b41c0484 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda#280ea6eee9e2ddefde25ff799c4f0363 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda#f116940d825ffc9104400f0d7f1a4551 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda#5b767048b1b3ee9a954b06f4084f93dc +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 @@ -61,16 +57,17 @@ https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.cond https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.4-h3f801dc_0.conda#01ba04e414e47f95c03d6ddd81fd37be -https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hd53d788_0.conda#c183787d2b228775dece45842abbbe53 -https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-h02bd7ab_0.conda#b7a924e3e9ebc7938ffc7d94fe603ed3 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda#8621a450add4e231f676646880703f49 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-hd08acf3_7.conda#716f4c96e07207d74e635c915b8b3f8b +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_14.conda#b1b15da9757caaa0814d7dc3112b3e06 https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda#a587892d3c13b6621a6091be690dbca2 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda#f627678cf829bd70bccf141a19c3ad3e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -84,17 +81,17 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.con https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_3.conda#03b04e4effefa41aee638f8ba30a6e78 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.2.5-hde8ca8f_0.conda#1920c3502e7f6688d650ab81cd3775fd -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d -https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hf2c8021_0.conda#5304333319a6124a2737d9f128cbc4ed +https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.22.0-h4cfbee9_0.conda#bede98a38485d588b3ec7e4ba2e46532 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.22.0-hc31b594_1.conda#52019609422a72ec80c32bbc16a889d8 https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hd9e9e21_7.conda#54876317578ad4bf695aad97ff8398d9 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_5.conda#82954a6f42e3fba59628741dca105c98 @@ -106,61 +103,43 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 -https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-h41a2e66_0.conda#4ddfd44e473c676cb8e80548ba4aa704 -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-hb991d5c_7.conda#39586596e88259bae48f904fb1025b77 +https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_104.conda#a7a67bf132a4a2dea92a7cb498cdc5b1 +https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda#679616eb5ad4e521c83da4650860aba7 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_14.conda#fe0c2ac970a0b10835f3432a3dfd4542 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h7db7018_7.conda#a68add92b710d3139b46f46a27d06c80 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-he663afc_7.conda#2700e7aad63bca8c26c2042a6a7214d6 +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h6395336_2.conda#c09c4ac973f7992ba0c6bb1aafd77bd4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda#729a572a3ebb8c43933b30edcc628ceb https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda#8035e5b54c08429354d5d64027041cad -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h76bdaa0_7.conda#cd5d2db69849f2fc7b592daf86c3015a -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h1e4d427_14.conda#5d81121caf70d8799d90dabbf98e5d3d -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-hc876b51_14.conda#1852de0052b0d6af4294b3ae25a4a450 -https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 -https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda#c7944d55af26b6d2d7629e27e9a972c1 -https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h7c6b74e_0.conda#645bc783bc723d67a294a51bc860762d -https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b +https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-default_h4852527_104.conda#d351e4894d6c4d9d8775bf169a97089d +https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-default_h4852527_104.conda#e30e71d685e23cc1e5ac1c1990ba1f81 +https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2#576d629e47797577ab0f1b351297ef4a https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a -https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh707e725_0.conda#9ba00b39e03a0afb2b1cc0767d4c6175 +https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.2-pyhd8ed1ab_0.conda#fcac5929097ba1f2a0e5b6ecaa13b253 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.14-py311hd8ed1ab_2.conda#43ed151bed1a0eb7181d305fed7cf051 -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.1-py311h0daaf2c_0.conda#1be85c7845e9ba143f3cef9fd5780dc3 +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py311h0daaf2c_0.conda#93f275715239f0ad95343a75fb15dbd7 https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2#961b3a227b437d82ad7054484cfa71b2 https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-he448592_7.conda#94394acdc56dcb4d55dddf0393134966 -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-he448592_7.conda#91dc0abe7274ac5019deaa6100643265 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h442bea5_14.conda#e6b9e795d27f9f524c67ad8803157056 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -170,21 +149,18 @@ https://conda.anaconda.org/conda-forge/noarch/json5-0.12.1-pyhd8ed1ab_0.conda#0f https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-3.0.0-py311h38be061_2.conda#5dd29601defbcc14ac6953d9504a80a7 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b965c999135d43a3d0f7bd7d024e26a -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h7f8ec31_1002.conda#c01021ae525a76fe62720c7346212d74 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_1.conda#638350cf5da41f3651958876a2104992 -https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c -https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 +https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/narwhals-2.12.0-pyhcf101f3_0.conda#02cab382663872083b7e8675f09d9c21 -https://conda.anaconda.org/conda-forge/noarch/networkx-3.5-pyhe01879c_0.conda#16bff3d37a4f99e3aa089c36c2b8d650 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6-pyhcf101f3_0.conda#6725bfdf8ea7a8bf6415f096f3f1ffa5 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311h07c5bb8_0.conda#51f505a537b2d216a1b36b823df80995 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda#5c7a868f8241e64e1cf5fdf4962f23e2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 @@ -203,11 +179,10 @@ https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_0.con https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h2315fbb_0.conda#6c87a0f4566469af3585b11d89163fd7 https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda#5f0f24f8032c2c1bb33f59b75974f5fc -https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.29.0-py311h902ca64_0.conda#9c57ad209dc7af39ada3b571202daf8d +https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda#3893f7b40738f9fe87510cb4468cdda5 https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh0d859eb_1.conda#938c8de6b9de091997145b3bf25cdbf9 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 -https://conda.anaconda.org/conda-forge/noarch/sniffio-1.3.1-pyhd8ed1ab_2.conda#03fe290994c5e4ec17293cfb6bdce520 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda#18c019ccf43769d211f2cf78e9ad46c2 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb @@ -224,27 +199,39 @@ https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.con https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda#2841eb5bfc75ce15e9a0054b98dcd64d https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda#2f1ed718fcd829c184a6d4f0f2e07409 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f -https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhd8ed1ab_0.conda#df5e78d904988eb55042c0c97446079f +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa +https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_0.conda#b1a27250d70881943cca0dd6b4ba0956 https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.60.1-py311h3778330_0.conda#91f834f85ac92978cfc3c1c178573e85 -https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py311h3778330_0.conda#f5ee391df23b7f50676ebe79fc53ee03 +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h6f77f03_14.conda#39ad5dd223e52cd1d52486913aec8539 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_14.conda#fe0c2ac970a0b10835f3432a3dfd4542 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_14.conda#4f780ca1ee70dee1c9acbe1932305cb2 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_14.conda#54ae44a161f3e492c654582c5fc47537 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h7f8ec31_1002.conda#c01021ae525a76fe62720c7346212d74 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb +https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c +https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhd8ed1ab_1.conda#71abbefb6f3b95e1668cd5e0af3affb9 https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda#f5a4d548d1d3bdd517260409fc21e205 @@ -257,76 +244,87 @@ https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.14-hd8ed1ab_2.cond https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda#efba281bbdae5f6b0a1d53c6d4a97c93 https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.5.0-pyhcf101f3_0.conda#2caf483992d5d92b232451f843bdc8af https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/noarch/anyio-4.11.0-pyhcf101f3_0.conda#814472b61da9792fae28156cb9ee54f5 +https://conda.anaconda.org/conda-forge/noarch/anyio-4.12.0-pyhcf101f3_0.conda#9958d4a1ee7e9c768fe8f4fb51bd07ea https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda#6e36e9d2b535c3fbe2e093108df26695 https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda#85c4f19f377424eafc4ed7911b291642 -https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda#749ebebabc2cae99b2e5b3edd04c6ca2 +https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-h5f6438b_0.conda#08a03378bc5293c6f97637323802f480 -https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e +https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/noarch/doit-0.36.0-pyhd8ed1ab_1.conda#18d4243b3d30352f9dea8e522f6ff4d1 https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_14.conda#8b9b800bc6424c356a460f90f2a997ad +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h1e4d427_14.conda#5d81121caf70d8799d90dabbf98e5d3d +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_14.conda#9b11172adc0436dafda8875cd2adee00 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-hc876b51_14.conda#1852de0052b0d6af4294b3ae25a4a450 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda#4ebae00eae9705b0c3d6d1018a81d047 https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_1.conda#2d983ff1b82a1ccb6f2e9d8784bdd6bd https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b +https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 +https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.25.1-pyhe01879c_0.conda#341fd940c242cf33e832c0402face56f -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.6.4-pyhe01879c_0.conda#b1f5663c5ccf466416fb822d11e1aff3 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h5875eb1_mkl.conda#6a1a4ec47263069b2dae3cfba106320c -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.0-pyhcf101f3_0.conda#4797b73e8813dce0afe8c96839118294 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.3-h5c1c036_1.conda#762af6d08fdfa7a45346b1466740bacd https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a +https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.25.1-he01879c_0.conda#13e31c573c884962318a738405ca3487 -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.6.1-pyhe01879c_0.conda#b55913693e8934299585267ce95af06e -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_hfef963f_mkl.conda#62ffd188ee5c953c2d6ac54662c158a7 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h5e43f62_mkl.conda#4f33d79eda3c82c95a54e8c2981adddb +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.0-pyhcf101f3_0.conda#97624651e6fc9ca05effe0b4a80766e3 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h5875eb1_mkl.conda#6a1a4ec47263069b2dae3cfba106320c +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.3-py311he4c1a5a_1.conda#8c769099c0729ff85aac64f566bcd0d7 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.3-h5c1c036_1.conda#762af6d08fdfa7a45346b1466740bacd https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda#f56000b36f09ab7533877e695e4e8cb0 https://conda.anaconda.org/conda-forge/noarch/jupytext-1.18.1-pyh80e38bb_0.conda#3c85f79f1debe2d2c82ac08f1c1126e1 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_hdba1596_mkl.conda#96dea51ff1435bd823020e25fd02da59 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_hfef963f_mkl.conda#62ffd188ee5c953c2d6ac54662c158a7 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h5e43f62_mkl.conda#4f33d79eda3c82c95a54e8c2981adddb https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda#6bb0d77277061742744176ab555b723c -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py311h2e04523_0.conda#01da92ddaf561cabebd06019ae521510 https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_3.conda#d2bbbd293097e664ffb01fc4cdaf5729 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.3-py311he4c1a5a_1.conda#8c769099c0729ff85aac64f566bcd0d7 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_hdba1596_mkl.conda#96dea51ff1435bd823020e25fd02da59 +https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda#cfc86ccc3b1de35d36ccaae4c50391f5 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py311h2e04523_0.conda#01da92ddaf561cabebd06019ae521510 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-2_hcf00494_mkl.conda#77b464e7c3b853268dec4c82b21dca5a https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311hdf67eae_3.conda#c4e2f4d5193e55a70bb67a2aa07006ae -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2025.11.11-py311h99464e2_0.conda#ef3de0e69e6b286b5ff5539c07a5c7d4 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2025.11.11-py311hd2c663a_1.conda#6cbb8004493da9989e6c94c36151e4c3 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 -https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda#cfc86ccc3b1de35d36ccaae4c50391f5 +https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda#d79a87dcfa726bcea8e61275feed6f83 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_1.conda#72e3452bf0ff08132e86de0272f2fbb0 https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.9.0-py311h0372a8f_2.conda#4e078a6bafb23473ea476450f45c9650 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311h1e13796_1.conda#e1947291b713cb0afa949e1bcda1f935 https://conda.anaconda.org/conda-forge/linux-64/blas-2.302-mkl.conda#9c83adee9e1069446e6cc92b8ea19797 -https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda#d79a87dcfa726bcea8e61275feed6f83 +https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.5-py311h0372a8f_1.conda#9db66ee103839915d80e7573b522d084 https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.10.16-pyhd8ed1ab_0.conda#f5b9f02d19761f79c564900a2a399984 -https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.25.2-py311hed34c8f_2.conda#515ec832e4a98828374fded73405e3f3 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.0-pyhd8ed1ab_0.conda#058a1b9b7deca7ab48659088543a8158 +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.0-pyhcf101f3_1.conda#e53b79419913df0b84f7c3af7727122b https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda#5af206d64d18d6c8dfb3122b4d9e643b https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda#837aaf71ddf3b27acae0e7e9015eebc6 https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda#bf22cb9c439572760316ce0748af3713 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index f171bd9b1de94..91086e030f897 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -12,31 +12,27 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-bootstrap_ha15bf96_3.conda#3036ca5b895b7f5146c5a25486234a68 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-h85bb3a7_107.conda#84915638a998fae4d495fa038683a73e +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_114.conda#5addcb22be964dc0df75bbd4649fee59 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda#f7b4d76975aac7e5d9e6ad13845f92fe -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h85bb3a7_107.conda#eaf0f047b048c4d86a4b8c60c0e95f38 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_114.conda#c88929e13f56dac9233cdf615502e5f3 https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.6-h4922eb0_0.conda#7a0b9ce502e0ed62195e02891dfcd704 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_8.conda#1bad93f0aa428d618875ef3a588a889e -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-6_kmp_llvm.conda#197811678264cb9da0d2ea0726a70661 -https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-bootstrap_h59bd682_3.conda#5f1f949fc9c875458b5bc02a0c856f18 +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-bootstrap_h8a22499_3.conda#e39cc547941ee90dd512bfbe3d2a02d7 -https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-bootstrap_h8a22499_3.conda#c990e32bb7fce8b93d78b67f5eb26117 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda#c0374badb3a5d4b1372db28d19462c53 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 -https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-h09219d5_0.conda#9b3117ec960b823815b02190b41c0484 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda#280ea6eee9e2ddefde25ff799c4f0363 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-hcd61629_7.conda#f116940d825ffc9104400f0d7f1a4551 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc @@ -45,7 +41,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda#b64523fb87ac6f87f0790f324ad43046 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda#5b767048b1b3ee9a954b06f4084f93dc +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 @@ -66,18 +62,19 @@ https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.4-h3f801dc_0.conda#01ba04e414e47f95c03d6ddd81fd37be https://conda.anaconda.org/conda-forge/linux-64/libasprintf-0.25.1-h3f43e3d_1.conda#3b0d184bc9404516d418d4509e418bdc -https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hd53d788_0.conda#c183787d2b228775dece45842abbbe53 -https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-h02bd7ab_0.conda#b7a924e3e9ebc7938ffc7d94fe603ed3 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.25.1-h3f43e3d_1.conda#2f4de899028319b27eb7a4023be5dfd2 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_7.conda#8621a450add4e231f676646880703f49 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-hd08acf3_7.conda#716f4c96e07207d74e635c915b8b3f8b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda#f627678cf829bd70bccf141a19c3ad3e +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_14.conda#b1b15da9757caaa0814d7dc3112b3e06 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -93,97 +90,81 @@ https://conda.anaconda.org/conda-forge/linux-64/svt-av1-3.1.2-hecca717_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_3.conda#03b04e4effefa41aee638f8ba30a6e78 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.2.5-hde8ca8f_0.conda#1920c3502e7f6688d650ab81cd3775fd -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda#6432cb5d4ac0046c3ac0a8a0f95842f9 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d -https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hf2c8021_0.conda#5304333319a6124a2737d9f128cbc4ed +https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.22.0-h4cfbee9_0.conda#bede98a38485d588b3ec7e4ba2e46532 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.22.0-hc31b594_1.conda#52019609422a72ec80c32bbc16a889d8 https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hd9e9e21_7.conda#54876317578ad4bf695aad97ff8398d9 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.25.1-h3f43e3d_1.conda#fd9cf4a11d07f0ef3e44fc061611b1ed https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.25.1-h3f43e3d_1.conda#3f7a43b3160ec0345c9535a9f0d7908e -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_7.conda#beeb74a6fe5ff118451cf0581bfe2642 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h6548e54_1.conda#f01292fb36b6d00d5c51e5d46b513bcf https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_5.conda#82954a6f42e3fba59628741dca105c98 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_2.conda#b04e0a2163a72588a40cde1afd6f2d18 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 +https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 -https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-h41a2e66_0.conda#4ddfd44e473c676cb8e80548ba4aa704 -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-hb991d5c_7.conda#39586596e88259bae48f904fb1025b77 +https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_104.conda#a7a67bf132a4a2dea92a7cb498cdc5b1 +https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda#679616eb5ad4e521c83da4650860aba7 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_14.conda#fe0c2ac970a0b10835f3432a3dfd4542 +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/gettext-0.25.1-h3f43e3d_1.conda#c42356557d7f2e37676e121515417e3b -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h7db7018_7.conda#a68add92b710d3139b46f46a27d06c80 https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.2-hf516916_1.conda#495c262933b7c5b8c09413d44fa5974b -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-he663afc_7.conda#2700e7aad63bca8c26c2042a6a7214d6 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h6395336_2.conda#c09c4ac973f7992ba0c6bb1aafd77bd4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.0-hee844dc_0.conda#729a572a3ebb8c43933b30edcc628ceb https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h76bdaa0_7.conda#cd5d2db69849f2fc7b592daf86c3015a -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h1e4d427_14.conda#5d81121caf70d8799d90dabbf98e5d3d -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-hc876b51_14.conda#1852de0052b0d6af4294b3ae25a4a450 -https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda#ee48bf17cc83a00f59ca1494d5646869 -https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f -https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda#def531a3ac77b7fb8c21d17bb5d0badb -https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h7c6b74e_0.conda#645bc783bc723d67a294a51bc860762d -https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b +https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-default_h4852527_104.conda#d351e4894d6c4d9d8775bf169a97089d +https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-default_h4852527_104.conda#e30e71d685e23cc1e5ac1c1990ba1f81 +https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a -https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh707e725_0.conda#9ba00b39e03a0afb2b1cc0767d4c6175 +https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-he448592_7.conda#94394acdc56dcb4d55dddf0393134966 -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-he448592_7.conda#91dc0abe7274ac5019deaa6100643265 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h442bea5_14.conda#e6b9e795d27f9f524c67ad8803157056 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h7f8ec31_1002.conda#c01021ae525a76fe62720c7346212d74 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_1.conda#638350cf5da41f3651958876a2104992 -https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda#ef1910918dd895516a769ed36b5b3a4e -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c +https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda#ee48bf17cc83a00f59ca1494d5646869 +https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311h07c5bb8_0.conda#51f505a537b2d216a1b36b823df80995 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda#5c7a868f8241e64e1cf5fdf4962f23e2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e @@ -201,67 +182,85 @@ https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda#1 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.2-pyhd8ed1ab_0.conda#5d99943f2ae3cc69e1ada12ce9d4d701 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_2.conda#00d80af3a7bf27729484e786a68aafff +https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py311h49ec1c0_2.conda#8d7a63fc9653ed0bdc253a51d9a5c371 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 -https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhd8ed1ab_0.conda#df5e78d904988eb55042c0c97446079f +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa +https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.60.1-py311h3778330_0.conda#91f834f85ac92978cfc3c1c178573e85 -https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py311h3778330_0.conda#f5ee391df23b7f50676ebe79fc53ee03 +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h6f77f03_14.conda#39ad5dd223e52cd1d52486913aec8539 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_14.conda#fe0c2ac970a0b10835f3432a3dfd4542 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_14.conda#4f780ca1ee70dee1c9acbe1932305cb2 https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.2-h5192d8d_1.conda#7071a9745767777b4be235f8c164ea75 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_14.conda#54ae44a161f3e492c654582c5fc47537 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhd8ed1ab_0.conda#446bd6c8cb26050d528881df495ce646 +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h7f8ec31_1002.conda#c01021ae525a76fe62720c7346212d74 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb +https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda#ef1910918dd895516a769ed36b5b3a4e +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhd8ed1ab_1.conda#71abbefb6f3b95e1668cd5e0af3affb9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda#9f6a8664f1fe752f79473eeb9bf33a60 -https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.2-pyha770c72_0.conda#749ebebabc2cae99b2e5b3edd04c6ca2 -https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e +https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e +https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_14.conda#8b9b800bc6424c356a460f90f2a997ad +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h1e4d427_14.conda#5d81121caf70d8799d90dabbf98e5d3d https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_14.conda#9b11172adc0436dafda8875cd2adee00 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-hc876b51_14.conda#1852de0052b0d6af4294b3ae25a4a450 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 +https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 +https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 +https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.11-h651a532_0.conda#d8d8894f8ced2c9be76dc9ad1ae531ce +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.4-pyhd8ed1ab_2.conda#bb0230917e2473c77d615104dbe8a49d -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h5875eb1_mkl.conda#6a1a4ec47263069b2dae3cfba106320c -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_hfef963f_mkl.conda#62ffd188ee5c953c2d6ac54662c158a7 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h5e43f62_mkl.conda#4f33d79eda3c82c95a54e8c2981adddb +https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h5875eb1_mkl.conda#6a1a4ec47263069b2dae3cfba106320c +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h3c3fd16_6.conda#5aab84b9d164509b5bbe3af660518606 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_hdba1596_mkl.conda#96dea51ff1435bd823020e25fd02da59 -https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_hfef963f_mkl.conda#62ffd188ee5c953c2d6ac54662c158a7 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h5e43f62_mkl.conda#4f33d79eda3c82c95a54e8c2981adddb https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_hdba1596_mkl.conda#96dea51ff1435bd823020e25fd02da59 +https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-2_hcf00494_mkl.conda#77b464e7c3b853268dec4c82b21dca5a https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2025.11.11-py311h99464e2_0.conda#ef3de0e69e6b286b5ff5539c07a5c7d4 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2025.11.11-py311hd2c663a_1.conda#6cbb8004493da9989e6c94c36151e4c3 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.conda#643f8cb35133eb1be4919fb953f0a25f https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index dda4f7d48cf80..e67cb05aa98df 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.conda#9e115653741810778c9a915a2f8439e7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-he277a41_7.conda#34cef4753287c36441f907d5fdd78d42 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_14.conda#f08c95adda42a8f04c2ce888a36be575 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-2_gnu.tar.bz2#6168d71addc746e8f2b8d57dfd2edcea @@ -16,22 +16,22 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda#cf105bce884e4ef8c8ccdca9fe6695e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-he277a41_7.conda#afa05d91f8d57dd30985827a09c21464 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_14.conda#43ff19fcf6f6737770018bb20bb2a9f9 https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.14-h86ecc28_0.conda#a696b24c1b473ecc4774bcb5a6ac6337 https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_8.conda#2921ac0b541bf37c69e66bd6d9a43bca https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda#e7df0aab10b9cbb73ab2a467ebfaf8c7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-hd4db518_0.conda#ede431bf5eb917815cd62dc3bf2703a4 +https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d5cf_1.conda#8ec1d03f3000108899d1799d9964f281 https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda#a9138815598fe6b91a1d6782ca657b0c https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.3-hfae3067_0.conda#b414e36fbb7ca122030276c75fa9c34a https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-hd65408f_0.conda#0c5ad486dcfb188885e3cf8ba209b97b -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_7.conda#a5ce1f0a32f02c75c11580c5b2f9258a -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h87db57e_7.conda#dd7233e2874ea59e92f7d24d26bb341b +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_14.conda#acd92c808b9f95f5b28db20054306ba7 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_14.conda#a35c50126e425ee8b5bb3e504ed23b8a https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda#5a86bf847b9b926f3a4f203339748d78 https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda#5109d7f837a3dfdf5c60f60e311b041f https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.1-h86ecc28_2.conda#7d362346a479256857ab338588190da0 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-h3f4de04_7.conda#6a2f0ee17851251a85fbebafbe707d2d +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_14.conda#83f466be64f6bc1f7ece406c009e0586 https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.2-h3e4203c_0.conda#3a68e44fdf2a2811672520fdd62996bd https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda#08aad7cbe9f5a6b460d0976076b6ae64 @@ -44,15 +44,15 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5c https://conda.anaconda.org/conda-forge/linux-aarch64/double-conversion-3.3.1-h5ad3122_0.conda#399959d889e1a73fc99f12ce480e77e1 https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda#4aa540e9541cc9d6581ab23ff2043f13 https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.0.0-hfdc4d58_1.conda#60dceb7e876f4d74a9cbd42bbbc6b9cf -https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-hb159aeb_0.conda#05d5e1d976c0b5cb0885a654a368ee8a -https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-ha5a240b_0.conda#09ea194ce9f89f7664a8a6d8baa63d88 +https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf_1.conda#47e5b71b77bb8b47b4ecf9659492977f +https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda#6553a5d017fe14859ea8a4e6ea5def8f https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda#2079727b538f6dd16f3fa579d4c3c53f https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda#fb640d776fc92b682a14e001980825b1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_7.conda#ffe6ad135bd85bb594a6da1d78768f7c +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_14.conda#5425a01b852c315ddabc0a3dde6bba0c https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.51-h1abf092_0.conda#913b1a53ee5f71ce323a15593597be0b -https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.0-h022381a_0.conda#8920ce2226463a3815e2183c8b5008b8 -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hf1166c9_7.conda#9e5deec886ad32f3c6791b3b75c78681 +https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.1-h022381a_0.conda#233efdd411317d2dc5fde72464b3df7a +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_14.conda#410b06d8a2f7dd0cc1b6acdfbcf101c6 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda#b4df5d7d4b63579d081fd3a4cf99740e https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda#8b5222a41b5d51fb1a5a2c514e770218 @@ -62,14 +62,14 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.2-h8382b9d_2.con https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h561c983_103.conda#631db4799bc2bfe4daccf80bb3cbc433 https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.24.0-h4f8a99f_1.conda#f6966cb1f000c230359ae98c29e37d87 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda#2d1409c50882819cb1af2de82e2b7208 -https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.2.5-h92288e7_0.conda#ffbcf78fd47999748154300e9f2a6f39 -https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-hbcf94c1_2.conda#5be90c5a3e4b43c53e38f50a85e11527 -https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-hf3d421d_0.conda#c43264ebd8b93281d09d3a9ad145f753 +https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.1-h92288e7_0.conda#56f8acceedc8c4de5f7a6e1418e74eee +https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-hefd9da6_4.conda#68a63e1ba896c15344e33eacb11e1311 +https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 https://conda.anaconda.org/conda-forge/linux-aarch64/icu-75.1-hf9b3779_0.conda#268203e8b983fddb6412b36f2024e75c https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.21.3-h50a48e9_0.conda#29c10432a2ca1472b53f299ffb2ffa37 -https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45-default_1234567_3.conda#cafa05c86759c42f9eb1e8398b41a1a3 +https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45-default_h1979696_104.conda#28035705fe0c977ea33963489cd008ad https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.1-hdae7a39_0.conda#9c2f56b6e011c6d8010ff43b796aab2f -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-ng-15.2.0-he9431aa_7.conda#e810efad68f395154237c4dce83aa482 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-ng-15.2.0-he9431aa_14.conda#640d27c96b59e2af7d440728cbb9e437 https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.2-he84ff74_0.conda#d184d68eaa57125062786e10440ff461 https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d @@ -79,9 +79,9 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-keysyms-0.4.1-h5c7 https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-renderutil-0.3.10-h5c728e9_0.conda#7beeda4223c5484ef72d89fb66b7e8c1 https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-wm-0.4.2-h5c728e9_0.conda#f14dcda6894722e421da2b7dcffb0b78 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.12-hca56bd8_0.conda#3df132f0048b9639bc091ef22937c111 -https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-hec30622_0.conda#5005bf1c06def246408b73d65f0d3de9 +https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-hd651790_1.conda#5c933384d588a06cd8dac78ca2864aab https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.28-h6c5dea3_0.conda#b6d06b46e791add99cc39fbbc34530d5 -https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-heda779d_0.conda#9203b74bb1f3fa0d6f308094b3b44c1e +https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda#a4b6b82427d15f0489cef0df2d82f926 https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.17-hc88f144_0.conda#b87b1abd2542cf65a00ad2e2461a3083 https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-2_haddc8a3_openblas.conda#1a4b8fba71eb980ac7fb0f2ab86f295d https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h5cdc715_5.conda#ac0333d338076ef19170938bbaf97582 @@ -99,8 +99,8 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda#ae2c2dd0e2d38d249887727db2af960e https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.11.3-h4889ad1_0.conda#e0b9e519da2bf0fb8c48381daf87a194 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_1.conda#44600c4667a319d67dbe0681fc0bc833 -https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.1-py311hdc11669_0.conda#4e9072696f84a95df4aa562e2732d332 +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.2-py311hdc11669_0.conda#324e329aea785abb32429a383f1f151d https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.1-h8af1aa0_0.conda#0c8f36ebd3678eed1685f0fc93fc2175 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 @@ -113,14 +113,14 @@ https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h30c48ee_0.conda#48f31a61be512ec1929f4b4a9cedf4bd https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.0.0-py311h9a6517a_0.conda#2dcc43f9f47cb65f1ebcbdc96183f6d2 +https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.0.0-py311h8e17b9e_2.conda#b86d6e26631d730f43732ade7e510a3f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_2.conda#00d80af3a7bf27729484e786a68aafff +https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.2-py311hb9158a3_2.conda#6d68a78b162d9823e5abe63001c6df36 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d @@ -136,11 +136,11 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.6-h86ec https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.12.0-py311h2dad8b0_0.conda#ddb3e5a915ecebd167f576268083c50b https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.15.0-h8dda3cd_1.conda#112b71b6af28b47c624bcbeefeea685b -https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.60.1-py311h164a683_0.conda#e15201d7a1ed08ce5b85beca0d4a0131 +https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.0-py311h164a683_0.conda#3c533754d7ceb31f50f1f9bea8f2cb8f https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-2_hb558247_openblas.conda#498aa2a8940c8c26c141dd4ce99e7843 https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm21-21.1.6-hfd2ba90_0.conda#54e87a913eeaa2b27f2e7b491860f612 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.1-haf03d9f_1.conda#11a55df5dc2234fcd4135e73fb5737d7 +https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.1-haf03d9f_2.conda#8b0d66c4db91b3ef64daad7f61a569d0 https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.328.1-h8b8848b_0.conda#e5a3ff3a266b68398bd28ed1d4363e65 https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.0-h3c6a4c8_0.conda#a7c78be36bf59b4ba44ad2f2f8b92b37 https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 From ee50be64413b531445d7ff3aa45bc6b92451ce49 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Tue, 2 Dec 2025 14:52:41 +0100 Subject: [PATCH 025/462] FIX screening in enet_coordinate_descent_multi_task (#32811) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- sklearn/linear_model/_cd_fast.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/linear_model/_cd_fast.pyx b/sklearn/linear_model/_cd_fast.pyx index 578d7f7fe2338..c227100ec066e 100644 --- a/sklearn/linear_model/_cd_fast.pyx +++ b/sklearn/linear_model/_cd_fast.pyx @@ -1434,7 +1434,7 @@ def enet_coordinate_descent_multi_task( if do_screening: n_active = 0 for j in range(n_features): - if norm2_cols_X[j] == 0: + if excluded_set[j]: continue # Xj_theta = ||X[:,j] @ dual_theta||_2 Xj_theta = XtA_row_norms[j] / fmax(l1_reg, dual_norm_XtA) From 90ea990d03caed8a76a4b5265f78b066fc91729c Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Tue, 2 Dec 2025 15:36:26 +0100 Subject: [PATCH 026/462] TST Enable pytest faulthandler functionality (#32776) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- azure-pipelines.yml | 1 - pyproject.toml | 6 ++++++ sklearn/conftest.py | 6 ------ 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 74f2f7ea5ef82..95d0d104036af 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -89,7 +89,6 @@ jobs: COVERAGE: 'false' # Disable pytest-xdist to use multiple cores for stress-testing with pytest-run-parallel PYTEST_XDIST_VERSION: 'none' - SKLEARN_FAULTHANDLER_TIMEOUT: '1800' # 30 * 60 seconds # Will run all the time regardless of linting outcome. - template: build_tools/azure/posix.yml diff --git a/pyproject.toml b/pyproject.toml index f5259bb277b48..e21d5824e8f4e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -115,6 +115,12 @@ thread_unsafe_fixtures = [ "tmp_path", # does not isolate temporary directories across threads "pyplot", # some tests might mutate some shared state of pyplot. ] +# 10 min timeout per test: in case of timeout, dump the tracebacks of all +# threads and terminate the whole test session if a test hangs for more than 10 +# min (likely due to a deadlock). +# The second option requires pytest 9.0+ to be active. +faulthandler_timeout = 600 +faulthandler_exit_on_timeout = true [tool.ruff] diff --git a/sklearn/conftest.py b/sklearn/conftest.py index 5699392ba2505..0d7cd01b60258 100644 --- a/sklearn/conftest.py +++ b/sklearn/conftest.py @@ -2,7 +2,6 @@ # SPDX-License-Identifier: BSD-3-Clause import builtins -import faulthandler import platform import sys from contextlib import suppress @@ -346,11 +345,6 @@ def pytest_configure(config): for line in get_pytest_filterwarning_lines(): config.addinivalue_line("filterwarnings", line) - faulthandler_timeout = int(environ.get("SKLEARN_FAULTHANDLER_TIMEOUT", "0")) - if faulthandler_timeout > 0: - faulthandler.enable() - faulthandler.dump_traceback_later(faulthandler_timeout, exit=True) - if not PARALLEL_RUN_AVAILABLE: config.addinivalue_line( "markers", From 473fef0bf83882efbc3273c2dfb4d82491e9066b Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Wed, 3 Dec 2025 02:14:53 +1100 Subject: [PATCH 027/462] DOC Update Contributing intro and Ways to contribute (#32792) --- doc/developers/contributing.rst | 106 +++++++++++++++++--------------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/doc/developers/contributing.rst b/doc/developers/contributing.rst index f722b035618d8..7e79b6bc19d33 100644 --- a/doc/developers/contributing.rst +++ b/doc/developers/contributing.rst @@ -24,15 +24,16 @@ Contributing .. currentmodule:: sklearn -This project is a community effort, and everyone is welcome to -contribute. It is hosted on https://github.com/scikit-learn/scikit-learn. +This project is a community effort, shaped by a large number of contributors from +across the world. For more information on the history and people behind scikit-learn +see :ref:`about`. It is hosted on https://github.com/scikit-learn/scikit-learn. The decision making process and governance structure of scikit-learn is laid out in :ref:`governance`. Scikit-learn is :ref:`selective ` when it comes to adding new algorithms and features. This means the best way to contribute and help the project is to start working on known issues. -See :ref:`new_contributors` to get started. +See :ref:`ways_to_contribute` to learn how to make meaningful contributions. .. topic:: **Our community, our values** @@ -54,49 +55,33 @@ See :ref:`new_contributors` to get started. Communications on all channels should respect our `Code of Conduct `_. - - -In case you experience issues using this package, do not hesitate to submit a -ticket to the -`GitHub issue tracker -`_. You are also -welcome to post feature requests or pull requests. - .. _ways_to_contribute: Ways to contribute ================== -There are many ways to contribute to scikit-learn. Improving the -documentation is no less important than improving the code of the library -itself. If you find a typo in the documentation, or have made improvements, do -not hesitate to create a GitHub issue or preferably submit a GitHub pull request. - -There are many ways to help. In particular helping to -:ref:`improve, triage, and investigate issues ` and -:ref:`reviewing other developers' pull requests ` are very -valuable contributions that move the project forward. - -Another way to contribute is to report issues you are facing, and give a "thumbs -up" on issues that others reported and that are relevant to you. It also helps -us if you spread the word: reference the project from your blog and articles, -link to it from your website, or simply star to say "I use it": - -.. raw:: html - -

- - -

- -In case a contribution/issue involves changes to the API principles -or changes to dependencies or supported versions, it must be backed by a -:ref:`slep`, where a SLEP must be submitted as a pull-request to -`enhancement proposals `_ -using the `SLEP template `_ -and follows the decision-making process outlined in :ref:`governance`. +There are many ways to contribute to scikit-learn. These include: + +* referencing scikit-learn from your blog and articles, linking to it from your website, + or simply + `staring it `__ + to say "I use it"; this helps us promote the project +* :ref:`improving and investigating issues ` +* :ref:`reviewing other developers' pull requests ` +* reporting difficulties when using this package by submitting an + `issue `__, and giving a + "thumbs up" on issues that others reported and that are relevant to you (see + :ref:`submitting_bug_feature` for details) +* improving the :ref:`contribute_documentation` +* making a code contribution + +There are many ways to contribute without writing code, and we value these +contributions just as highly as code contributions. If you are interested in making +a code contribution, please keep in mind that scikit-learn has evolved into a mature +and complex project since its inception in 2007. Contributing to the project code +generally requires advanced skills, and it may not be the best place to begin if you +are new to open source contribution. In this case we suggest you follow the suggestions +in :ref:`new_contributors`. .. dropdown:: Contributing to related projects @@ -125,16 +110,32 @@ New Contributors ---------------- We recommend new contributors start by reading this contributing guide, in -particular :ref:`ways_to_contribute`, :ref:`automated_contributions_policy` -and :ref:`pr_checklist`. For expected etiquette around which issues and stalled PRs +particular :ref:`ways_to_contribute`, :ref:`automated_contributions_policy`. + +Next, we advise new contributors gain foundational knowledge on +scikit-learn and open source by: + +* :ref:`improving and investigating issues ` + + * confirming that a problem reported can be reproduced and providing a + :ref:`minimal reproducible code ` (if missing), can help you + learn about different use cases and user needs + * investigating the root cause of an issue will aid you in familiarising yourself + with the scikit-learn codebase + +* :ref:`reviewing other developers' pull requests ` will help you + develop an understanding of the requirements and quality expected of contributions +* improving the :ref:`contribute_documentation` can help deepen your knowledge + of the statistical concepts behind models and functions, and scikit-learn API + +If you wish to make code contributions after building your foundational knowledge, we +recommend you start by looking for an issue that is of interest to you, in an area you +are already familiar with as a user or have background knowledge of. We recommend +starting with smaller pull requests and following our :ref:`pr_checklist`. +For expected etiquette around which issues and stalled PRs to work on, please read :ref:`stalled_pull_request`, :ref:`stalled_unclaimed_issues` and :ref:`issues_tagged_needs_triage`. -We understand that everyone has different interests and backgrounds, thus we recommend -you start by looking for an issue that is of interest to you, in an area you are -already familiar with as a user or have background knowledge of. We recommend starting -with smaller pull requests, to get used to the contribution process. - We rarely use the "good first issue" label because it is difficult to make assumptions about new contributors and these issues often prove more complex than originally anticipated. It is still useful to check if there are @@ -173,6 +174,8 @@ If you used AI tools, please state so in your PR description. PRs that appear to violate this policy will be closed without review. +.. _submitting_bug_feature: + Submitting a bug report or a feature request ============================================ @@ -199,6 +202,13 @@ following rules before submitting: - If you are submitting a bug report, we strongly encourage you to follow the guidelines in :ref:`filing_bugs`. +When a feature request involves changes to the API principles +or changes to dependencies or supported versions, it must be backed by a +:ref:`SLEP `, which must be submitted as a pull-request to +`enhancement proposals `_ +using the `SLEP template `_ +and follows the decision-making process outlined in :ref:`governance`. + .. _filing_bugs: How to make a good bug report From 41ceebb66a353f900f26ac0152b1b0ecaaa563c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Thu, 4 Dec 2025 05:39:03 +0100 Subject: [PATCH 028/462] CI Make linting bot comment only on failure (#32804) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- .github/workflows/bot-lint-comment.yml | 2 +- build_tools/get_comment.py | 229 ++++++++++--------------- 2 files changed, 91 insertions(+), 140 deletions(-) diff --git a/.github/workflows/bot-lint-comment.yml b/.github/workflows/bot-lint-comment.yml index 36c29ad3e0b84..8832d583ca7d2 100644 --- a/.github/workflows/bot-lint-comment.yml +++ b/.github/workflows/bot-lint-comment.yml @@ -58,7 +58,7 @@ jobs: python-version: 3.11 - name: Install dependencies - run: python -m pip install requests + run: python -m pip install PyGithub - name: Create/update GitHub comment env: diff --git a/build_tools/get_comment.py b/build_tools/get_comment.py index 2c25ae9da8605..1725865e6dba5 100644 --- a/build_tools/get_comment.py +++ b/build_tools/get_comment.py @@ -1,11 +1,10 @@ # This script is used to generate a comment for a PR when linting issues are # detected. It is used by the `Comment on failed linting` GitHub Action. -# This script fails if there are not comments to be posted. import os import re -import requests +from github import Auth, Github, GithubException def get_versions(versions_file): @@ -67,15 +66,15 @@ def get_step_message(log, start, end, title, message, details): return res -def get_message(log_file, repo, pr_number, sha, run_id, details, versions): +def get_message(log_file, repo_str, pr_number, sha, run_id, details, versions): with open(log_file, "r") as f: log = f.read() sub_text = ( "\n\n _Generated for commit:" - f" [{sha[:7]}](https://github.com/{repo}/pull/{pr_number}/commits/{sha}). " + f" [{sha[:7]}](https://github.com/{repo_str}/pull/{pr_number}/commits/{sha}). " "Link to the linter CI: [here]" - f"(https://github.com/{repo}/actions/runs/{run_id})_ " + f"(https://github.com/{repo_str}/actions/runs/{run_id})_ " ) if "### Linting completed ###" not in log: @@ -189,12 +188,8 @@ def get_message(log_file, repo, pr_number, sha, run_id, details, versions): ) if not message: - # no issues detected, so this script "fails" - return ( - "## ✔️ Linting Passed\n" - "All linting checks passed. Your pull request is in excellent shape! ☀️" - + sub_text - ) + # no issues detected, the linting succeeded + return None if not details: # This happens if posting the log fails, which happens if the log is too @@ -216,7 +211,7 @@ def get_message(log_file, repo, pr_number, sha, run_id, details, versions): + "https://scikit-learn.org/dev/developers/development_setup.html#set-up-pre-commit)" + ".\n\n" + "You can see the details of the linting issues under the `lint` job [here]" - + f"(https://github.com/{repo}/actions/runs/{run_id})\n\n" + + f"(https://github.com/{repo_str}/actions/runs/{run_id})\n\n" + message + sub_text ) @@ -224,96 +219,50 @@ def get_message(log_file, repo, pr_number, sha, run_id, details, versions): return message -def get_headers(token): - """Get the headers for the GitHub API.""" - return { - "Accept": "application/vnd.github+json", - "Authorization": f"Bearer {token}", - "X-GitHub-Api-Version": "2022-11-28", - } - - -def find_lint_bot_comments(repo, token, pr_number): +def find_lint_bot_comments(issue): """Get the comment from the linting bot.""" - # repo is in the form of "org/repo" - # API doc: https://docs.github.com/en/rest/issues/comments?apiVersion=2022-11-28#list-issue-comments - response = requests.get( - f"https://api.github.com/repos/{repo}/issues/{pr_number}/comments", - headers=get_headers(token), - ) - response.raise_for_status() - all_comments = response.json() failed_comment = "❌ Linting issues" - success_comment = "✔️ Linting Passed" - - # Find all comments that match the linting bot, and return the first one. - # There should always be only one such comment, or none, if the PR is - # just created. - comments = [ - comment - for comment in all_comments - if comment["user"]["login"] == "github-actions[bot]" - and (failed_comment in comment["body"] or success_comment in comment["body"]) - ] - - if len(all_comments) > 25 and not comments: - # By default the API returns the first 30 comments. If we can't find the - # comment created by the bot in those, then we raise and we skip creating - # a comment in the first place. - raise RuntimeError("Comment not found in the first 30 comments.") - - return comments[0] if comments else None - - -def create_or_update_comment(comment, message, repo, pr_number, token): - """Create a new comment or update existing one.""" - # repo is in the form of "org/repo" + + for comment in issue.get_comments(): + if comment.user.login == "github-actions[bot]": + if failed_comment in comment.body: + return comment + + return None + + +def create_or_update_comment(comment, message, issue): + """Create a new comment or update the existing linting comment.""" + if comment is not None: - print("updating existing comment") - # API doc: https://docs.github.com/en/rest/issues/comments?apiVersion=2022-11-28#update-an-issue-comment - response = requests.patch( - f"https://api.github.com/repos/{repo}/issues/comments/{comment['id']}", - headers=get_headers(token), - json={"body": message}, - ) + print("Updating existing comment") + comment.edit(message) else: - print("creating new comment") - # API doc: https://docs.github.com/en/rest/issues/comments?apiVersion=2022-11-28#create-an-issue-comment - response = requests.post( - f"https://api.github.com/repos/{repo}/issues/{pr_number}/comments", - headers=get_headers(token), - json={"body": message}, - ) + print("Creating new comment") + issue.create_comment(message) - response.raise_for_status() +def update_linter_fails_label(linting_failed, issue): + """Add or remove the label indicating that the linting has failed.""" -def update_linter_fails_label(message, repo, pr_number, token): - """ "Add or remove the label indicating that the linting has failed.""" + label = "CI:Linter failure" + + if linting_failed: + issue.add_to_labels(label) - if "❌ Linting issues" in message: - # API doc: https://docs.github.com/en/rest/issues/labels?apiVersion=2022-11-28#add-labels-to-an-issue - response = requests.post( - f"https://api.github.com/repos/{repo}/issues/{pr_number}/labels", - headers=get_headers(token), - json={"labels": ["CI:Linter failure"]}, - ) - response.raise_for_status() else: - # API doc: https://docs.github.com/en/rest/issues/labels?apiVersion=2022-11-28#remove-a-label-from-an-issue - response = requests.delete( - f"https://api.github.com/repos/{repo}/issues/{pr_number}/labels/CI:Linter" - " failure", - headers=get_headers(token), - ) - # If the label was not set, trying to remove it returns a 404 error - if response.status_code != 404: - response.raise_for_status() + try: + issue.remove_from_labels(label) + except GithubException as exception: + # The exception is ignored if raised because the issue did not have the + # label already + if not exception.message == "Label does not exist": + raise if __name__ == "__main__": - repo = os.environ["GITHUB_REPOSITORY"] + repo_str = os.environ["GITHUB_REPOSITORY"] token = os.environ["GITHUB_TOKEN"] pr_number = os.environ["PR_NUMBER"] sha = os.environ["BRANCH_SHA"] @@ -323,58 +272,60 @@ def update_linter_fails_label(message, repo, pr_number, token): versions = get_versions(versions_file) - if not repo or not token or not pr_number or not log_file or not run_id: - raise ValueError( - "One of the following environment variables is not set: " - "GITHUB_REPOSITORY, GITHUB_TOKEN, PR_NUMBER, LOG_FILE, RUN_ID" - ) + for var, val in [ + ("GITHUB_REPOSITORY", repo_str), + ("GITHUB_TOKEN", token), + ("PR_NUMBER", pr_number), + ("LOG_FILE", log_file), + ("RUN_ID", run_id), + ]: + if not val: + raise ValueError(f"The following environment variable is not set: {var}") if not re.match(r"\d+$", pr_number): raise ValueError(f"PR_NUMBER should be a number, got {pr_number!r} instead") + pr_number = int(pr_number) + + gh = Github(auth=Auth.Token(token)) + repo = gh.get_repo(repo_str) + issue = repo.get_issue(number=pr_number) + + message = get_message( + log_file, + repo_str=repo_str, + pr_number=pr_number, + sha=sha, + run_id=run_id, + details=True, + versions=versions, + ) - try: - comment = find_lint_bot_comments(repo, token, pr_number) - except RuntimeError: - print("Comment not found in the first 30 comments. Skipping!") - exit(0) - - try: - message = get_message( - log_file, - repo=repo, - pr_number=pr_number, - sha=sha, - run_id=run_id, - details=True, - versions=versions, - ) - create_or_update_comment( - comment=comment, - message=message, - repo=repo, - pr_number=pr_number, - token=token, - ) - print(message) - except requests.HTTPError: - # The above fails if the message is too long. In that case, we - # try again without the details. - message = get_message( - log_file, - repo=repo, - pr_number=pr_number, - sha=sha, - run_id=run_id, - details=False, - versions=versions, - ) - create_or_update_comment( - comment=comment, - message=message, - repo=repo, - pr_number=pr_number, - token=token, - ) - print(message) + update_linter_fails_label( + linting_failed=message is not None, + issue=issue, + ) + + comment = find_lint_bot_comments(issue) - update_linter_fails_label(message, repo, pr_number, token) + if message is None: # linting succeeded + if comment is not None: + print("Deleting existing comment.") + comment.delete() + else: + try: + create_or_update_comment(comment, message, issue) + print(message) + except GithubException: + # The above fails if the message is too long. In that case, we + # try again without the details. + message = get_message( + log_file, + repo=repo, + pr_number=pr_number, + sha=sha, + run_id=run_id, + details=False, + versions=versions, + ) + create_or_update_comment(comment, message, issue) + print(message) From 4a10d0ed8d85e6ed24a647bd28a65c0c64b101ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Thu, 4 Dec 2025 07:34:27 +0100 Subject: [PATCH 029/462] DOC Add HTML repr related PR to existing changelog (#32831) --- .../upcoming_changes/sklearn.utils/31564.enhancement.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst index 6b9ef89fdd01f..d0082d8335eac 100644 --- a/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst +++ b/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst @@ -2,4 +2,4 @@ more generally of estimators inheriting from :class:`base.BaseEstimator` now displays the parameter description as a tooltip and has a link to the online documentation for each parameter. - By :user:`Dea María Léon `. + By :user:`Dea María Léon `. :pr:`30763` and From 5b9561dfcef6f0b089f3a09251c05333692fbf74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Thu, 4 Dec 2025 12:01:20 +0100 Subject: [PATCH 030/462] MNT Use Pyodide 0.29 version to avoid micropip error inside JupyterLite (#32835) --- doc/jupyter-lite.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/jupyter-lite.json b/doc/jupyter-lite.json index 9ad29615decb6..63a4ad485b310 100644 --- a/doc/jupyter-lite.json +++ b/doc/jupyter-lite.json @@ -3,7 +3,7 @@ "jupyter-config-data": { "litePluginSettings": { "@jupyterlite/pyodide-kernel-extension:kernel": { - "pyodideUrl": "https://cdn.jsdelivr.net/pyodide/v0.27.2/full/pyodide.js" + "pyodideUrl": "https://cdn.jsdelivr.net/pyodide/v0.29.0/full/pyodide.js" } } } From 3300836d26c8e49ce0c2092878c53ad105aa8b53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= Date: Fri, 5 Dec 2025 06:04:31 +0100 Subject: [PATCH 031/462] DOC Remove PR from changelog that was already in 1.7 (#32841) --- .../upcoming_changes/sklearn.utils/31564.enhancement.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst index d0082d8335eac..6b9ef89fdd01f 100644 --- a/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst +++ b/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst @@ -2,4 +2,4 @@ more generally of estimators inheriting from :class:`base.BaseEstimator` now displays the parameter description as a tooltip and has a link to the online documentation for each parameter. - By :user:`Dea María Léon `. :pr:`30763` and + By :user:`Dea María Léon `. From ec4f93c3f027f8a8e97588d7e49d295c9ac7a202 Mon Sep 17 00:00:00 2001 From: antoinebaker Date: Fri, 5 Dec 2025 11:30:43 +0100 Subject: [PATCH 032/462] FIX Add new default max_samples=None in Bagging estimators (#32825) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Arthur Lacote Co-authored-by: Olivier Grisel Co-authored-by: Loïc Estève --- .../sklearn.ensemble/31414.fix.rst | 7 -- .../sklearn.ensemble/32825.fix.rst | 8 ++ sklearn/ensemble/_bagging.py | 96 ++++++++++++++----- sklearn/ensemble/tests/test_bagging.py | 64 +++++++++++-- 4 files changed, 139 insertions(+), 36 deletions(-) delete mode 100644 doc/whats_new/upcoming_changes/sklearn.ensemble/31414.fix.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.ensemble/32825.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.ensemble/31414.fix.rst b/doc/whats_new/upcoming_changes/sklearn.ensemble/31414.fix.rst deleted file mode 100644 index 17c2f765d4b7c..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.ensemble/31414.fix.rst +++ /dev/null @@ -1,7 +0,0 @@ -- :class:`ensemble.BaggingClassifier`, :class:`ensemble.BaggingRegressor` - and :class:`ensemble.IsolationForest` now use `sample_weight` to draw - the samples instead of forwarding them multiplied by a uniformly sampled - mask to the underlying estimators. Furthermore, `max_samples` is now - interpreted as a fraction of `sample_weight.sum()` instead of `X.shape[0]` - when passed as a float. - By :user:`Antoine Baker `. diff --git a/doc/whats_new/upcoming_changes/sklearn.ensemble/32825.fix.rst b/doc/whats_new/upcoming_changes/sklearn.ensemble/32825.fix.rst new file mode 100644 index 0000000000000..604ec9421a424 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.ensemble/32825.fix.rst @@ -0,0 +1,8 @@ +- :class:`ensemble.BaggingClassifier`, :class:`ensemble.BaggingRegressor` and + :class:`ensemble.IsolationForest` now use `sample_weight` to draw the samples + instead of forwarding them multiplied by a uniformly sampled mask to the + underlying estimators. Furthermore, when `max_samples` is a float, it is now + interpreted as a fraction of `sample_weight.sum()` instead of `X.shape[0]`. + The new default `max_samples=None` draws `X.shape[0]` samples, irrespective + of `sample_weight`. + By :user:`Antoine Baker `. :pr:`31414` and diff --git a/sklearn/ensemble/_bagging.py b/sklearn/ensemble/_bagging.py index 067bdb9e7db0e..a3d0b2bc931c7 100644 --- a/sklearn/ensemble/_bagging.py +++ b/sklearn/ensemble/_bagging.py @@ -46,6 +46,63 @@ MAX_INT = np.iinfo(np.int32).max +def _get_n_samples_bootstrap(n_samples, max_samples, sample_weight): + """ + Get the number of samples in a bootstrap sample. + + Parameters + ---------- + n_samples : int + Number of samples in the dataset. + + max_samples : None, int or float + The maximum number of samples to draw. + + - If None, then draw `n_samples` samples. + - If int, then draw `max_samples` samples. + - If float, then draw `max_samples * n_samples` unweighted samples or + `max_samples * sample_weight.sum()` weighted samples. + + sample_weight : array of shape (n_samples,) or None + Sample weights with frequency semantics when `max_samples` is explicitly + set to a float or integer value. When keeping the `max_samples=None` default + value, the equivalence between fitting with integer weighted data points or + integer repeated data points is no longer guaranteed because the effective + bootstrap size is no longer guaranteed to be equivalent. + + Returns + ------- + n_samples_bootstrap : int + The total number of samples to draw for the bootstrap sample. + """ + if max_samples is None: + return n_samples + elif isinstance(max_samples, Integral): + return max_samples + + if sample_weight is None: + weighted_n_samples = n_samples + weighted_n_samples_msg = f"the number of samples is {weighted_n_samples} " + else: + weighted_n_samples = sample_weight.sum() + weighted_n_samples_msg = ( + f"the total sum of sample weights is {weighted_n_samples} " + ) + + # max_samples Real fractional value relative to weighted_n_samples + n_samples_bootstrap = max(int(max_samples * weighted_n_samples), 1) + # Warn when number of bootstrap samples is suspiciously small + # This heuristic for "suspiciously small" might be adapted if found + # unsuitable in practice + if n_samples_bootstrap < max(10, n_samples ** (1 / 3)): + warn( + f"Using the fractional value {max_samples=} when {weighted_n_samples_msg}" + f"results in a low number ({n_samples_bootstrap}) of bootstrap samples. " + "We recommend passing `max_samples` as an integer instead." + ) + return n_samples_bootstrap + + def _generate_indices(random_state, bootstrap, n_population, n_samples): """Draw randomly sampled indices.""" # Draw sample indices @@ -273,6 +330,7 @@ class BaseBagging(BaseEnsemble, metaclass=ABCMeta): "estimator": [HasMethods(["fit", "predict"]), None], "n_estimators": [Interval(Integral, 1, None, closed="left")], "max_samples": [ + None, Interval(Integral, 1, None, closed="left"), Interval(RealNotInt, 0, 1, closed="right"), ], @@ -295,7 +353,7 @@ def __init__( estimator=None, n_estimators=10, *, - max_samples=1.0, + max_samples=None, max_features=1.0, bootstrap=True, bootstrap_features=False, @@ -340,7 +398,9 @@ def fit(self, X, y, sample_weight=None, **fit_params): Sample weights. If None, then samples are equally weighted. Used as probabilities to sample the training set. Note that the expected frequency semantics for the `sample_weight` parameter are only - fulfilled when sampling with replacement `bootstrap=True`. + fulfilled when sampling with replacement `bootstrap=True` and using + a float or integer `max_samples` (instead of the default + `max_samples=None`). **fit_params : dict Parameters to pass to the underlying estimators. @@ -462,20 +522,7 @@ def _fit( if max_samples is None: max_samples = self.max_samples - if not isinstance(max_samples, numbers.Integral): - if sample_weight is None: - max_samples = max(int(max_samples * X.shape[0]), 1) - else: - sw_sum = np.sum(sample_weight) - if sw_sum <= 1: - raise ValueError( - f"The total sum of sample weights is {sw_sum}, which prevents " - "resampling with a fractional value for max_samples=" - f"{max_samples}. Either pass max_samples as an integer or " - "use a larger sample_weight." - ) - max_samples = max(int(max_samples * sw_sum), 1) - + max_samples = _get_n_samples_bootstrap(X.shape[0], max_samples, sample_weight) if not self.bootstrap and max_samples > X.shape[0]: raise ValueError( f"Effective max_samples={max_samples} must be <= n_samples=" @@ -728,13 +775,14 @@ class BaggingClassifier(ClassifierMixin, BaseBagging): n_estimators : int, default=10 The number of base estimators in the ensemble. - max_samples : int or float, default=1.0 + max_samples : int or float, default=None The number of samples to draw from X to train each base estimator (with replacement by default, see `bootstrap` for more details). + - If None, then draw `X.shape[0]` samples irrespective of `sample_weight`. - If int, then draw `max_samples` samples. - - If float, then draw `max_samples * X.shape[0]` unweighted samples - or `max_samples * sample_weight.sum()` weighted samples. + - If float, then draw `max_samples * X.shape[0]` unweighted samples or + `max_samples * sample_weight.sum()` weighted samples. max_features : int or float, default=1.0 The number of features to draw from X to train each base estimator ( @@ -867,7 +915,7 @@ def __init__( estimator=None, n_estimators=10, *, - max_samples=1.0, + max_samples=None, max_features=1.0, bootstrap=True, bootstrap_features=False, @@ -1239,12 +1287,14 @@ class BaggingRegressor(RegressorMixin, BaseBagging): n_estimators : int, default=10 The number of base estimators in the ensemble. - max_samples : int or float, default=1.0 + max_samples : int or float, default=None The number of samples to draw from X to train each base estimator (with replacement by default, see `bootstrap` for more details). + - If None, then draw `X.shape[0]` samples irrespective of `sample_weight`. - If int, then draw `max_samples` samples. - - If float, then draw `max_samples * X.shape[0]` samples. + - If float, then draw `max_samples * X.shape[0]` unweighted samples or + `max_samples * sample_weight.sum()` weighted samples. max_features : int or float, default=1.0 The number of features to draw from X to train each base estimator ( @@ -1368,7 +1418,7 @@ def __init__( estimator=None, n_estimators=10, *, - max_samples=1.0, + max_samples=None, max_features=1.0, bootstrap=True, bootstrap_features=False, diff --git a/sklearn/ensemble/tests/test_bagging.py b/sklearn/ensemble/tests/test_bagging.py index 611ea271b3f91..0b73499467da6 100644 --- a/sklearn/ensemble/tests/test_bagging.py +++ b/sklearn/ensemble/tests/test_bagging.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: BSD-3-Clause import re +import warnings from itertools import cycle, product import joblib @@ -26,6 +27,7 @@ RandomForestClassifier, RandomForestRegressor, ) +from sklearn.ensemble._bagging import _get_n_samples_bootstrap from sklearn.feature_selection import SelectKBest from sklearn.linear_model import LogisticRegression, Perceptron from sklearn.model_selection import GridSearchCV, ParameterGrid, train_test_split @@ -706,16 +708,17 @@ def test_warning_bootstrap_sample_weight(): def test_invalid_sample_weight_max_samples_bootstrap_combinations(): X, y = iris.data, iris.target - # Case 1: small weights and fractional max_samples would lead to sampling - # less than 1 sample, which is not allowed. + # Case 1: small weights and fractional max_samples lead to a small + # number of bootstrap samples, which raises a UserWarning. clf = BaggingClassifier(max_samples=1.0) sample_weight = np.ones_like(y) / (2 * len(y)) expected_msg = ( - r"The total sum of sample weights is 0.5(\d*), which prevents resampling with " - r"a fractional value for max_samples=1\.0\. Either pass max_samples as an " - r"integer or use a larger sample_weight\." + "Using the fractional value max_samples=1.0 when " + r"the total sum of sample weights is 0.5(\d*) " + r"results in a low number \(1\) of bootstrap samples. " + "We recommend passing `max_samples` as an integer." ) - with pytest.raises(ValueError, match=expected_msg): + with pytest.warns(UserWarning, match=expected_msg): clf.fit(X, y, sample_weight=sample_weight) # Case 2: large weights and bootstrap=False would lead to sampling without @@ -813,6 +816,55 @@ def test_draw_indices_using_sample_weight( assert_allclose(estimator.y_, y[samples]) +def test_get_n_samples_bootstrap(): + n_samples, max_samples, sample_weight = 10, None, "not_used" + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == n_samples + + n_samples, max_samples, sample_weight = 10, 5, "not_used" + assert ( + _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == max_samples + ) + + n_samples, max_samples, sample_weight = 10, 1e-5, None + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == 1 + + n_samples, max_samples, sample_weight = 10, 0.66, None + warning_msg = ".+the number of samples.+low number.+max_samples.+as an integer" + with pytest.warns(UserWarning, match=warning_msg): + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == int( + max_samples * n_samples + ) + + n_samples, max_samples, sample_weight = 10, 1e-5, None + with pytest.warns(UserWarning, match=warning_msg): + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == 1 + + warning_msg_with_weights = ( + ".+the total sum of sample weights.+low number.+max_samples.+as an integer" + ) + rng = np.random.default_rng(0) + n_samples, max_samples, sample_weight = 1_000_000, 1e-5, rng.uniform(size=1_000_000) + with pytest.warns(UserWarning, match=warning_msg_with_weights): + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == int( + max_samples * sample_weight.sum() + ) + + sample_weight = np.ones(3) + with warnings.catch_warnings(): + warnings.simplefilter("error") + + n_samples, max_samples, sample_weight = 100, 30, None + assert ( + _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) + == max_samples + ) + + n_samples, max_samples, sample_weight = 100, 0.5, rng.uniform(size=100) + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == int( + max_samples * sample_weight.sum() + ) + + def test_oob_score_removed_on_warm_start(): X, y = make_hastie_10_2(n_samples=100, random_state=1) From f1ad9f9498333cc71854cbd897f85f48450fbec9 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Fri, 5 Dec 2025 15:09:16 +0100 Subject: [PATCH 033/462] Fix `_safe_indexing` with non integer arrays on array API inputs (#32840) --- sklearn/utils/_array_api.py | 2 +- sklearn/utils/_indexing.py | 20 +++++++++-- sklearn/utils/tests/test_indexing.py | 52 ++++++++++++++++++++++++---- 3 files changed, 65 insertions(+), 9 deletions(-) diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index e3ba6b58149c5..03e3e18db4f84 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -469,7 +469,7 @@ def move_to(*arrays, xp, device): `array` may contain `None` entries, these are left unchanged. Sparse arrays are accepted (as pass through) if the reference namespace is - Numpy, in which case they are returned unchanged. Otherwise a `TypeError` + NumPy, in which case they are returned unchanged. Otherwise a `TypeError` is raised. Parameters diff --git a/sklearn/utils/_indexing.py b/sklearn/utils/_indexing.py index de983f2f3adb0..f4202ac7586c0 100644 --- a/sklearn/utils/_indexing.py +++ b/sklearn/utils/_indexing.py @@ -36,8 +36,24 @@ def _array_indexing(array, key, key_dtype, axis): """Index an array or scipy.sparse consistently across NumPy version.""" xp, is_array_api, device_ = get_namespace_and_device(array) if is_array_api: - key = move_to(key, xp=xp, device=device_) - return xp.take(array, key, axis=axis) + if hasattr(key, "shape"): + key = move_to(key, xp=xp, device=device_) + elif isinstance(key, (int, slice)): + # Passthrough for valid __getitem__ inputs as noted in the array + # API spec. + pass + else: + key = xp.asarray(key, device=device_) + + if hasattr(key, "dtype"): + if xp.isdtype(key.dtype, "integral"): + return xp.take(array, key, axis=axis) + elif xp.isdtype(key.dtype, "bool"): + # Array API does not support boolean indexing for n-dim arrays + # yet hence the need to turn to equivalent integer indexing. + indices = xp.arange(array.shape[axis], device=device_) + return xp.take(array, indices[key], axis=axis) + if issparse(array) and key_dtype == "bool": key = np.asarray(key) if isinstance(key, tuple): diff --git a/sklearn/utils/tests/test_indexing.py b/sklearn/utils/tests/test_indexing.py index 8934b5ef5a98d..4d4b5a4a7bf78 100644 --- a/sklearn/utils/tests/test_indexing.py +++ b/sklearn/utils/tests/test_indexing.py @@ -10,7 +10,10 @@ from sklearn.externals._packaging.version import parse as parse_version from sklearn.utils import _safe_indexing, resample, shuffle from sklearn.utils._array_api import ( + _convert_to_numpy, _get_namespace_device_dtype_ids, + device, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._indexing import ( @@ -22,6 +25,7 @@ from sklearn.utils._testing import ( _array_api_for_tests, _convert_container, + assert_allclose, assert_allclose_dense_sparse, assert_array_equal, skip_if_array_api_compat_not_configured, @@ -108,22 +112,22 @@ def test_determine_key_type_slice_error(): @skip_if_array_api_compat_not_configured @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_, dtype_name", yield_namespace_device_dtype_combinations(), ids=_get_namespace_device_dtype_ids, ) -def test_determine_key_type_array_api(array_namespace, device, dtype_name): - xp = _array_api_for_tests(array_namespace, device) +def test_determine_key_type_array_api(array_namespace, device_, dtype_name): + xp = _array_api_for_tests(array_namespace, device_) with sklearn.config_context(array_api_dispatch=True): - int_array_key = xp.asarray([1, 2, 3]) + int_array_key = xp.asarray([1, 2, 3], device=device_) assert _determine_key_type(int_array_key) == "int" - bool_array_key = xp.asarray([True, False, True]) + bool_array_key = xp.asarray([True, False, True], device=device_) assert _determine_key_type(bool_array_key) == "bool" try: - complex_array_key = xp.asarray([1 + 1j, 2 + 2j, 3 + 3j]) + complex_array_key = xp.asarray([1 + 1j, 2 + 2j, 3 + 3j], device=device_) except TypeError: # Complex numbers are not supported by all Array API libraries. complex_array_key = None @@ -133,6 +137,42 @@ def test_determine_key_type_array_api(array_namespace, device, dtype_name): _determine_key_type(complex_array_key) +@skip_if_array_api_compat_not_configured +@pytest.mark.parametrize( + "array_namespace, device_, dtype_name", + yield_namespace_device_dtype_combinations(), + ids=_get_namespace_device_dtype_ids, +) +@pytest.mark.parametrize( + "indexing_key", + ( + 0, + -1, + [1, 3], + np.array([1, 3]), + slice(1, 2), + [True, False, True, True], + np.asarray([False, False, False, False]), + ), +) +@pytest.mark.parametrize("axis", [0, 1]) +def test_safe_indexing_array_api_support( + array_namespace, device_, dtype_name, indexing_key, axis +): + xp = _array_api_for_tests(array_namespace, device_) + + array_to_index_np = np.arange(16).reshape(4, 4) + expected_result = _safe_indexing(array_to_index_np, indexing_key, axis=axis) + array_to_index_xp = move_to(array_to_index_np, xp=xp, device=device_) + + with sklearn.config_context(array_api_dispatch=True): + indexed_array_xp = _safe_indexing(array_to_index_xp, indexing_key, axis=axis) + assert device(indexed_array_xp) == device(array_to_index_xp) + assert indexed_array_xp.dtype == array_to_index_xp.dtype + + assert_allclose(_convert_to_numpy(indexed_array_xp, xp=xp), expected_result) + + @pytest.mark.parametrize( "array_type", ["list", "array", "sparse", "dataframe", "polars", "pyarrow"] ) From 47621fec9c88727fcf06e1acfb9493480454edf9 Mon Sep 17 00:00:00 2001 From: Tim Head Date: Fri, 5 Dec 2025 17:59:35 +0100 Subject: [PATCH 034/462] FIX Make `get_namespace` handle pandas dataframe input (#32838) --- .../upcoming_changes/array-api/32838.fix.rst | 2 + sklearn/compose/_column_transformer.py | 6 +- .../gradient_boosting.py | 4 +- sklearn/feature_selection/_base.py | 4 +- sklearn/inspection/_plot/decision_boundary.py | 5 +- .../preprocessing/_function_transformer.py | 7 +- sklearn/utils/_array_api.py | 3 + sklearn/utils/_dataframe.py | 123 ++++++++++++++++++ sklearn/utils/_indexing.py | 16 ++- sklearn/utils/tests/test_array_api.py | 30 +++++ sklearn/utils/tests/test_dataframe.py | 84 ++++++++++++ sklearn/utils/tests/test_validation.py | 71 ---------- sklearn/utils/validation.py | 53 +------- 13 files changed, 267 insertions(+), 141 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/32838.fix.rst create mode 100644 sklearn/utils/_dataframe.py create mode 100644 sklearn/utils/tests/test_dataframe.py diff --git a/doc/whats_new/upcoming_changes/array-api/32838.fix.rst b/doc/whats_new/upcoming_changes/array-api/32838.fix.rst new file mode 100644 index 0000000000000..ae689f8816841 --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/32838.fix.rst @@ -0,0 +1,2 @@ +- Estimators with array API support no longer reject dataframe inputs when array API support is enabled. + By :user:`Tim Head ` diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index 4e052399d36f5..e2c196f84d313 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -20,6 +20,7 @@ from sklearn.pipeline import _fit_transform_one, _name_estimators, _transform_one from sklearn.preprocessing import FunctionTransformer from sklearn.utils import Bunch +from sklearn.utils._dataframe import is_pandas_df from sklearn.utils._indexing import ( _determine_key_type, _get_column_indices, @@ -47,7 +48,6 @@ _check_feature_names_in, _check_n_features, _get_feature_names, - _is_pandas_df, _num_samples, check_array, check_is_fitted, @@ -773,7 +773,7 @@ def _validate_output(self, result): except ImportError: return for Xs, name in zip(result, names): - if not _is_pandas_df(Xs): + if not is_pandas_df(Xs): continue for col_name, dtype in Xs.dtypes.to_dict().items(): if getattr(dtype, "na_value", None) is not pd.NA: @@ -1064,7 +1064,7 @@ def transform(self, X, **params): # were not present in fit time, and the order of the columns doesn't # matter. fit_dataframe_and_transform_dataframe = hasattr(self, "feature_names_in_") and ( - _is_pandas_df(X) or hasattr(X, "__dataframe__") + is_pandas_df(X) or hasattr(X, "__dataframe__") ) n_samples = _num_samples(X) diff --git a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py index 4bbc46d9ae135..4a4fa319f4ab7 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py +++ b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py @@ -40,6 +40,7 @@ from sklearn.model_selection import train_test_split from sklearn.preprocessing import FunctionTransformer, LabelEncoder, OrdinalEncoder from sklearn.utils import check_random_state, compute_sample_weight, resample +from sklearn.utils._dataframe import is_pandas_df from sklearn.utils._missing import is_scalar_nan from sklearn.utils._openmp_helpers import _openmp_effective_n_threads from sklearn.utils._param_validation import Interval, RealNotInt, StrOptions @@ -48,7 +49,6 @@ _check_monotonic_cst, _check_sample_weight, _check_y, - _is_pandas_df, check_array, check_consistent_length, check_is_fitted, @@ -371,7 +371,7 @@ def _check_categorical_features(self, X): # fixed in main and maybe included in 2.2.1, see # https://github.com/pandas-dev/pandas/pull/57173. # Also pandas versions < 1.5.1 do not support the dataframe interchange - if _is_pandas_df(X): + if is_pandas_df(X): X_is_dataframe = True categorical_columns_mask = np.asarray(X.dtypes == "category") elif hasattr(X, "__dataframe__"): diff --git a/sklearn/feature_selection/_base.py b/sklearn/feature_selection/_base.py index 3c12cd035d5c8..4527cfd0cd815 100644 --- a/sklearn/feature_selection/_base.py +++ b/sklearn/feature_selection/_base.py @@ -12,11 +12,11 @@ from sklearn.base import TransformerMixin from sklearn.utils import _safe_indexing, check_array, safe_sqr +from sklearn.utils._dataframe import is_pandas_df from sklearn.utils._set_output import _get_output_config from sklearn.utils._tags import get_tags from sklearn.utils.validation import ( _check_feature_names_in, - _is_pandas_df, check_is_fitted, validate_data, ) @@ -100,7 +100,7 @@ def transform(self, X): # Preserve X when X is a dataframe and the output is configured to # be pandas. output_config_dense = _get_output_config("transform", estimator=self)["dense"] - preserve_X = output_config_dense != "default" and _is_pandas_df(X) + preserve_X = output_config_dense != "default" and is_pandas_df(X) # note: we use get_tags instead of __sklearn_tags__ because this is a # public Mixin. diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index 22292053f7867..33c8a15bb4fe7 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -8,13 +8,12 @@ from sklearn.base import is_regressor from sklearn.preprocessing import LabelEncoder from sklearn.utils import _safe_indexing +from sklearn.utils._dataframe import is_pandas_df, is_polars_df from sklearn.utils._optional_dependencies import check_matplotlib_support from sklearn.utils._response import _get_response_values from sklearn.utils._set_output import _get_adapter_from_container from sklearn.utils.validation import ( _is_arraylike_not_scalar, - _is_pandas_df, - _is_polars_df, _num_features, check_is_fitted, ) @@ -496,7 +495,7 @@ def from_estimator( ) X_grid = np.c_[xx0.ravel(), xx1.ravel()] - if _is_pandas_df(X) or _is_polars_df(X): + if is_pandas_df(X) or is_polars_df(X): adapter = _get_adapter_from_container(X) X_grid = adapter.create_container( X_grid, diff --git a/sklearn/preprocessing/_function_transformer.py b/sklearn/preprocessing/_function_transformer.py index 7c56758d249a2..b3a64508e906c 100644 --- a/sklearn/preprocessing/_function_transformer.py +++ b/sklearn/preprocessing/_function_transformer.py @@ -7,6 +7,7 @@ import numpy as np from sklearn.base import BaseEstimator, TransformerMixin, _fit_context +from sklearn.utils._dataframe import is_pandas_df, is_polars_df from sklearn.utils._param_validation import StrOptions from sklearn.utils._repr_html.estimator import _VisualBlock from sklearn.utils._set_output import _get_adapter_from_container, _get_output_config @@ -15,8 +16,6 @@ _allclose_dense_sparse, _check_feature_names_in, _get_feature_names, - _is_pandas_df, - _is_polars_df, check_array, validate_data, ) @@ -302,9 +301,9 @@ def transform(self, X): "a {0} DataFrame to follow the `set_output` API or `feature_names_out`" " should be defined." ) - if output_config == "pandas" and not _is_pandas_df(out): + if output_config == "pandas" and not is_pandas_df(out): warnings.warn(warn_msg.format("pandas")) - elif output_config == "polars" and not _is_polars_df(out): + elif output_config == "polars" and not is_polars_df(out): warnings.warn(warn_msg.format("polars")) return out diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 03e3e18db4f84..9b6cc6d9774ba 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -16,6 +16,7 @@ from sklearn.externals import array_api_compat from sklearn.externals import array_api_extra as xpx from sklearn.externals.array_api_compat import numpy as np_compat +from sklearn.utils._dataframe import is_df_or_series from sklearn.utils.fixes import parse_version # TODO: complete __all__ @@ -320,6 +321,8 @@ def _remove_non_arrays(*arrays, remove_none=True, remove_types=(str,)): continue if sp.issparse(array): continue + if is_df_or_series(array): + continue filtered_arrays.append(array) return filtered_arrays diff --git a/sklearn/utils/_dataframe.py b/sklearn/utils/_dataframe.py new file mode 100644 index 0000000000000..2d77e098aefbb --- /dev/null +++ b/sklearn/utils/_dataframe.py @@ -0,0 +1,123 @@ +"""Functions to determine if an object is a dataframe or series.""" + +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +import sys + + +def is_df_or_series(X): + """Return True if the X is a dataframe or series. + + Parameters + ---------- + X : {array-like, dataframe} + The array-like or dataframe object to check. + + Returns + ------- + bool + True if the X is a dataframe or series, False otherwise. + """ + return is_pandas_df_or_series(X) or is_polars_df_or_series(X) or is_pyarrow_data(X) + + +def is_pandas_df_or_series(X): + """Return True if the X is a pandas dataframe or series. + + Parameters + ---------- + X : {array-like, dataframe} + The array-like or dataframe object to check. + + Returns + ------- + bool + True if the X is a pandas dataframe or series, False otherwise. + """ + try: + pd = sys.modules["pandas"] + except KeyError: + return False + return isinstance(X, (pd.DataFrame, pd.Series)) + + +def is_pandas_df(X): + """Return True if the X is a pandas dataframe. + + Parameters + ---------- + X : {array-like, dataframe} + The array-like or dataframe object to check. + + Returns + ------- + bool + True if the X is a pandas dataframe, False otherwise. + """ + try: + pd = sys.modules["pandas"] + except KeyError: + return False + return isinstance(X, pd.DataFrame) + + +def is_pyarrow_data(X): + """Return True if the X is a pyarrow Table, RecordBatch, Array or ChunkedArray. + + Parameters + ---------- + X : {array-like, dataframe} + The array-like or dataframe object to check. + + Returns + ------- + bool + True if the X is a pyarrow Table, RecordBatch, Array or ChunkedArray, + False otherwise. + """ + try: + pa = sys.modules["pyarrow"] + except KeyError: + return False + return isinstance(X, (pa.Table, pa.RecordBatch, pa.Array, pa.ChunkedArray)) + + +def is_polars_df_or_series(X): + """Return True if the X is a polars dataframe or series. + + Parameters + ---------- + X : {array-like, dataframe} + The array-like or dataframe object to check. + + Returns + ------- + bool + True if the X is a polars dataframe or series, False otherwise. + """ + try: + pl = sys.modules["polars"] + except KeyError: + return False + return isinstance(X, (pl.DataFrame, pl.Series)) + + +def is_polars_df(X): + """Return True if the X is a polars dataframe. + + Parameters + ---------- + X : {array-like, dataframe} + The array-like or dataframe object to check. + + Returns + ------- + bool + True if the X is a polarsdataframe, False otherwise. + """ + try: + pl = sys.modules["polars"] + except KeyError: + return False + return isinstance(X, pl.DataFrame) diff --git a/sklearn/utils/_indexing.py b/sklearn/utils/_indexing.py index f4202ac7586c0..484e716bc1170 100644 --- a/sklearn/utils/_indexing.py +++ b/sklearn/utils/_indexing.py @@ -16,15 +16,17 @@ get_namespace_and_device, move_to, ) +from sklearn.utils._dataframe import ( + is_pandas_df, + is_polars_df_or_series, + is_pyarrow_data, +) from sklearn.utils._param_validation import Interval, validate_params from sklearn.utils.extmath import _approximate_mode from sklearn.utils.fixes import PYARROW_VERSION_BELOW_17 from sklearn.utils.validation import ( _check_sample_weight, _is_arraylike_not_scalar, - _is_pandas_df, - _is_polars_df_or_series, - _is_pyarrow_data, _use_interchange_protocol, check_array, check_consistent_length, @@ -341,21 +343,21 @@ def _safe_indexing(X, indices, *, axis=0): if ( axis == 1 and indices_dtype == "str" - and not (_is_pandas_df(X) or _use_interchange_protocol(X)) + and not (is_pandas_df(X) or _use_interchange_protocol(X)) ): raise ValueError( "Specifying the columns using strings is only supported for dataframes." ) if hasattr(X, "iloc"): - # TODO: we should probably use _is_pandas_df_or_series(X) instead but: + # TODO: we should probably use is_pandas_df_or_series(X) instead but: # 1) Currently, it (probably) works for dataframes compliant to pandas' API. # 2) Updating would require updating some tests such as # test_train_test_split_mock_pandas. return _pandas_indexing(X, indices, indices_dtype, axis=axis) - elif _is_polars_df_or_series(X): + elif is_polars_df_or_series(X): return _polars_indexing(X, indices, indices_dtype, axis=axis) - elif _is_pyarrow_data(X): + elif is_pyarrow_data(X): return _pyarrow_indexing(X, indices, indices_dtype, axis=axis) elif _use_interchange_protocol(X): # pragma: no cover # Once the dataframe X is converted into its dataframe interchange protocol diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index 8bb17c8a4fa08..a1fc81c109af8 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -43,6 +43,7 @@ from sklearn.utils._testing import ( SkipTest, _array_api_for_tests, + _convert_container, assert_array_equal, skip_if_array_api_compat_not_configured, ) @@ -84,6 +85,35 @@ def test_get_namespace_ndarray_with_dispatch(): assert xp_out is np_compat +@skip_if_array_api_compat_not_configured +@pytest.mark.parametrize( + "constructor_name", ["pyarrow", "dataframe", "polars", "series"] +) +def test_get_namespace_df_with_dispatch(constructor_name): + """Test get_namespace on dataframes and series.""" + + df = _convert_container([[1, 4, 2], [3, 3, 6]], constructor_name) + with config_context(array_api_dispatch=True): + xp_out, is_array_api_compliant = get_namespace(df) + assert not is_array_api_compliant + + # When operating on dataframes or series the Numpy namespace is + # the right thing to use. + assert xp_out is np_compat + + +@skip_if_array_api_compat_not_configured +def test_get_namespace_sparse_with_dispatch(): + """Test get_namespace on sparse arrays.""" + with config_context(array_api_dispatch=True): + xp_out, is_array_api_compliant = get_namespace(sp.csr_array([[1, 2, 3]])) + assert not is_array_api_compliant + + # When operating on sparse arrays the Numpy namespace is + # the right thing to use. + assert xp_out is np_compat + + @skip_if_array_api_compat_not_configured def test_get_namespace_array_api(monkeypatch): """Test get_namespace for ArrayAPI arrays.""" diff --git a/sklearn/utils/tests/test_dataframe.py b/sklearn/utils/tests/test_dataframe.py new file mode 100644 index 0000000000000..49e5296590c34 --- /dev/null +++ b/sklearn/utils/tests/test_dataframe.py @@ -0,0 +1,84 @@ +"""Tests for dataframe detection functions.""" + +import numpy as np +import pytest + +from sklearn._min_dependencies import dependent_packages +from sklearn.utils._dataframe import is_df_or_series, is_pandas_df, is_polars_df +from sklearn.utils._testing import _convert_container + + +@pytest.mark.parametrize("constructor_name", ["pyarrow", "dataframe", "polars"]) +def test_is_df_or_series(constructor_name): + df = _convert_container([[1, 4, 2], [3, 3, 6]], constructor_name) + + assert is_df_or_series(df) + assert not is_df_or_series(np.asarray([1, 2, 3])) + + +@pytest.mark.parametrize("constructor_name", ["pyarrow", "dataframe", "polars"]) +def test_is_pandas_df_other_libraries(constructor_name): + df = _convert_container([[1, 4, 2], [3, 3, 6]], constructor_name) + if constructor_name in ("pyarrow", "polars"): + assert not is_pandas_df(df) + else: + assert is_pandas_df(df) + + +def test_is_pandas_df(): + """Check behavior of is_pandas_df when pandas is installed.""" + pd = pytest.importorskip("pandas") + df = pd.DataFrame([[1, 2, 3]]) + assert is_pandas_df(df) + assert not is_pandas_df(np.asarray([1, 2, 3])) + assert not is_pandas_df(1) + + +def test_is_pandas_df_pandas_not_installed(hide_available_pandas): + """Check is_pandas_df when pandas is not installed.""" + + assert not is_pandas_df(np.asarray([1, 2, 3])) + assert not is_pandas_df(1) + + +@pytest.mark.parametrize( + "constructor_name, minversion", + [ + ("pyarrow", dependent_packages["pyarrow"][0]), + ("dataframe", dependent_packages["pandas"][0]), + ("polars", dependent_packages["polars"][0]), + ], +) +def test_is_polars_df_other_libraries(constructor_name, minversion): + df = _convert_container( + [[1, 4, 2], [3, 3, 6]], + constructor_name, + minversion=minversion, + ) + if constructor_name in ("pyarrow", "dataframe"): + assert not is_polars_df(df) + else: + assert is_polars_df(df) + + +def test_is_polars_df_for_duck_typed_polars_dataframe(): + """Check is_polars_df for object that looks like a polars dataframe""" + + class NotAPolarsDataFrame: + def __init__(self): + self.columns = [1, 2, 3] + self.schema = "my_schema" + + not_a_polars_df = NotAPolarsDataFrame() + assert not is_polars_df(not_a_polars_df) + + +def test_is_polars_df(): + """Check that is_polars_df return False for non-dataframe objects.""" + + class LooksLikePolars: + def __init__(self): + self.columns = ["a", "b"] + self.schema = ["a", "b"] + + assert not is_polars_df(LooksLikePolars()) diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 3aafe4ce625b9..b029cab433eb9 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -14,7 +14,6 @@ import sklearn from sklearn._config import config_context -from sklearn._min_dependencies import dependent_packages from sklearn.base import BaseEstimator from sklearn.datasets import make_blobs from sklearn.ensemble import RandomForestRegressor @@ -77,8 +76,6 @@ _estimator_has, _get_feature_names, _is_fitted, - _is_pandas_df, - _is_polars_df, _num_features, _num_samples, _to_object_array, @@ -1995,63 +1992,6 @@ def test_get_feature_names_dataframe_protocol(constructor_name, minversion): assert_array_equal(feature_names, columns) -@pytest.mark.parametrize("constructor_name", ["pyarrow", "dataframe", "polars"]) -def test_is_pandas_df_other_libraries(constructor_name): - df = _convert_container([[1, 4, 2], [3, 3, 6]], constructor_name) - if constructor_name in ("pyarrow", "polars"): - assert not _is_pandas_df(df) - else: - assert _is_pandas_df(df) - - -def test_is_pandas_df(): - """Check behavior of is_pandas_df when pandas is installed.""" - pd = pytest.importorskip("pandas") - df = pd.DataFrame([[1, 2, 3]]) - assert _is_pandas_df(df) - assert not _is_pandas_df(np.asarray([1, 2, 3])) - assert not _is_pandas_df(1) - - -def test_is_pandas_df_pandas_not_installed(hide_available_pandas): - """Check _is_pandas_df when pandas is not installed.""" - - assert not _is_pandas_df(np.asarray([1, 2, 3])) - assert not _is_pandas_df(1) - - -@pytest.mark.parametrize( - "constructor_name, minversion", - [ - ("pyarrow", dependent_packages["pyarrow"][0]), - ("dataframe", dependent_packages["pandas"][0]), - ("polars", dependent_packages["polars"][0]), - ], -) -def test_is_polars_df_other_libraries(constructor_name, minversion): - df = _convert_container( - [[1, 4, 2], [3, 3, 6]], - constructor_name, - minversion=minversion, - ) - if constructor_name in ("pyarrow", "dataframe"): - assert not _is_polars_df(df) - else: - assert _is_polars_df(df) - - -def test_is_polars_df_for_duck_typed_polars_dataframe(): - """Check _is_polars_df for object that looks like a polars dataframe""" - - class NotAPolarsDataFrame: - def __init__(self): - self.columns = [1, 2, 3] - self.schema = "my_schema" - - not_a_polars_df = NotAPolarsDataFrame() - assert not _is_polars_df(not_a_polars_df) - - def test_get_feature_names_numpy(): """Get feature names return None for numpy arrays.""" X = np.array([[1, 2, 3], [4, 5, 6]]) @@ -2322,17 +2262,6 @@ def test_column_or_1d(): column_or_1d(y) -def test__is_polars_df(): - """Check that _is_polars_df return False for non-dataframe objects.""" - - class LooksLikePolars: - def __init__(self): - self.columns = ["a", "b"] - self.schema = ["a", "b"] - - assert not _is_polars_df(LooksLikePolars()) - - def test_check_array_writeable_np(): """Check the behavior of check_array when a writeable array is requested without copy if possible, on numpy arrays. diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index a112ec4adba61..0e59bde2c02dc 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -5,7 +5,6 @@ import numbers import operator -import sys import warnings from collections.abc import Sequence from contextlib import suppress @@ -30,6 +29,7 @@ get_namespace, get_namespace_and_device, ) +from sklearn.utils._dataframe import is_pandas_df, is_pandas_df_or_series from sklearn.utils._isfinite import FiniteStatus, cy_isfinite from sklearn.utils._tags import get_tags from sklearn.utils.fixes import ( @@ -312,7 +312,7 @@ def _use_interchange_protocol(X): to ensure strict behavioral backward compatibility with older versions of scikit-learn. """ - return not _is_pandas_df(X) and hasattr(X, "__dataframe__") + return not is_pandas_df(X) and hasattr(X, "__dataframe__") def _num_features(X): @@ -1129,7 +1129,7 @@ def is_sparse(dtype): # ensure that the output is writeable, even if avoidable, to not overwrite # the user's data by surprise. - if _is_pandas_df_or_series(array_orig): + if is_pandas_df_or_series(array_orig): try: # In pandas >= 3, np.asarray(df), called earlier in check_array, # returns a read-only intermediate array. It can be made writeable @@ -2307,51 +2307,6 @@ def _check_method_params(X, params, indices=None): return method_params_validated -def _is_pandas_df_or_series(X): - """Return True if the X is a pandas dataframe or series.""" - try: - pd = sys.modules["pandas"] - except KeyError: - return False - return isinstance(X, (pd.DataFrame, pd.Series)) - - -def _is_pandas_df(X): - """Return True if the X is a pandas dataframe.""" - try: - pd = sys.modules["pandas"] - except KeyError: - return False - return isinstance(X, pd.DataFrame) - - -def _is_pyarrow_data(X): - """Return True if the X is a pyarrow Table, RecordBatch, Array or ChunkedArray.""" - try: - pa = sys.modules["pyarrow"] - except KeyError: - return False - return isinstance(X, (pa.Table, pa.RecordBatch, pa.Array, pa.ChunkedArray)) - - -def _is_polars_df_or_series(X): - """Return True if the X is a polars dataframe or series.""" - try: - pl = sys.modules["polars"] - except KeyError: - return False - return isinstance(X, (pl.DataFrame, pl.Series)) - - -def _is_polars_df(X): - """Return True if the X is a polars dataframe.""" - try: - pl = sys.modules["polars"] - except KeyError: - return False - return isinstance(X, pl.DataFrame) - - def _get_feature_names(X): """Get feature names from X. @@ -2375,7 +2330,7 @@ def _get_feature_names(X): feature_names = None # extract feature names for support array containers - if _is_pandas_df(X): + if is_pandas_df(X): # Make sure we can inspect columns names from pandas, even with # versions too old to expose a working implementation of # __dataframe__.column_names() and avoid introducing any From 96e242533869d92328120eede658a2878e3bb700 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 8 Dec 2025 14:49:05 +0100 Subject: [PATCH 035/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#32858) Co-authored-by: Lock file bot --- ...a_forge_cuda_array-api_linux-64_conda.lock | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 392461bfb0ceb..130e53ea4b032 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -16,13 +16,13 @@ https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.6-h4922eb0_0.conda#7a0b9ce502e0ed62195e02891dfcd704 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.7-h4922eb0_0.conda#ec29f865968a81e1961b3c2f2765eebb https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_8.conda#1bad93f0aa428d618875ef3a588a889e https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.0-hb9d3cd8_0.conda#f65c946f28f0518f41ced702f44c52b7 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc @@ -32,17 +32,17 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb03c661_4 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.10.0-h202a827_0.conda#0f98f3e95272d118f7931b6bef69bfe5 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 @@ -67,11 +67,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -86,8 +86,8 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.con https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.17.0-h3dad3f2_6.conda#3a127d28266cdc0da93384d1f59fe8df https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb03c661_4.conda#ca4ed8015764937c81b830f7f5b68543 https://conda.anaconda.org/conda-forge/linux-64/cudatoolkit-11.8.0-h4ba93d1_13.conda#eb43f5f1f16e2fad2eba22219c3e499b @@ -98,7 +98,7 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.28.3-h6128344_1.conda#d8703f1ffe5a06356f06467f1d0b9464 @@ -128,7 +128,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.9-h04c0eec_0.conda# https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.1.1-h2271f48_0.conda#67075ef2cb33079efee3abfe58127a3b -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda#4780fe896e961722d0623fa91d0d3378 +https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e https://conda.anaconda.org/conda-forge/linux-64/re2-2024.07.02-h9925aae_2.conda#e84ddf12bde691e8ec894b00ea829ddf https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 @@ -140,14 +140,14 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.12.2-h108da3e_2.con https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.14.0-h5cfcd09_0.conda#0a8838771cc2e985cd295e01ae83baf1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda#367133808e89325690562099851529c8 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py313hc80a56d_0.conda#a14fa0e1f58e2fce8d6fddf8f54ed500 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda#9bcbd351966dc56a24fc0c368da5ad99 https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda#66b8b26023b8efdf8fcb23bac4b6325d https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda#d18004c37182f83b9818b714825a7627 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.12.0-pyhd8ed1ab_0.conda#a3b9510e2491c20c7fc0f5e730227fbb https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 https://conda.anaconda.org/conda-forge/linux-64/libcudnn-dev-9.10.1.4-h0fdc2d1_0.conda#a0c0b44d26a4710e6ea577fcddbe09d1 @@ -158,7 +158,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.cond https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda#74e91c36d0eef3557915c68b6c2bef96 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h7a3aeb2_0.conda#31059dc620fa57d787e3899ed0421e6d https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 @@ -167,7 +167,7 @@ https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h80991f8_2.conda#37ca27d2f726f29a068230d8f6917ce4 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 @@ -205,7 +205,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.18.0-hfca https://conda.anaconda.org/conda-forge/linux-64/libpq-17.7-h5c52fec_1.conda#a4769024afeab4b32ac8167c2f92c7ac https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.9-h4df99d1_101.conda#f41e3c1125e292e6bfcea8392a3de3d8 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.11-h4df99d1_100.conda#d1461b2e63b1909f4f5b41c823bd90ae https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-h8d10470_4.conda#e6d46d70c68d0eb69b9a040ebe3acddf https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f @@ -215,7 +215,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.36.0-h0121fbd_0.conda#fc5efe1833a4d709953964037985bb72 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha770c72_17.conda#e4ab075598123e783b788b995afbdad0 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.510-h37a5c72_3.conda#beb8577571033140c6897d257acc7724 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.12.0-ha633028_1.conda#7c1980f89dd41b097549782121a73490 @@ -243,7 +243,7 @@ https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3. https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.6.0-py313hc2a895b_2.conda#1b3207acc9af23dcfbccb4647df0838e https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-19.0.1-hcb10f89_3_cpu.conda#a28f04b6e68a1c76de76783108ad729d https://conda.anaconda.org/conda-forge/linux-64/libmagma_sparse-2.9.0-h45b15fe_0.conda#beac0a5bbe0af75db6b16d3d8fd24f7e -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_1.conda#9e87d4bda0c2711161d765332fa38781 +https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_2.conda#8a69ea71fdd37bfe42a28f0967dbb75a https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h11c21cd_1.conda#26b089b9e5fcdcdca714b01f8008d808 https://conda.anaconda.org/conda-forge/linux-64/blas-2.137-mkl.conda#9deb2d32720cc73c9991dbd9e24b499e https://conda.anaconda.org/conda-forge/linux-64/cupy-13.6.0-py313h66a2ee2_2.conda#9d83bdb568a47daf7fc38117db17fe4e From 88b46b50056ada15941f71c290615f37a35778bd Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 8 Dec 2025 14:50:02 +0100 Subject: [PATCH 036/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#32856) Co-authored-by: Lock file bot --- ...pylatest_free_threaded_linux-64_conda.lock | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index 95f916d48d876..a38cc403d1a05 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -6,45 +6,45 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#3251796e09870c978e0f69fa05e38fb6 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h4a7cf45_openblas.conda#6146bf1b7f58113d54614c6ec683c14a +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-4_h4a7cf45_openblas.conda#14ff9fdfbd8bd590fca383b995470711 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.0-he1279bd_2_cp314t.conda#f82ece6dbaba8c6bf8ed6122eb273b9d +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-he1279bd_0_cp314t.conda#08a2a24f4e6907bea0ebfe22eecae6be https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.0-py314hd8ed1ab_2.conda#86fdc2e15c6f0efb98804a2c461f30b6 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.2-py314hd8ed1ab_0.conda#d0ce45508dd9dffaec3795252897bd7a https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py314h3f98dc2_0.conda#af078f15b212d1414633e888166dd2bf https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_h0358290_openblas.conda#a84b2b7ed34206d14739fb8d29cd2799 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h47877c9_openblas.conda#9fb20e74a7436dc94dd39d9a9decddc3 -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-4_h0358290_openblas.conda#25f5e5af61cee1ffedd9b4c9947d3af8 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-4_h47877c9_openblas.conda#8ba8431802764597f400ee3e99026367 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f @@ -54,8 +54,8 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py314hd4f4903_0.conda#f9c8cd3ab6c388232550c806379856d5 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 -https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.0-h92d6c8b_2.conda#bbd6d97a4f90042d5ae148217d3110a6 +https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.2-h92d6c8b_0.conda#f4db4d53331f31ec695670d5b3cedabb https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py314hf5b80f4_1.conda#b010b4d97f99c579c759996db97e53c0 https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.0-pyhd8ed1ab_0.conda#7d545e76cfc231cf246f99963bcd27b0 From bd0dd87f792ee88c8ec70248299aae779b51ac16 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 8 Dec 2025 14:52:28 +0100 Subject: [PATCH 037/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#32859) Co-authored-by: Lock file bot --- build_tools/azure/debian_32bit_lock.txt | 4 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 108 +++++++------ ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 28 ++-- .../pylatest_conda_forge_osx-arm64_conda.lock | 59 +++---- ...st_pip_openblas_pandas_linux-64_conda.lock | 30 ++-- ...nblas_min_dependencies_linux-64_conda.lock | 40 ++--- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 58 ++++--- ...min_conda_forge_openblas_win-64_conda.lock | 30 ++-- build_tools/azure/ubuntu_atlas_lock.txt | 4 +- build_tools/circle/doc_linux-64_conda.lock | 144 +++++++++--------- .../doc_min_dependencies_linux-64_conda.lock | 99 ++++++------ ...n_conda_forge_arm_linux-aarch64_conda.lock | 50 +++--- 12 files changed, 324 insertions(+), 330 deletions(-) diff --git a/build_tools/azure/debian_32bit_lock.txt b/build_tools/azure/debian_32bit_lock.txt index 545879de75099..69fff8cc96d64 100644 --- a/build_tools/azure/debian_32bit_lock.txt +++ b/build_tools/azure/debian_32bit_lock.txt @@ -14,7 +14,7 @@ iniconfig==2.3.0 # via pytest joblib==1.5.2 # via -r build_tools/azure/debian_32bit_requirements.txt -meson==1.9.1 +meson==1.9.2 # via meson-python meson-python==0.18.0 # via -r build_tools/azure/debian_32bit_requirements.txt @@ -33,7 +33,7 @@ pygments==2.19.2 # via pytest pyproject-metadata==0.10.0 # via meson-python -pytest==9.0.1 +pytest==9.0.2 # via # -r build_tools/azure/debian_32bit_requirements.txt # pytest-cov diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index b39c5c199a0a6..2fe48c0e7538e 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -15,14 +15,14 @@ https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.6-h4922eb0_0.conda#7a0b9ce502e0ed62195e02891dfcd704 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.7-h4922eb0_0.conda#ec29f865968a81e1961b3c2f2765eebb https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d -https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.5-hb03c661_1.conda#f1d45413e1c41a7eff162bf702c02cea +https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda#f7f0d6cc2dc986d42ac2689ec88192be https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 @@ -30,17 +30,17 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.2-hfe17d71_0.conda#5641725dfad698909ec71dac80d16736 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 @@ -50,10 +50,10 @@ https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002. https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f -https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.10-h346e085_1.conda#7e6b378cfb6ad918a5fa52bd7741ab20 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h7e655bb_8.conda#1baf55dfcc138d98d437309e9aba2635 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h7e655bb_3.conda#70e83d2429b7edb595355316927dfbea -https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h7e655bb_4.conda#83a6e0fc73a7f18a8024fc89455da81c +https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.13-h2c9d079_1.conda#3c3d02681058c3d206b562b2e3bc337f +https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h8b1a151_9.conda#f7ec84186dfe7a9e3a9f9e5a4d023e75 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h8b1a151_4.conda#c7e3e08b7b1b285524ab9d74162ce40b +https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h8b1a151_5.conda#68da5b56dde41e172b7b24f071c4b392 https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda#bfd56492d8346d669010eccafe0ba058 https://conda.anaconda.org/conda-forge/linux-64/fmt-12.0.0-h2b0788b_0.conda#d90bf58b03d9a958cb4f9d3de539af17 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 @@ -66,11 +66,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -78,16 +78,16 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda#7fa07cb0fb1b625a089ccc01218ee5b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.0-h8399546_1.conda#8dbc626b1b11e7feb40a14498567b954 +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.2-he8a4886_1.conda#bade189a194e66b93c03021bd36c337b https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-ha76f1cc_3.conda#14d9fc6b1c7a823fca6cf65f595ff70d +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-hdaf4b65_5.conda#132e8f8f40f0ffc0bbde12bb4e8dd1a1 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 @@ -96,7 +96,7 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_2.conda#94cb88daa0892171457d9fdc69f43eca @@ -109,8 +109,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.6-h3cb25bf_6.conda#874d910adf3debe908b1e8e5847e0014 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-hc5c8343_4.conda#b6fdadda34f2a60870980607ef469e39 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.7-h28f887f_1.conda#7b8e3f846353b75db163ad93248e5f9d +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-ha8fc4e3_5.conda#3028f20dacafc00b22b88b324c8956cc https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 @@ -125,29 +125,30 @@ https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.9.0-heeeca48_0.conda#8a2a73951c1ea275e76fb1b92d97ff3e https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.1-hd747db4_0.conda#ddab8b2af55b88d63469c040377bd37e -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda#4780fe896e961722d0623fa91d0d3378 +https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_0.conda#0227d04521bc3d28c7995c7e1f99a721 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.1-h7ca4310_7.conda#6e91a9182506f6715c25c3ab80990653 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-h3a25ec9_10.conda#f329cc15f3b4559cab20646245c3fc9b +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.1-hef928c7_8.conda#bf749bed7435c6ed446de490d48e0444 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-hc63082f_11.conda#6a653aefdc5d83a4f959869d1759e6e3 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda#1d4e0d37da5f3c22ecd44033f673feba +https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.2.0-py313h18e8e13_0.conda#ab79cf30dea6ef4d1ab2623c5ac5601b https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda#6c4d3597cf43f3439a51b2b13e29a4ba https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda#367133808e89325690562099851529c8 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py313hc80a56d_0.conda#a14fa0e1f58e2fce8d6fddf8f54ed500 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda#66b8b26023b8efdf8fcb23bac4b6325d https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda#d18004c37182f83b9818b714825a7627 -https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.2.4-py313h7033f15_1.conda#54e4dec31235bbc794d091af9afcd845 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.12.0-pyhd8ed1ab_0.conda#a3b9510e2491c20c7fc0f5e730227fbb +https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.0-py313h7033f15_0.conda#2b1cf80423628afd34b4c66b767d7f6b https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -157,7 +158,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda#ff63bb12ac31c176ff257e3289f20770 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 @@ -167,10 +168,9 @@ https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda# https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h80991f8_2.conda#37ca27d2f726f29a068230d8f6917ce4 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/linux-64/playwright-1.57.0-h5585027_0.conda#0a2e773b5c3f67325d1733d2b7ca0ffb -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 -https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac @@ -191,10 +191,9 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.10.1-hcb69869_2.conda#3bcec65152e70e02e8d17d296c056a82 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.2-h0019752_1.conda#d99c84b6cd98789b8d5b0ad1aed5de0a https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda#4e921d9c85e6559c60215497978b3cdb https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.11.0-h3d7a050_1.conda#89985ba2a3742f34be6aafd6a8f3af8c -https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py313hf46b229_1.conda#d0616e7935acab407d1543b28c446f6f https://conda.anaconda.org/conda-forge/linux-64/coverage-7.12.0-py313h3dea7bd_0.conda#8ef99d298907bfd688a95cc714662ae7 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee @@ -204,27 +203,27 @@ https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc4 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h7f8ec31_1002.conda#c01021ae525a76fe62720c7346212d74 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_hafda6a7_1003.conda#4fe840c6d6b3719b4231ed89d389bb17 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.7-hf7376ad_0.conda#27dc1a582b442f24979f2a28641fe478 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.0-pyhd8ed1ab_0.conda#ec33a030c3bc90f0131305a8eba5f8a3 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.9-h4df99d1_101.conda#f41e3c1125e292e6bfcea8392a3de3d8 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.11-h4df99d1_100.conda#d1461b2e63b1909f4f5b41c823bd90ae https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda#a4059bc12930bddeb41aef71537ffaed https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.2-h2ceb62e_4.conda#363b3e12e49cecf931338d10114945e9 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.2-h2a9d012_5.conda#7dcf545d2a6bef32015633c5e18bbaf1 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.15.0-h2a74896_1.conda#ffd553ff98ce5d74d3d89ac269153149 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_1.conda#d3042ebdaacc689fd1daa701885fc96c +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_1.conda#66508e5f84c3dc9af1a0a62694325ef2 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 @@ -232,45 +231,44 @@ https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.56.0-pyhcf101f https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.2-pyhcf101f3_1.conda#da0c42269086f5170e2b296878ec13a6 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd -https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py313h54dd161_1.conda#710d4663806d0f72b2fb414e936223b5 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-hd6e39bc_7.conda#0f7a1d2e2c6cdfc3864c4c0b16ade511 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.0-pyhd8ed1ab_0.conda#de7372f43e63ff0876b4023b79b55e95 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-hf38915e_8.conda#af98ca0cb5bc454e249872270084e9aa https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.13.0-hf38f1be_1.conda#f10b9303c7239fbce3580a60a92bcf97 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.35.2-py310hffdcd12_0.conda#2b90c3aaf73a5b6028b068cf3c76e0b7 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a +https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-h773bc41_4_cpu.conda#9d89be0b1ca8be7eedf821a365926338 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h5875eb1_mkl.conda#6a1a4ec47263069b2dae3cfba106320c +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-4_h5875eb1_mkl.conda#bd1a86e560c3b26961279ef6b6e8d45f https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 https://conda.anaconda.org/conda-forge/noarch/polars-1.35.2-pyh6a1acc5_0.conda#24e8f78d79881b3c035f89f4b83c565c +https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.3-h5c1c036_1.conda#762af6d08fdfa7a45346b1466740bacd -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-22.0.0-h8c2c5c3_4_cpu.conda#fdecd3d6168561098fa87d767de05171 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_hfef963f_mkl.conda#62ffd188ee5c953c2d6ac54662c158a7 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h5e43f62_mkl.conda#4f33d79eda3c82c95a54e8c2981adddb +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-4_hfef963f_mkl.conda#41f4f9428b9d92b1b06f1fff80a2674d +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-4_h5e43f62_mkl.conda#f647e3368af2453546812658b5393901 https://conda.anaconda.org/conda-forge/linux-64/libparquet-22.0.0-h7376487_4_cpu.conda#5e9383b1d25179787aff71aaad8208aa https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.3-py313h85046ba_1.conda#bb7ac52bfa917611096023598a7df152 -https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e +https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_0.conda#e6475f566489789e65ebd5544db36b3e https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-22.0.0-h635bf11_4_cpu.conda#20f1a4625bce6e9b41e01232895450d9 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_hdba1596_mkl.conda#96dea51ff1435bd823020e25fd02da59 -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.9.1-cpu_mkl_hf3ca1bf_100.conda#d449787ee0ce676437bcaa48a20fa3c1 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-4_hdba1596_mkl.conda#f0b31cc6189ebd85a2e16b15de09850b +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.9.1-cpu_mkl_hf3ca1bf_101.conda#5ef08e134f6dfcf431732cb0db6f877d https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py313hf6604e3_0.conda#15f43bcd12c90186e78801fafc53d89b https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-22.0.0-py313he109ebe_0_cpu.conda#0b4a0a9ab270b275eb6da8671edb9458 -https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_0.conda#e6475f566489789e65ebd5544db36b3e https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-2_hcf00494_mkl.conda#77b464e7c3b853268dec4c82b21dca5a +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-4_hcf00494_mkl.conda#7f7c616ec25c252749fa4945ea1db3fd https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda#6186382cb34a9953bf2a18fc763dc346 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-22.0.0-h635bf11_4_cpu.conda#6389644214f7707ab05f17f464863ed3 -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_1.conda#9e87d4bda0c2711161d765332fa38781 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.9.1-cpu_mkl_py313_h5a1586b_100.conda#2230e60bae8b12369db0381e59324c0b +https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_2.conda#8a69ea71fdd37bfe42a28f0967dbb75a +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.9.1-cpu_mkl_py313_h5a1586b_101.conda#48b128d28e7849060753d14a5f249f27 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h11c21cd_1.conda#26b089b9e5fcdcdca714b01f8008d808 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.0.1-pyhe01879c_0.conda#303ec962addf1b6016afd536e9db6bc6 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.302-mkl.conda#9c83adee9e1069446e6cc92b8ea19797 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.304-mkl.conda#adbc1b7f2e7acf80f45bd6592f88f0ae https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-22.0.0-h3f74fd7_4_cpu.conda#6f07bf204431fb87d8f827807d752662 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed -https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.9.1-cpu_mkl_hd61e0f4_100.conda#b56ab3c41a86a46bd1efdb33cf3752e0 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.9.1-cpu_mkl_hd61e0f4_101.conda#d053f5fbadaf26fcb23a7acb2b0e21e6 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b https://conda.anaconda.org/conda-forge/linux-64/pyarrow-22.0.0-py313h78bf25f_0.conda#dfe7289ae9ad7aa091979a7c5e6a55c7 diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index bd7a985b866fb..b497327c72150 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -9,7 +9,7 @@ https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda#97c4b https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/osx-64/icu-75.1-h120a0e1_0.conda#d68d48a3060eb5abdc1cdc8e2a3a5966 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 -https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.6-h3d58e20_0.conda#866af4d7269cd8c9b70f5b49ad6173aa +https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.7-h3d58e20_0.conda#67c086bf0efc67b54a235dd9184bd7a2 https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda#222e0732a1d0780a622926265bee14ef https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda#d214916b24c625bcc459b245d509f22e @@ -19,7 +19,7 @@ https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda#846 https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda#18b81186a6adb43f000ad19ed7b70381 https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda#7bb6608cf1f83578587297a158a6630b https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda#003a54a4e32b02f7355b50a837e699da -https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.6-h472b3d1_0.conda#d002bb48f35085405e90a62ffeebebfb +https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.7-h472b3d1_0.conda#c9f0fc88c8f46637392b95bef78dc036 https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda#ced34dd9929f491ca6dab6a2927aff25 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda#47f1b8b4a76ebd0cd22bd7153e54a4dc @@ -28,7 +28,7 @@ https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda#21f765ced1a0ef4070df53cb425e1967 https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda#63186ac7a8a24b3528b4b14f21c03f54 https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f -https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.51-h380d223_0.conda#d54babdd92ec19c27af739b53e189335 +https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.53-h380d223_0.conda#0cdbbd56f660997cfe5d33e516afac2f https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.1-h6cc646a_0.conda#f71213ed0c51030cb17a77fc60a757f1 https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-ha1d9b0f_0.conda#453807a4b94005e7148f89f9327eb1b7 @@ -37,14 +37,14 @@ https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda#3f5 https://conda.anaconda.org/conda-forge/osx-64/qhull-2020.2-h3c5361c_5.conda#dd1ea9ff27c93db7c01a7b7656bd4ad4 https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda#342570f8e02f2f022147a7f841475784 https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda#bd9f1de651dbd80b51281c694827f78f -https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.1-h55e386d_0.conda#a74905e66f8d64c939c1010f1ade58f9 -https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h281d3d1_4.conda#40d8b69d4ab5b315e615ac0bdb650613 +https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.2-h53ec75d_0.conda#1e979f90e823b82604ab1da7e76c75e5 +https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.conda#dfbdc8fd781dc3111541e4234c19fdbd -https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_14.conda#ad31de7df92caf04a70d0d8dc48d9ecd +https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_15.conda#c816665789d1e47cdfd6da8a81e1af64 https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h7b7ecba_0.conda#e7ed73b34f9d43d80b7e80eba9bce9f3 -https://conda.anaconda.org/conda-forge/osx-64/python-3.14.0-hf88997e_102_cp314.conda#7917d1205eed3e72366a3397dca8a2af +https://conda.anaconda.org/conda-forge/osx-64/python-3.14.2-hf88997e_100_cp314.conda#48921d5efb314c3e628089fc6e27e54a https://conda.anaconda.org/conda-forge/osx-64/brotli-1.2.0-hf139dec_1.conda#149d8ee7d6541a02a6117d8814fd9413 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -54,14 +54,14 @@ https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.9-py314hf3ac25a_2.conda#28a77c52c425fa9c6d914c609c626b1a https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.17-h72f5680_0.conda#bf210d0c63f2afb9e414a858b79f0eaa https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.1-h694c41f_0.conda#e0e2edaf5e0c71b843e25a7ecc451cc9 -https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_14.conda#0f4173df0120daf2b2084a55960048e8 -https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.1-default_h094e1f9_1002.conda#4d9e9610b6a16291168144842cd9cae2 -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_15.conda#c2a6149bf7f82774a0118b9efef966dd +https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.1-default_h273dbb7_1003.conda#5a87dfe5dcdc54ca4dc839e1d3577785 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h87e8dc5_0.conda#a67d3517ebbf615b91ef9fdc99934e0c https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 @@ -79,7 +79,7 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.0-pyh7db6752_0.conda#2ae6c63938d6dd000e940673df75419c https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.1-h694c41f_0.conda#ca641fdf8b7803f4b7212b6d66375930 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_14.conda#c11e0acbe6ba3df9a30dbe7f839cbd99 +https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_15.conda#a089323fefeeaba2ae60e1ccebf86ddc https://conda.anaconda.org/conda-forge/osx-64/pillow-12.0.0-py314hedf0282_2.conda#399177697c7225b64edeaeb373a8c98b https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -87,7 +87,7 @@ https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.13.0-hf0c99ee_4.conda#411 https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.0.2-h2beb688_0.tar.bz2#524282b2c46c9dedf051b3bc2ae05494 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/osx-64/mkl-2023.2.0-h694c41f_50502.conda#0bdfc939c8542e0bc6041cbd9a900219 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/osx-64/ccache-4.11.3-h33566b8_0.conda#b65cad834bd6c1f660c101cca09430bf https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-20_osx64_mkl.conda#160fdc97a51d66d51dc782fb67d35205 https://conda.anaconda.org/conda-forge/osx-64/mkl-devel-2023.2.0-h694c41f_50502.conda#045f993e4434eaa02518d780fdca34ae @@ -99,7 +99,7 @@ https://conda.anaconda.org/conda-forge/osx-64/liblapacke-3.9.0-20_osx64_mkl.cond https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.5-py314hf08249b_0.conda#5c9e4bc0c170115fd3602d7377c9e8da https://conda.anaconda.org/conda-forge/osx-64/blas-devel-3.9.0-20_osx64_mkl.conda#cc3260179093918b801e373c6e888e02 https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h00ed6fe_3.conda#761aa19f97a0dd5dedb9a0a6003707c1 -https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.3-py314hc4308db_1.conda#21a858b49f91ac1f5a7b8d0ab61f8e7d +https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.3-py314hc4308db_2.conda#b082e18eb2696625aa09c80e0fbd1997 https://conda.anaconda.org/conda-forge/osx-64/scipy-1.16.3-py314h9d854bd_1.conda#017b471251f1d7401ed1dd63370bad2f https://conda.anaconda.org/conda-forge/osx-64/blas-2.120-mkl.conda#b041a7677a412f3d925d8208936cb1e2 https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.8-py314hd47142c_0.conda#91d76a5937b47f7f0894857ce88feb9f diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock index fa1eff93c7b1a..fe44be4c0899f 100644 --- a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock @@ -11,7 +11,8 @@ https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda#58fd217444c2a5701a44244faf518206 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa -https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.6-hf598326_0.conda#3ea79e55a64bff6c3cbd4588c89a527a +https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.7-hf598326_0.conda#0de94f39727c31c0447e408c5a210a56 +https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda#b79875dbb5b1db9a4a22a4520f918e1a https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda#411ff7cd5d1472bba0f55c0faf04453b @@ -22,7 +23,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda#c0d87c3c8e075daf1daf6c31b53e8083 https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda#e5e7d467f80da752be17796b87fe6385 https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda#369964e85dc26bfe78f41399b366c435 -https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.6-h4a912ad_0.conda#4a274d80967416bce3c7d89bf43923ec +https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.7-h4a912ad_0.conda#05d475f50ddcc2173a6beece9960c6cb https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda#068d497125e4bf8a66bf707254fff5ae https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda#415816daf82e0b23a736a069a75e9da7 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda#78b548eed8227a689f93775d5d23ae09 @@ -35,8 +36,8 @@ https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda#a74 https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20250512.1-cxx17_hd41c47c_0.conda#360dbb413ee2c170a0a684a33c4fc6b8 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda#079e88933963f3f149054eec2c487bc2 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 -https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_1.conda#1399af81db60d441e7c6577307d5cf82 -https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.51-hfab5511_0.conda#06efb9eace7676738ced2f9661c59fb8 +https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef +https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.53-hfab5511_0.conda#62b6111feeffe607c3ecc8ca5bd1514b https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.1-h9a5124b_0.conda#67e50e5bd4e5e2310d66b88c4da50096 https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h8eac4d7_0.conda#cf7291a970b93fe3bb726879f2037af8 @@ -48,33 +49,33 @@ https://conda.anaconda.org/conda-forge/osx-arm64/sleef-3.9.0-hb028509_0.conda#68 https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_0.conda#347261d575a245cb6111fb2cb5a79fc7 https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_3.conda#a73d54a5abba6543cb2f0af1bfbd6851 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda#e3170d898ca6cb48f1bb567afb92f775 -https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.1-h3470cca_0.conda#30c613d957b652b9604c5eaf8532562d -https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hd0aec43_4.conda#93345396269a7f456f2e80de6bda540d +https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.2-h248ca61_0.conda#c2a30a3b30cf86ef97ec880d53a6571a +https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda#6d4ede03e2a8e20eb51f7f681d2a2550 -https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_14.conda#1b3fb17dd26afdafe0bf30fafcb900a2 +https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_15.conda#9633bbd83cdc75ca0d325bf26fa32375 https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.31.1-h658db43_2.conda#155d3d17eaaf49ddddfe6c73842bc671 https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-hba2cd1d_0.conda#a53d5f7fff38853ddb6bdc8fb609c039 https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.1-hb693164_3.conda#4e4ea852d54cc2b869842de5044662fb -https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.9-hfc2f54d_101_cp313.conda#a4241bce59eecc74d4d2396e108c93b8 +https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.11-hfc2f54d_100_cp313.conda#18a8c69608151098a8fb75eea64cc266 https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-0.1.3-h44b9a77_0.tar.bz2#4a2cac04f86a4540b8c9b8d8f597848f https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda#48ece20aa479be6ac9a284772827d00c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.9-py313hd8ed1ab_101.conda#367133808e89325690562099851529c8 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.2-py313h66a7184_0.conda#e5fd9ec2e9f89306a3f48302b29df4e1 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda#66b8b26023b8efdf8fcb23bac4b6325d -https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.10.0-pyhd8ed1ab_0.conda#d18004c37182f83b9818b714825a7627 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.12.0-pyhd8ed1ab_0.conda#a3b9510e2491c20c7fc0f5e730227fbb https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py313h7add70c_2.conda#9583687276aaa393e723f3b7970be69f https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda#92a61fd30b19ebd5c1621a5bfe6d8b5f https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda#f35fb38e89e2776994131fbf961fa44b -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_14.conda#4fa9de90ec33234997aed5871d20f14e +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_15.conda#75737d092770ee4695e13f6b181bdbd2 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h7d74516_0.conda#3df5979cc0b761dda0053ffdb0bca3ea -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.3.1-h8f1351a_1.conda#a5635df796b71f6ca400fc7026f50701 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 @@ -82,7 +83,7 @@ https://conda.anaconda.org/conda-forge/noarch/networkx-3.6-pyhcf101f3_0.conda#67 https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hbfb3c88_0.conda#6bf3d24692c157a41c01ce0bd17daeea https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 @@ -104,7 +105,7 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_h6922315_1.conda#66697cc97d32afa29c17855b3d56680e https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_h73dfc95_5.conda#0b1110de04b80ea62e93fef6f8056fbb -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_14.conda#3187356c87594c3ebc3b8c0bd72a7e9f +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_15.conda#5c9f004d0b98ce792a022f1095d1b338 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.0.0-py313ha86496b_2.conda#d52bb6207093e90d6b70649728257e3f https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff @@ -113,46 +114,46 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_h73dfc95_5.conda#561b822bdb2c1bb41e16e59a090f1e36 https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_1.conda#3a3ff7c8991ea2807eb13425733491c2 -https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-2_h8d724d3_accelerate.conda#143e99fafc3cdd43c917ff8183f6a219 +https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-4_h8d724d3_accelerate.conda#2a826a3c1c83fe42be22ee4efddfe597 https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.0.2-hbec66e7_0.tar.bz2#37ca71a16015b17397da4a5e6883f66f https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.18.0-py313ha61f8ec_0.conda#08c825d0a6cde154eb8c4729563114e7 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.11.3-hd7c7cec_0.conda#7fe1ee81492f43731ea583b4bee50b8b https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_h8c76c84_1.conda#296de61644a3372f5cf13f266eb6ad88 https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_5.conda#6773a2b7d7d1b0a8d0e0f3bf4e928936 -https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-2_h752f6bc_accelerate.conda#e0e6e7e33c7bc6b61471ee1014b7d4a9 -https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-2_hcb0d94e_accelerate.conda#cc5238dd60dec488f46a164cdba0a0f5 +https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-4_h752f6bc_accelerate.conda#e296bcad6b433ca2c30cee42fd43603a +https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-4_hcb0d94e_accelerate.conda#4285e49fbda8dc95c699f71ccc1527ac https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_1.conda#4df7fec2dac84a966f9de8addd561561 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_1.conda#e9d1109b5313ca4969210c3bedec6f0b https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_h36137df_5.conda#c11a3a5a0cdb74d8ce58c6eac8d1f662 https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda#8d99c82e0f5fed6cc36fcf66a11e03f0 -https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-2_hbdd07e9_accelerate.conda#790ab9dc92e3f2374a848a27d3ea3be1 -https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.9.1-cpu_generic_h040b7fb_0.conda#73bf235baaa1d1528f8f48bbbdfde1a3 +https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-4_hbdd07e9_accelerate.conda#14bf7f811c9e1b7c4af5387d4878ebbf +https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.9.1-cpu_generic_h040b7fb_1.conda#4d3dbf224d7d41e146777ae04c05ecc0 https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.3.5-py313h9771d21_0.conda#3f8330206033158d3e443120500af416 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 -https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-2_h55bc449_accelerate.conda#a9d1c17bf0b35053727c05235be9b7ba +https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-4_h55bc449_accelerate.conda#cc98d2287a45077d377bdaf45bf27069 https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313ha61f8ec_3.conda#5643cff3e9ab77999fba139465156e35 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_impl_osx-arm64-14.3.0-h6d03799_1.conda#1e9ec88ecc684d92644a45c6df2399d0 -https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.3-py313h7d16b84_1.conda#5ddddcc319d3aee21cc4fe4640a61f8a -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.9.1-cpu_generic_py313_h6bf06e3_0.conda#5d3ce52595cf76e7352aee892ace4a6c +https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.3-py313h7d16b84_2.conda#03771a1c710d15974372ae791811bcde +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.9.1-cpu_generic_py313_h6bf06e3_1.conda#b47dd1b58e9c6aa7b45239f7902b1243 https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.16.3-py313h0d10b07_1.conda#55c947938346fb644c2752383c40f935 -https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.302-accelerate.conda#cce50d5ad6fc1de3752d42d71af96b6c -https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-h76e6a08_26.conda#f872a20e3b1d19aa054f113ae3804372 +https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.304-accelerate.conda#6515d85975013b221a4b97bb96540f5d +https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-h76e6a08_27.conda#2fb912af00fa523f5968855053bebd13 https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py313h58042b9_0.conda#745c18472bc6d3dc9146c3dec18bb740 https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py313h28ea3aa_1.conda#51a353d043e612a8f520627cf0e73653 -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.9.1-cpu_generic_hcc7c195_0.conda#317359fedeb03a60ac1831166eff601d -https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h07b0088_26.conda#bae6f596e3ce534c6a23922711510228 +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.9.1-cpu_generic_hcc7c195_1.conda#139bf77a4b1174e2e30c7d884fb160c8 +https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h07b0088_27.conda#0c9ac1e5d33185824ced44ce0aeab0b2 https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py313h39782a4_0.conda#bae471007cbebf097a19e851c219d56a https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda#148516e0c9edf4e9331a4d53ae806a9b -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-h276745f_26.conda#7654ab743ef26bf8018f510f918665d4 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-h276745f_27.conda#834e2e73c7a45604603b5e586f53a377 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_osx-arm64-14.3.0-h3c33bd0_0.conda#8db8c0061c0f3701444b7b9cc9966511 -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h07b0088_26.conda#51cfb178328f60dbaad16fa06b0f20c2 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h07b0088_27.conda#de5434190db50b34f78341ae3c58cb1b https://conda.anaconda.org/conda-forge/osx-arm64/gfortran-14.3.0-h3ef1dbf_0.conda#e148e0bc9bbc90b6325a479a5501786d https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda#043afed05ca5a0f2c18252ae4378bdee https://conda.anaconda.org/conda-forge/osx-arm64/fortran-compiler-1.11.0-h81a4f41_0.conda#d221c62af175b83186f96d8b0880bff6 diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index 319d62e6fda92..9872a43eb2915 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -6,31 +6,31 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.9-hc97d973_101_cp313.conda#4780fe896e961722d0623fa91d0d3378 +https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b @@ -49,7 +49,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip joblib @ https://files.pythonhosted.org/packages/1e/e8/685f47e0d754320684db4425a0967f7d3fa70126bffd76110b7009a0090f/joblib-1.5.2-py3-none-any.whl#sha256=4e1f0bdbb987e6d843c70cf43714cb276623def372df3c22fe5266b2670bc241 # pip kiwisolver @ https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 -# pip meson @ https://files.pythonhosted.org/packages/9c/07/b48592d325cb86682829f05216e4efb2dc881762b8f1bafb48b57442307a/meson-1.9.1-py3-none-any.whl#sha256=f824ab770c041a202f532f69e114c971918ed2daff7ea56583d80642564598d0 +# pip meson @ https://files.pythonhosted.org/packages/d7/ab/115470e7c6dcce024e43e2e00986864c56e48c59554bb19f4b02ed72814c/meson-1.9.2-py3-none-any.whl#sha256=1a284dc1912929098a6462401af58dc49ae3f324e94814a38a8f1020cee07cba # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip numpy @ https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017 # pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 @@ -70,12 +70,12 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip tabulate @ https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl#sha256=024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb # pip tzdata @ https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl#sha256=1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 -# pip urllib3 @ https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl#sha256=e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc +# pip urllib3 @ https://files.pythonhosted.org/packages/56/1a/9ffe814d317c5224166b23e7c47f606d6e473712a2fad0f704ea9b99f246/urllib3-2.6.0-py3-none-any.whl#sha256=c90f7a39f716c572c4e3e58509581ebd83f9b59cced005b7db7ad2d22b0db99f # pip array-api-strict @ https://files.pythonhosted.org/packages/e1/7b/81bef4348db9705d829c58b9e563c78eddca24438f1ce1108d709e6eed55/array_api_strict-2.4.1-py3-none-any.whl#sha256=22198ceb47cd3d9c0534c50650d265848d0da6ff71707171215e6678ce811ca5 # pip contourpy @ https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/c0/57/e69a1de45ec7a99a707e9f1a5defa035a48de0cae2d8582451c72d2db456/pyproject_metadata-0.10.0-py3-none-any.whl#sha256=b1e439a9f7560f9792ee5975dcf5e89d2510b1fc84a922d7e5d665aa9102d966 -# pip pytest @ https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl#sha256=67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad +# pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 # pip scipy @ https://files.pythonhosted.org/packages/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=7dc1360c06535ea6116a2220f760ae572db9f661aba2d88074fe30ec2aa1ff88 @@ -87,5 +87,5 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 # pip scipy-doctest @ https://files.pythonhosted.org/packages/f5/99/a17f725f45e57efcf5a84494687bba7176e0b5cba7ca0f69161a063fa86d/scipy_doctest-2.0.1-py3-none-any.whl#sha256=7725b1cb5f4722ab2a77b39f0aadd39726266e682b19e40f96663d7afb2d46b1 -# pip sphinx @ https://files.pythonhosted.org/packages/fe/8b/76e2a1ce12b915399365873eef2b1197da9d032c99e661a71fd7e1490333/sphinx-9.0.0-py3-none-any.whl#sha256=3442bf635d378da2ba4e88aa8496f3a61b2d59ef145aeaf34353ab93fd79f1bf +# pip sphinx @ https://files.pythonhosted.org/packages/c6/3f/4bbd76424c393caead2e1eb89777f575dee5c8653e2d4b6afd7a564f5974/sphinx-9.0.4-py3-none-any.whl#sha256=5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb # pip numpydoc @ https://files.pythonhosted.org/packages/6c/45/56d99ba9366476cd8548527667f01869279cedb9e66b28eb4dfb27701679/numpydoc-1.8.0-py3-none-any.whl#sha256=72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541 diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index ed5d6b562fb93..e94fdf6ae3dec 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -11,12 +11,12 @@ https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.6-h4922eb0_0.conda#7a0b9ce502e0ed62195e02891dfcd704 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.7-h4922eb0_0.conda#ec29f865968a81e1961b3c2f2765eebb https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc @@ -25,8 +25,8 @@ https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc @@ -36,9 +36,9 @@ https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb9d3cd8_3.conda# https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda#b64523fb87ac6f87f0790f324ad43046 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -62,11 +62,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.25.1-h3f43e3d_1.conda#2f4de899028319b27eb7a4023be5dfd2 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -80,8 +80,8 @@ https://conda.anaconda.org/conda-forge/linux-64/s2n-1.3.46-h06160fa_0.conda#413d https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda#580a52a05f5be28ce00764149017c6d4 https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 @@ -97,7 +97,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.co https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.25.1-h3f43e3d_1.conda#3f7a43b3160ec0345c9535a9f0d7908e -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h6548e54_1.conda#f01292fb36b6d00d5c51e5d46b513bcf https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 @@ -160,14 +160,14 @@ https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda#e https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda#5c7a868f8241e64e1cf5fdf4962f23e2 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 @@ -197,10 +197,10 @@ https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc4 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.7-hf7376ad_0.conda#27dc1a582b442f24979f2a28641fe478 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda#ef1910918dd895516a769ed36b5b3a4e -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -208,14 +208,14 @@ https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_1.conda#d3042ebdaacc689fd1daa701885fc96c +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_1.conda#66508e5f84c3dc9af1a0a62694325ef2 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.20.2-h2a5cb19_18.conda#7313674073496cec938f73b71163bc31 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-20_linux64_openblas.conda#9932a1d4e9ecf2d35fb19475446e361e diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 58890b5886d00..f0adc2af81009 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -6,20 +6,20 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -28,91 +28,89 @@ https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002. https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h4a7cf45_openblas.conda#6146bf1b7f58113d54614c6ec683c14a +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-4_h4a7cf45_openblas.conda#14ff9fdfbd8bd590fca383b995470711 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a +https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.2.0-py311h6b1f9c4_0.conda#596b9cc36b7af0640825b399e6b11ccc https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py311h0daaf2c_0.conda#93f275715239f0ad95343a75fb15dbd7 -https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc +https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.3-pyhd8ed1ab_0.conda#abbe8c85619c87c4f4f61b44173434af https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_h0358290_openblas.conda#a84b2b7ed34206d14739fb8d29cd2799 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h47877c9_openblas.conda#9fb20e74a7436dc94dd39d9a9decddc3 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-4_h0358290_openblas.conda#25f5e5af61cee1ffedd9b4c9947d3af8 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-4_h47877c9_openblas.conda#8ba8431802764597f400ee3e99026367 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 -https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda#5f0f24f8032c2c1bb33f59b75974f5fc +https://conda.anaconda.org/conda-forge/noarch/roman-numerals-3.1.0-pyhd8ed1ab_0.conda#b272e95116c1449e584fb397e12bc3db https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb -https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_2.conda#959484a66b4b76befcddc4fa97c95567 +https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhcf101f3_3.conda#de98449f11d48d4b52eefb354e2bfe35 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 -https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_h6ae95b6_openblas.conda#35d16498d50b73886cb30014c2741726 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-4_h6ae95b6_openblas.conda#91ee3fce1a4fb8495b9aa110de74d926 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py311h2e04523_0.conda#01da92ddaf561cabebd06019ae521510 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-2_h1ea3ea9_openblas.conda#7cee1860b6bf5a1deb8a62a6b2dfcfbd +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-4_h1ea3ea9_openblas.conda#b94457a746ba3bba8cc39881a18d6d41 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_1.conda#72e3452bf0ff08132e86de0272f2fbb0 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311h1e13796_1.conda#e1947291b713cb0afa949e1bcda1f935 -https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.302-openblas.conda#fa34398c7f1c68bec5f00b0a841d2d05 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.0-pyhd8ed1ab_0.conda#de7372f43e63ff0876b4023b79b55e95 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.304-openblas.conda#9f3df6e080be9558b0eced56c01b1ce5 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda#5af206d64d18d6c8dfb3122b4d9e643b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda#16e3f039c0aa6446513e94ab18a8784b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda#910f28a05c178feba832f842155cbfff https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_1.conda#e9fb3fe8a5b758b4aff187d434f94f03 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_1.conda#00534ebcc0375929b45c3039b5ba7636 -https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda#f7af826063ed569bb13f7207d6f949b0 +https://conda.anaconda.org/conda-forge/noarch/sphinx-9.0.4-pyhd8ed1ab_0.conda#950eae33376107d143a529d48c363832 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda#3bc61f7161d28137797e038263c04c54 diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock index 797799b84cad9..f510d9a52f8a8 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock @@ -14,7 +14,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda#8a86073cf3b343b87d03f41790d8b4e5 https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda#58f67b437acbf2764317ba273d731f1d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_14.conda#c21643058895b399fd413e6ba17f587f +https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_15.conda#18713a6d90ce576053ac3ce9f792fe14 https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda#378d5dcec45eaea8d303da6f00447ac0 https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda#37e16618af5c4851a3f3d66dd0e11141 https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_32.conda#ef02bbe151253a72b8eda264a935db66 @@ -27,7 +27,7 @@ https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.c https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda#8c9e4f1a0e688eef2e95711178061a0f https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda#ba4ad812d2afc22b9a34ce8327a0930f -https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_14.conda#b39b17a9f5ec5f3a395dbf0f5ee13b66 +https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_15.conda#e05ab7ace69b10ae32f8a710a5971f4f https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#64571d1dd6cdcfa25d0664a5950fdaa2 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda#56a686f92ac0273c0f6af58858a3f013 https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda#c15148b2e18da456f5108ccb5e411446 @@ -41,13 +41,13 @@ https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda#84f https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda#08c8fa3b419df480d985e304f7884d35 https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda#854fbdff64b572b5c0b470f334d34c11 https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_3.conda#7cb36e506a7dba4817970f8adb6396f9 -https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.1-h32d8bfd_0.conda#de8426202e7a7de6cc431835224f7551 +https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.2-h5112557_0.conda#2b4f8712b09b5fd3182cda872ce8482c https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda#31aec030344e962fbd7dbbbbd68e60a9 -https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-2_h0adab6e_openblas.conda#95fa206f4ffdc2993fa6a48b07b4c77d +https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-4_h0adab6e_openblas.conda#1e44e1899ea86037873e65de3f5c19c5 https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda#450e3ae947fc46b60f1d8f8f318b40d4 https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda#ccd93cfa8e54fd9df4e83dbe55ff6e8c https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda#2cf0cf76cc15d360dfa2f17fd6cf9772 -https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.51-h7351971_0.conda#5b98079b7e86c25c7e70ed7fd7da7da5 +https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.53-h7351971_0.conda#fb6f43f6f08ca100cb24cff125ab0d9e https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h06f855e_0.conda#4a5ea6ec2055ab0dfd09fd0c498f834a https://conda.anaconda.org/conda-forge/win-64/openblas-0.3.30-pthreads_h4a7f399_4.conda#482e61f83248a880d180629bf8ed36b2 https://conda.anaconda.org/conda-forge/win-64/pcre2-10.46-h3402e2f_0.conda#889053e920d15353c2665fa6310d7a7a @@ -55,7 +55,7 @@ https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.co https://conda.anaconda.org/conda-forge/win-64/python-3.11.14-h0159041_2_cpython.conda#02a9ba5950d8b78e6c9862d6ba7a5045 https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda#8436cab9a76015dfe7208d3c9f97c156 https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda#a7c03e38aa9c0e84d41881b9236eacfb -https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h1b5488d_4.conda#4fcccc053a113f5711dddf64401e9010 +https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda#053b84beec00b71ea8ff7a4f84b55207 https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hfd05255_1.conda#6abd7089eb3f0c790235fe469558d190 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -63,18 +63,18 @@ https://conda.anaconda.org/conda-forge/win-64/cython-3.2.2-py311h9990397_0.conda https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py311h275cad7_2.conda#e9eb24a8d111be48179bf82a9e0e13ca -https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-2_h2a8eebe_openblas.conda#ffc9f6913d7436e558b9d85a1c380591 -https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.6-default_ha2db4b5_0.conda#32b0f9f52f859396db50d738d50b4a82 +https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-4_h2a8eebe_openblas.conda#464b3434e245c2967c0e226f1611f6f9 +https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.7-default_ha2db4b5_1.conda#065bcc5d1a29de06d4566b7b9ac89882 https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda#6e7c5c5ab485057b5d07fd8188ba5c28 https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.2-hd9c3897_0.conda#fbd144e60009d93f129f0014a76512d3 -https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-2_hd232482_openblas.conda#b42a971e4cef38ee91a7a42cdb224be4 +https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-4_hd232482_openblas.conda#808ae0372f0b1495c41a1ce2064f291f https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-ha29bfb0_0.conda#87116b9de9c1825c3fd4ef92c984877b -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e @@ -92,22 +92,22 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda#3538827f77b82a837fa681a4579e37a1 https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda#3235024fe48d4087721797ebd6c9d28c -https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-2_hbb0e6ff_openblas.conda#d0bc7a5338ff7d95e210a3f7e1264ed9 +https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-4_hbb0e6ff_openblas.conda#cf28f3b4945a9b76dbb64c60d534d7b7 https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 https://conda.anaconda.org/conda-forge/win-64/numpy-2.3.5-py311h80b3fa1_0.conda#1e0fb210584b09130000c4404b77f0f6 https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h24db6dd_0.conda#5af852046226bb3cb15c7f61c2ac020a https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-2_ha590de0_openblas.conda#2faff8da7caa95fedbebd4029c815910 +https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-4_ha590de0_openblas.conda#e3e893858dd88ee0351f1a5b9cb140f3 https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h3fd045d_3.conda#5e7e380c470e9f4683b3129fedafbcdf https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.0-py311h3f79411_0.conda#448f4a9f042eec9a840e3a0090e9a6d8 https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda#d69c21967f35eb2ce7f1f85d6b6022d3 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/win-64/pillow-12.0.0-py311h17b8079_2.conda#a80f6ec79f4ea2bf7572f4f8e8b467f7 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/win-64/scipy-1.16.3-py311hf127856_1.conda#48d562b3a3fb120d7c3f5e6af6d4b3e9 -https://conda.anaconda.org/conda-forge/win-64/blas-2.302-openblas.conda#9a3d6e4359ba0ce36b6dea7b6c32bd94 +https://conda.anaconda.org/conda-forge/win-64/blas-2.304-openblas.conda#a17d4405929291b138f4fb3068b44b2a https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.15.0-h765892d_1.conda#9bb0026a2131b09404c59c4290c697cd https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d diff --git a/build_tools/azure/ubuntu_atlas_lock.txt b/build_tools/azure/ubuntu_atlas_lock.txt index 6db4c2cd12771..b7e46d69c03b0 100644 --- a/build_tools/azure/ubuntu_atlas_lock.txt +++ b/build_tools/azure/ubuntu_atlas_lock.txt @@ -12,7 +12,7 @@ iniconfig==2.3.0 # via pytest joblib==1.3.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt -meson==1.9.1 +meson==1.9.2 # via meson-python meson-python==0.18.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt @@ -29,7 +29,7 @@ pygments==2.19.2 # via pytest pyproject-metadata==0.10.0 # via meson-python -pytest==9.0.1 +pytest==9.0.2 # via # -r build_tools/azure/ubuntu_atlas_requirements.txt # pytest-xdist diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index c037ab9ddde16..5776d859d9d67 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -2,27 +2,26 @@ # platform: linux-64 # input_hash: ca6b5567d8c939295b5b4408ecaa611380022818d7f626c2732e529c500271e7 @EXPLICIT +https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_8.conda#ff007ab0f0fdc53d245972bba8a6d40c -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_462.conda#0ec3505e9b16acc124d1ec6e5ae8207c https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_114.conda#5addcb22be964dc0df75bbd4649fee59 +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_115.conda#eedcd688f597873e1d16f0529f4d6d10 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_114.conda#c88929e13f56dac9233cdf615502e5f3 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.6-h4922eb0_0.conda#7a0b9ce502e0ed62195e02891dfcd704 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_115.conda#1ef1a0376c610365eb26e67f5da5e48d https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_8.conda#1bad93f0aa428d618875ef3a588a889e -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 @@ -30,16 +29,16 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -61,13 +60,13 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_14.conda#b1b15da9757caaa0814d7dc3112b3e06 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_15.conda#9e82f96224931323c6ed53d88fb3241b https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda#a587892d3c13b6621a6091be690dbca2 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -81,8 +80,8 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.con https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_3.conda#03b04e4effefa41aee638f8ba30a6e78 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 @@ -95,6 +94,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hb https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_5.conda#82954a6f42e3fba59628741dca105c98 +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 @@ -109,10 +109,12 @@ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.con https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h6395336_2.conda#c09c4ac973f7992ba0c6bb1aafd77bd4 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-4_h4a7cf45_openblas.conda#14ff9fdfbd8bd590fca383b995470711 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 +https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 @@ -122,7 +124,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0. https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda#8035e5b54c08429354d5d64027041cad https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a -https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyh71513ae_0.conda#c7944d55af26b6d2d7629e27e9a972c1 +https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda#537296d57ea995666c68c821b00e360b +https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.2.0-py311h6b1f9c4_0.conda#596b9cc36b7af0640825b399e6b11ccc https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-default_h4852527_104.conda#d351e4894d6c4d9d8775bf169a97089d https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-default_h4852527_104.conda#e30e71d685e23cc1e5ac1c1990ba1f81 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 @@ -139,31 +142,33 @@ https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar. https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h442bea5_14.conda#e6b9e795d27f9f524c67ad8803157056 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h319ec69_15.conda#042695cf5fb55a63294f3575c33a468c https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/noarch/json5-0.12.1-pyhd8ed1ab_0.conda#0fc93f473c31a2f85c0bde213e7c63ca -https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-3.0.0-py311h38be061_2.conda#5dd29601defbcc14ac6953d9504a80a7 +https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda#cd2214824e36b0180141d422aba01938 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b965c999135d43a3d0f7bd7d024e26a +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-4_h0358290_openblas.conda#25f5e5af61cee1ffedd9b4c9947d3af8 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-4_h47877c9_openblas.conda#8ba8431802764597f400ee3e99026367 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.12.0-pyhcf101f3_0.conda#02cab382663872083b7e8675f09d9c21 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.13.0-pyhcf101f3_0.conda#0129bb97a81c2ca0f57031673424387a https://conda.anaconda.org/conda-forge/noarch/networkx-3.6-pyhcf101f3_0.conda#6725bfdf8ea7a8bf6415f096f3f1ffa5 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda#5c7a868f8241e64e1cf5fdf4962f23e2 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.23.1-pyhd8ed1ab_0.conda#a1e91db2d17fd258c64921cb38e6745a https://conda.anaconda.org/conda-forge/linux-64/psutil-7.1.3-py311haee01d2_0.conda#2092b7977bc8e05eb17a1048724593a4 https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda#7d9daffbb8d8e0af0f769dbbcd173a54 @@ -186,7 +191,7 @@ https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda#18c019ccf43769d211f2cf78e9ad46c2 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb -https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhd8ed1ab_2.conda#959484a66b4b76befcddc4fa97c95567 +https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhcf101f3_3.conda#de98449f11d48d4b52eefb354e2bfe35 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py311h49ec1c0_2.conda#8d7a63fc9653ed0bdc253a51d9a5c371 @@ -212,13 +217,13 @@ https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_0.conda#b1a27250d70881943cca0dd6b4ba0956 https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_15.conda#93b9b94788b52e6f79cf6ae88de40c76 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py311h3778330_0.conda#f5ee391df23b7f50676ebe79fc53ee03 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h6f77f03_14.conda#39ad5dd223e52cd1d52486913aec8539 https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_14.conda#fe0c2ac970a0b10835f3432a3dfd4542 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_14.conda#4f780ca1ee70dee1c9acbe1932305cb2 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_14.conda#54ae44a161f3e492c654582c5fc47537 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_15.conda#d10648cffe3cdacded77f7fdeacfb8f0 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_15.conda#a27be47954f8b96b0e4c383632bc80f9 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 @@ -226,15 +231,16 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h7f8ec31_1002.conda#c01021ae525a76fe62720c7346212d74 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-4_h6ae95b6_openblas.conda#91ee3fce1a4fb8495b9aa110de74d926 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.7-hf7376ad_0.conda#27dc1a582b442f24979f2a28641fe478 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 -https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhd8ed1ab_1.conda#71abbefb6f3b95e1668cd5e0af3affb9 +https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda#f5a4d548d1d3bdd517260409fc21e205 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py311h2e04523_0.conda#01da92ddaf561cabebd06019ae521510 https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.0-pyhd8ed1ab_0.conda#6d4c79b604d50c1140c32164f7eca72a @@ -245,7 +251,7 @@ https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.co https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda#efba281bbdae5f6b0a1d53c6d4a97c93 -https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.5.0-pyhcf101f3_0.conda#2caf483992d5d92b232451f843bdc8af +https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.5.1-pyhcf101f3_0.conda#c0d0b883e97906f7524e2aac94be0e0d https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f @@ -253,83 +259,75 @@ https://conda.anaconda.org/conda-forge/noarch/anyio-4.12.0-pyhcf101f3_0.conda#99 https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda#6e36e9d2b535c3fbe2e093108df26695 https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda#85c4f19f377424eafc4ed7911b291642 https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-4_h1ea3ea9_openblas.conda#b94457a746ba3bba8cc39881a18d6d41 https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-h5f6438b_0.conda#08a03378bc5293c6f97637323802f480 -https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311hdf67eae_3.conda#c4e2f4d5193e55a70bb67a2aa07006ae https://conda.anaconda.org/conda-forge/noarch/doit-0.36.0-pyhd8ed1ab_1.conda#18d4243b3d30352f9dea8e522f6ff4d1 https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_14.conda#8b9b800bc6424c356a460f90f2a997ad +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_15.conda#893d79ba69d21198012ff8212a8c563a https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h1e4d427_14.conda#5d81121caf70d8799d90dabbf98e5d3d -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_14.conda#9b11172adc0436dafda8875cd2adee00 -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-hc876b51_14.conda#1852de0052b0d6af4294b3ae25a4a450 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-hcfe7c2f_14.conda#c4fd428cfc444609ff7dbceed7f9b3ef +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2025.11.11-py311hd2c663a_1.conda#6cbb8004493da9989e6c94c36151e4c3 +https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda#4ebae00eae9705b0c3d6d1018a81d047 https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_1.conda#2d983ff1b82a1ccb6f2e9d8784bdd6bd https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_1.conda#d3042ebdaacc689fd1daa701885fc96c +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_1.conda#66508e5f84c3dc9af1a0a62694325ef2 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd -https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 +https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c +https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.9.0-py311h0372a8f_2.conda#4e078a6bafb23473ea476450f45c9650 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311h1e13796_1.conda#e1947291b713cb0afa949e1bcda1f935 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.0-pyhd8ed1ab_0.conda#de7372f43e63ff0876b4023b79b55e95 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b -https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 -https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f +https://conda.anaconda.org/conda-forge/linux-64/blas-2.304-openblas.conda#9f3df6e080be9558b0eced56c01b1ce5 +https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_15.conda#2cad53f60b22fba4693d6c67ee8e0cb7 +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_15.conda#0b1faa0b6a877261a8b4ec692d41b7c4 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.25.1-pyhe01879c_0.conda#341fd940c242cf33e832c0402face56f https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.0-pyhcf101f3_0.conda#4797b73e8813dce0afe8c96839118294 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 +https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 +https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.10.16-pyhd8ed1ab_0.conda#f5b9f02d19761f79c564900a2a399984 https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a -https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e +https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 +https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.25.1-he01879c_0.conda#13e31c573c884962318a738405ca3487 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.0-pyhcf101f3_0.conda#97624651e6fc9ca05effe0b4a80766e3 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h5875eb1_mkl.conda#6a1a4ec47263069b2dae3cfba106320c -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 +https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_3.conda#d2bbbd293097e664ffb01fc4cdaf5729 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.3-h5c1c036_1.conda#762af6d08fdfa7a45346b1466740bacd -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 +https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.25.2-py311hed34c8f_2.conda#515ec832e4a98828374fded73405e3f3 +https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 +https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda#f56000b36f09ab7533877e695e4e8cb0 https://conda.anaconda.org/conda-forge/noarch/jupytext-1.18.1-pyh80e38bb_0.conda#3c85f79f1debe2d2c82ac08f1c1126e1 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_hfef963f_mkl.conda#62ffd188ee5c953c2d6ac54662c158a7 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h5e43f62_mkl.conda#4f33d79eda3c82c95a54e8c2981adddb https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda#6bb0d77277061742744176ab555b723c -https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_3.conda#d2bbbd293097e664ffb01fc4cdaf5729 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.3-py311he4c1a5a_1.conda#8c769099c0729ff85aac64f566bcd0d7 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_hdba1596_mkl.conda#96dea51ff1435bd823020e25fd02da59 +https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda#cfc86ccc3b1de35d36ccaae4c50391f5 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py311h2e04523_0.conda#01da92ddaf561cabebd06019ae521510 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-2_hcf00494_mkl.conda#77b464e7c3b853268dec4c82b21dca5a -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311hdf67eae_3.conda#c4e2f4d5193e55a70bb67a2aa07006ae -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2025.11.11-py311hd2c663a_1.conda#6cbb8004493da9989e6c94c36151e4c3 -https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda#d79a87dcfa726bcea8e61275feed6f83 -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_1.conda#72e3452bf0ff08132e86de0272f2fbb0 -https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 -https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.9.0-py311h0372a8f_2.conda#4e078a6bafb23473ea476450f45c9650 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311h1e13796_1.conda#e1947291b713cb0afa949e1bcda1f935 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.302-mkl.conda#9c83adee9e1069446e6cc92b8ea19797 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 -https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 -https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.5-py311h0372a8f_1.conda#9db66ee103839915d80e7573b522d084 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.10.16-pyhd8ed1ab_0.conda#f5b9f02d19761f79c564900a2a399984 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 -https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.25.2-py311hed34c8f_2.conda#515ec832e4a98828374fded73405e3f3 -https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 -https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.0-pyhcf101f3_1.conda#e53b79419913df0b84f7c3af7727122b https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda#5af206d64d18d6c8dfb3122b4d9e643b https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda#837aaf71ddf3b27acae0e7e9015eebc6 https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda#bf22cb9c439572760316ce0748af3713 https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.6.1-pyhd8ed1ab_2.conda#3e6c15d914b03f83fc96344f917e0838 -https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.19.0-pyhd8ed1ab_0.conda#3cfa26d23bd7987d84051879f202a855 +https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.20.0-pyhd8ed1ab_0.conda#4cae490c8d142824fb80d9aed672fddd https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.10.1-pyhd8ed1ab_0.conda#bfc047865de18ef2657bd8a95d7b8b49 https://conda.anaconda.org/conda-forge/noarch/sphinx-remove-toctrees-1.0.0.post1-pyhd8ed1ab_1.conda#b275c865b753413caaa8548b9d44c024 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda#16e3f039c0aa6446513e94ab18a8784b diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 91086e030f897..997e3d4c0d8a6 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -12,17 +12,17 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_114.conda#5addcb22be964dc0df75bbd4649fee59 +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_115.conda#eedcd688f597873e1d16f0529f4d6d10 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_114.conda#c88929e13f56dac9233cdf615502e5f3 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.6-h4922eb0_0.conda#7a0b9ce502e0ed62195e02891dfcd704 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_115.conda#1ef1a0376c610365eb26e67f5da5e48d +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.7-h4922eb0_0.conda#ec29f865968a81e1961b3c2f2765eebb https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_8.conda#1bad93f0aa428d618875ef3a588a889e https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc @@ -31,8 +31,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc @@ -41,8 +41,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda#b64523fb87ac6f87f0790f324ad43046 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -69,12 +69,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.25.1-h3f43e3d_1.conda#2f4de899028319b27eb7a4023be5dfd2 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.51-h421ea60_0.conda#d8b81203d08435eb999baa249427884e -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_14.conda#b1b15da9757caaa0814d7dc3112b3e06 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_15.conda#9e82f96224931323c6ed53d88fb3241b https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -90,8 +90,8 @@ https://conda.anaconda.org/conda-forge/linux-64/svt-av1-3.1.2-hecca717_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_3.conda#03b04e4effefa41aee638f8ba30a6e78 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.1-hde8ca8f_0.conda#49c832bff803d95a56190e7992b4b230 -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 @@ -104,7 +104,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hb https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.25.1-h3f43e3d_1.conda#fd9cf4a11d07f0ef3e44fc061611b1ed https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.25.1-h3f43e3d_1.conda#3f7a43b3160ec0345c9535a9f0d7908e -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h6548e54_1.conda#f01292fb36b6d00d5c51e5d46b513bcf https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_5.conda#82954a6f42e3fba59628741dca105c98 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_2.conda#b04e0a2163a72588a40cde1afd6f2d18 @@ -136,6 +136,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda#def531a3ac77b7fb8c21d17bb5d0badb +https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.2.0-py311h6b1f9c4_0.conda#596b9cc36b7af0640825b399e6b11ccc https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-default_h4852527_104.conda#d351e4894d6c4d9d8775bf169a97089d https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-default_h4852527_104.conda#e30e71d685e23cc1e5ac1c1990ba1f81 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 @@ -148,7 +149,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.con https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h442bea5_14.conda#e6b9e795d27f9f524c67ad8803157056 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h319ec69_15.conda#042695cf5fb55a63294f3575c33a468c https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -159,17 +160,16 @@ https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda#e https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.0-pyhcf101f3_0.conda#5c7a868f8241e64e1cf5fdf4962f23e2 -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.1.3-py311haee01d2_0.conda#2092b7977bc8e05eb17a1048724593a4 -https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac @@ -194,26 +194,25 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 -https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_15.conda#93b9b94788b52e6f79cf6ae88de40c76 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py311h3778330_0.conda#f5ee391df23b7f50676ebe79fc53ee03 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h6f77f03_14.conda#39ad5dd223e52cd1d52486913aec8539 https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_14.conda#fe0c2ac970a0b10835f3432a3dfd4542 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_14.conda#4f780ca1ee70dee1c9acbe1932305cb2 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_15.conda#d10648cffe3cdacded77f7fdeacfb8f0 https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.2-h5192d8d_1.conda#7071a9745767777b4be235f8c164ea75 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_14.conda#54ae44a161f3e492c654582c5fc47537 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_15.conda#a27be47954f8b96b0e4c383632bc80f9 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h7f8ec31_1002.conda#c01021ae525a76fe62720c7346212d74 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.6-hf7376ad_0.conda#8aa154f30e0bc616cbde9794710e0be2 +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_hafda6a7_1003.conda#4fe840c6d6b3719b4231ed89d389bb17 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.7-hf7376ad_0.conda#27dc1a582b442f24979f2a28641fe478 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda#ef1910918dd895516a769ed36b5b3a4e -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.0-hca5e8e5_0.conda#aa65b4add9574bb1d23c76560c5efd4c -https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhd8ed1ab_1.conda#71abbefb6f3b95e1668cd5e0af3affb9 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 +https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda#9f6a8664f1fe752f79473eeb9bf33a60 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 @@ -221,44 +220,44 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e -https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_14.conda#8b9b800bc6424c356a460f90f2a997ad +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_15.conda#893d79ba69d21198012ff8212a8c563a https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h1e4d427_14.conda#5d81121caf70d8799d90dabbf98e5d3d https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_14.conda#9b11172adc0436dafda8875cd2adee00 -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-hc876b51_14.conda#1852de0052b0d6af4294b3ae25a4a450 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-hcfe7c2f_14.conda#c4fd428cfc444609ff7dbceed7f9b3ef https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.6-default_h99862b1_0.conda#0fcc9b4d3fc5e5010a7098318d9b7971 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.6-default_h746c552_0.conda#f5b64315835b284c7eb5332202b1e14b +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_1.conda#d3042ebdaacc689fd1daa701885fc96c +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_1.conda#66508e5f84c3dc9af1a0a62694325ef2 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd -https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 -https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 -https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.0-pyhd8ed1ab_0.conda#de7372f43e63ff0876b4023b79b55e95 +https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_15.conda#2cad53f60b22fba4693d6c67ee8e0cb7 https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.11-h651a532_0.conda#d8d8894f8ced2c9be76dc9ad1ae531ce +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_15.conda#0b1faa0b6a877261a8b4ec692d41b7c4 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.4-pyhd8ed1ab_2.conda#bb0230917e2473c77d615104dbe8a49d https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a -https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-2_h5875eb1_mkl.conda#6a1a4ec47263069b2dae3cfba106320c +https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 +https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-4_h5875eb1_mkl.conda#bd1a86e560c3b26961279ef6b6e8d45f https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 -https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h3c3fd16_6.conda#5aab84b9d164509b5bbe3af660518606 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-2_hfef963f_mkl.conda#62ffd188ee5c953c2d6ac54662c158a7 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-2_h5e43f62_mkl.conda#4f33d79eda3c82c95a54e8c2981adddb https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed +https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h3c3fd16_6.conda#5aab84b9d164509b5bbe3af660518606 +https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-4_hfef963f_mkl.conda#41f4f9428b9d92b1b06f1fff80a2674d +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-4_h5e43f62_mkl.conda#f647e3368af2453546812658b5393901 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-2_hdba1596_mkl.conda#96dea51ff1435bd823020e25fd02da59 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-4_hdba1596_mkl.conda#f0b31cc6189ebd85a2e16b15de09850b https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-2_hcf00494_mkl.conda#77b464e7c3b853268dec4c82b21dca5a +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-4_hcf00494_mkl.conda#7f7c616ec25c252749fa4945ea1db3fd https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2025.11.11-py311hd2c663a_1.conda#6cbb8004493da9989e6c94c36151e4c3 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 @@ -267,10 +266,10 @@ https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#867 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.8.0-py311h9f3472d_0.conda#17334e5c12abdf2db6b25bd4187cd3e4 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.302-mkl.conda#9c83adee9e1069446e6cc92b8ea19797 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.304-mkl.conda#adbc1b7f2e7acf80f45bd6592f88f0ae https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b -https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.5-py311h0372a8f_1.conda#9db66ee103839915d80e7573b522d084 +https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.10.16-pyhd8ed1ab_0.conda#f5b9f02d19761f79c564900a2a399984 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.22.0-py311h320fe9a_2.conda#e94b7f09b52628b89e66cdbd8c3029dd diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index e67cb05aa98df..97930fcc38716 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.conda#9e115653741810778c9a915a2f8439e7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_14.conda#f08c95adda42a8f04c2ce888a36be575 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_15.conda#0719da240fd6086c34c4c30080329806 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-2_gnu.tar.bz2#6168d71addc746e8f2b8d57dfd2edcea @@ -16,7 +16,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda#cf105bce884e4ef8c8ccdca9fe6695e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_14.conda#43ff19fcf6f6737770018bb20bb2a9f9 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_15.conda#cfdf8700e69902a113f2611e3cc09b55 https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.14-h86ecc28_0.conda#a696b24c1b473ecc4774bcb5a6ac6337 https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_8.conda#2921ac0b541bf37c69e66bd6d9a43bca https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda#e7df0aab10b9cbb73ab2a467ebfaf8c7 @@ -24,15 +24,15 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda#a9138815598fe6b91a1d6782ca657b0c https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.3-hfae3067_0.conda#b414e36fbb7ca122030276c75fa9c34a https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-hd65408f_0.conda#0c5ad486dcfb188885e3cf8ba209b97b -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_14.conda#acd92c808b9f95f5b28db20054306ba7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_14.conda#a35c50126e425ee8b5bb3e504ed23b8a +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_15.conda#ad92990dc6f608f412a01540a7c9510e +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_15.conda#77fa819fd8e8ae4b54c3fd5c7b666c5b https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda#5a86bf847b9b926f3a4f203339748d78 https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda#5109d7f837a3dfdf5c60f60e311b041f https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.1-h86ecc28_2.conda#7d362346a479256857ab338588190da0 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_14.conda#83f466be64f6bc1f7ece406c009e0586 -https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.2-h3e4203c_0.conda#3a68e44fdf2a2811672520fdd62996bd +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_15.conda#2873f805cdabcf33b880b19077cf6180 +https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.2-h1022ec0_1.conda#15b2cc72b9b05bcb141810b1bada654f https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda#08aad7cbe9f5a6b460d0976076b6ae64 https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda#182afabe009dc78d8b73100255ee6868 @@ -48,11 +48,11 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda#6553a5d017fe14859ea8a4e6ea5def8f https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda#2079727b538f6dd16f3fa579d4c3c53f https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda#fb640d776fc92b682a14e001980825b1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_14.conda#5425a01b852c315ddabc0a3dde6bba0c +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_15.conda#3ec85135541290a2ebd907f1e2d439d3 https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.51-h1abf092_0.conda#913b1a53ee5f71ce323a15593597be0b +https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.53-h1abf092_0.conda#7591d867dbcba9eb7fb5e88a5f756591 https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.1-h022381a_0.conda#233efdd411317d2dc5fde72464b3df7a -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_14.conda#410b06d8a2f7dd0cc1b6acdfbcf101c6 +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_15.conda#7a99de7c14096347968d1fd574b46bb2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda#b4df5d7d4b63579d081fd3a4cf99740e https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda#8b5222a41b5d51fb1a5a2c514e770218 @@ -62,14 +62,14 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.2-h8382b9d_2.con https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h561c983_103.conda#631db4799bc2bfe4daccf80bb3cbc433 https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.24.0-h4f8a99f_1.conda#f6966cb1f000c230359ae98c29e37d87 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda#2d1409c50882819cb1af2de82e2b7208 -https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.1-h92288e7_0.conda#56f8acceedc8c4de5f7a6e1418e74eee -https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-hefd9da6_4.conda#68a63e1ba896c15344e33eacb11e1311 +https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.2-h7ac5ae9_0.conda#a51d8a3d4a928bbfacb9ae37991dde63 +https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 https://conda.anaconda.org/conda-forge/linux-aarch64/icu-75.1-hf9b3779_0.conda#268203e8b983fddb6412b36f2024e75c https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.21.3-h50a48e9_0.conda#29c10432a2ca1472b53f299ffb2ffa37 https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45-default_h1979696_104.conda#28035705fe0c977ea33963489cd008ad https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.1-hdae7a39_0.conda#9c2f56b6e011c6d8010ff43b796aab2f -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-ng-15.2.0-he9431aa_14.conda#640d27c96b59e2af7d440728cbb9e437 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-ng-15.2.0-he9431aa_15.conda#2dfbf3e5dcef40592ea337342a3592e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.2-he84ff74_0.conda#d184d68eaa57125062786e10440ff461 https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d @@ -83,7 +83,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-hd651790_1.con https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.28-h6c5dea3_0.conda#b6d06b46e791add99cc39fbbc34530d5 https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda#a4b6b82427d15f0489cef0df2d82f926 https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.17-hc88f144_0.conda#b87b1abd2542cf65a00ad2e2461a3083 -https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-2_haddc8a3_openblas.conda#1a4b8fba71eb980ac7fb0f2ab86f295d +https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-4_haddc8a3_openblas.conda#10471558ac2b0c1b4dcd5e620fd65bfe https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h5cdc715_5.conda#ac0333d338076ef19170938bbaf97582 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.1-h8af1aa0_0.conda#1e61fb236ccd3d6ccaf9e91cb2d7e12d https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a @@ -105,16 +105,16 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.1-h8af1aa0_0.conda#0c8f36ebd3678eed1685f0fc93fc2175 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.4.9-py311h229e7f7_2.conda#18358d47ebdc1f936003b7d407c9e16f -https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-2_hd72aa62_openblas.conda#a074a14e43abb50d4a38fff28a791259 +https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-4_hd72aa62_openblas.conda#0a9f6e328c9255fd829e5e775bb0696b https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda#0d00176464ebb25af83d40736a2cd3bb -https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-2_h88aeb00_openblas.conda#c73b83da5563196bdfd021579c45d54c +https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-4_h88aeb00_openblas.conda#f4930dcf31fbe6327215b6e6122f73af https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.1-h788dabe_0.conda#a0e7779b7625b88e37df9bd73f0638dc -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.1-pyhcf101f3_0.conda#ef2b132f3e216b5bf6c2f3c36cfd4c89 +https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h30c48ee_0.conda#48f31a61be512ec1929f4b4a9cedf4bd https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.0.0-py311h8e17b9e_2.conda#b86d6e26631d730f43732ade7e510a3f -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhd8ed1ab_0.conda#7da7ccd349dbf6487a7778579d2bb971 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e @@ -138,26 +138,26 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.15.0-h8dda3cd_1.conda#112b71b6af28b47c624bcbeefeea685b https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.0-py311h164a683_0.conda#3c533754d7ceb31f50f1f9bea8f2cb8f https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-2_hb558247_openblas.conda#498aa2a8940c8c26c141dd4ce99e7843 -https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm21-21.1.6-hfd2ba90_0.conda#54e87a913eeaa2b27f2e7b491860f612 +https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-4_hb558247_openblas.conda#447716292a5606947e25f0a8ffda7947 +https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm21-21.1.7-hfd2ba90_0.conda#6627fdee03b7c7d943f70fd74a7c2ab0 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.1-haf03d9f_2.conda#8b0d66c4db91b3ef64daad7f61a569d0 https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.328.1-h8b8848b_0.conda#e5a3ff3a266b68398bd28ed1d4363e65 -https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.0-h3c6a4c8_0.conda#a7c78be36bf59b4ba44ad2f2f8b92b37 +https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.3.5-py311h669026d_0.conda#5ca3db64e7fe0c00685b97104def7953 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 -https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-2_h9678261_openblas.conda#c6f09be2e4ba1626ed277430111cb494 +https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-4_h9678261_openblas.conda#bae5d65bab207969c4c37a1afb149f45 https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h83712da_0.conda#cd55953a67ec727db5dc32b167201aa6 https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311hfca10b7_3.conda#47c305536dbf44cd3e629b6851605a50 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.6-default_he95a3c9_0.conda#6457ea18e8c2a534017aa7c7c88768eb -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.6-default_h94a09a5_0.conda#9cf3f6e2f743eac1cd85b4e9e55ba8a5 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.7-default_he95a3c9_1.conda#6e80b4cf4d469505f168c0a16bb30ed8 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.7-default_h94a09a5_1.conda#d1124b3f50bd5e1b86033033fbd747c6 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.1-pyhcf101f3_0.conda#fa7f71faa234947d9c520f89b4bda1a2 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.16.3-py311h33b5a33_1.conda#3d97f428e5e2f3d0f07f579d97e9fe70 -https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.302-openblas.conda#642f10de8032f498538c64494fcc3db8 +https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.304-openblas.conda#7987a64f37d8c509efc241968771f171 https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-12.2.0-he4899c9_0.conda#1437bf9690976948f90175a65407b65f https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d From e9752287ffffecb2d2878ce1ed97a77a43941579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Tue, 9 Dec 2025 14:25:05 +0100 Subject: [PATCH 038/462] DOC Release highlights for 1.8 (#32809) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Christian Lorentzen Co-authored-by: Olivier Grisel Co-authored-by: Virgil Chan Co-authored-by: Omar Salman Co-authored-by: Tim Head Co-authored-by: Jérémie du Boisberranger --- .../plot_release_highlights_1_8_0.py | 288 ++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 examples/release_highlights/plot_release_highlights_1_8_0.py diff --git a/examples/release_highlights/plot_release_highlights_1_8_0.py b/examples/release_highlights/plot_release_highlights_1_8_0.py new file mode 100644 index 0000000000000..3414a512724f4 --- /dev/null +++ b/examples/release_highlights/plot_release_highlights_1_8_0.py @@ -0,0 +1,288 @@ +# ruff: noqa: CPY001 +""" +======================================= +Release Highlights for scikit-learn 1.8 +======================================= + +.. currentmodule:: sklearn + +We are pleased to announce the release of scikit-learn 1.8! Many bug fixes +and improvements were added, as well as some key new features. Below we +detail the highlights of this release. **For an exhaustive list of +all the changes**, please refer to the :ref:`release notes `. + +To install the latest version (with pip):: + + pip install --upgrade scikit-learn + +or with conda:: + + conda install -c conda-forge scikit-learn + +""" + +# %% +# Array API support (enables GPU computations) +# -------------------------------------------- +# The progressive adoption of the Python array API standard in +# scikit-learn means that PyTorch and CuPy input arrays +# are used directly. This means that in scikit-learn estimators +# and functions non-CPU devices, such as GPUs, can be used +# to perform the computation. As a result performance is improved +# and integration with these libraries is easier. +# +# In scikit-learn 1.8, several estimators and functions have been updated to +# support array API compatible inputs, for example PyTorch tensors and CuPy +# arrays. +# +# Array API support was added to the following estimators: +# :class:`preprocessing.StandardScaler`, +# :class:`preprocessing.PolynomialFeatures`, :class:`linear_model.RidgeCV`, +# :class:`linear_model.RidgeClassifierCV`, :class:`mixture.GaussianMixture` and +# :class:`calibration.CalibratedClassifierCV`. +# +# Array API support was also added to several metrics in :mod:`sklearn.metrics` +# module, see :ref:`array_api_supported` for more details. +# +# Please refer to the :ref:`array API support` page for instructions +# to use scikit-learn with array API compatible libraries such as PyTorch or CuPy. +# Note: Array API support is experimental and must be explicitly enabled both +# in SciPy and scikit-learn. +# +# Here is an excerpt of using a feature engineering preprocessor on the CPU, +# followed by :class:`calibration.CalibratedClassifierCV` +# and :class:`linear_model.RidgeCV` together on a GPU with the help of PyTorch: +# +# .. code-block:: python +# +# ridge_pipeline_gpu = make_pipeline( +# # Ensure that all features (including categorical features) are preprocessed +# # on the CPU and mapped to a numerical representation. +# feature_preprocessor, +# # Move the results to the GPU and perform computations there +# FunctionTransformer( +# lambda x: torch.tensor(x.to_numpy().astype(np.float32), device="cuda")) +# , +# CalibratedClassifierCV( +# RidgeClassifierCV(alphas=alphas), method="temperature" +# ), +# ) +# with sklearn.config_context(array_api_dispatch=True): +# cv_results = cross_validate(ridge_pipeline_gpu, features, target) +# +# +# See the `full notebook on Google Colab +# `_ +# for more details. On this particular example, using the Colab GPU vs using a +# single CPU core leads to a 10x speedup which is quite typical for such workloads. + +# %% +# Free-threaded CPython 3.14 support +# ---------------------------------- +# +# scikit-learn has support for free-threaded CPython, in particular +# free-threaded wheels are available for all of our supported platforms on Python +# 3.14. +# +# We would be very interested by user feedback. Here are a few things you can +# try: +# +# - install free-threaded CPython 3.14, run your favourite +# scikit-learn script and check that nothing breaks unexpectedly. +# Note that CPython 3.14 (rather than 3.13) is strongly advised because a +# number of free-threaded bugs have been fixed since CPython 3.13. +# - if you use some estimators with a `n_jobs` parameter, try changing the +# default backend to threading with `joblib.parallel_config` as in the +# snippet below. This could potentially speed-up your code because the +# default joblib backend is process-based and incurs more overhead than +# threads. +# +# .. code-block:: python +# +# grid_search = GridSearchCV(clf, param_grid=param_grid, n_jobs=4) +# with joblib.parallel_config(backend="threading"): +# grid_search.fit(X, y) +# +# - don't hesitate to report any issue or unexpected performance behaviour by +# opening a `GitHub issue `_! +# +# Free-threaded (also known as nogil) CPython is a version of CPython that aims +# to enable efficient multi-threaded use cases by removing the Global +# Interpreter Lock (GIL). +# +# For more details about free-threaded CPython see `py-free-threading doc +# `_, in particular `how to install a +# free-threaded CPython `_ +# and `Ecosystem compatibility tracking `_. +# +# In scikit-learn, one hope with free-threaded Python is to more efficiently +# leverage multi-core CPUs by using thread workers instead of subprocess +# workers for parallel computation when passing `n_jobs>1` in functions or +# estimators. Efficiency gains are expected by removing the need for +# inter-process communication. Be aware that switching the default joblib +# backend and testing that everything works well with free-threaded Python is an +# ongoing long-term effort. + +# %% +# Temperature scaling in `CalibratedClassifierCV` +# ----------------------------------------------- +# Probability calibration of classifiers with temperature scaling is available in +# :class:`calibration.CalibratedClassifierCV` by setting `method="temperature"`. +# This method is particularly well suited for multiclass problems because it provides +# (better) calibrated probabilities with a single free parameter. This is in +# contrast to all the other available calibrations methods +# which use a "One-vs-Rest" scheme that adds more parameters for each class. + +from sklearn.calibration import CalibratedClassifierCV +from sklearn.datasets import make_classification +from sklearn.naive_bayes import GaussianNB + +X, y = make_classification(n_classes=3, n_informative=8, random_state=42) +clf = GaussianNB().fit(X, y) +sig = CalibratedClassifierCV(clf, method="sigmoid", ensemble=False).fit(X, y) +ts = CalibratedClassifierCV(clf, method="temperature", ensemble=False).fit(X, y) + +# %% +# The following example shows that temperature scaling can produce better calibrated +# probabilities than sigmoid calibration in multi-class classification problem +# with 3 classes. + +import matplotlib.pyplot as plt + +from sklearn.calibration import CalibrationDisplay + +fig, axes = plt.subplots( + figsize=(8, 4.5), + ncols=3, + sharey=True, +) +for i, c in enumerate(ts.classes_): + CalibrationDisplay.from_predictions( + y == c, clf.predict_proba(X)[:, i], name="Uncalibrated", ax=axes[i], marker="s" + ) + CalibrationDisplay.from_predictions( + y == c, + ts.predict_proba(X)[:, i], + name="Temperature scaling", + ax=axes[i], + marker="o", + ) + CalibrationDisplay.from_predictions( + y == c, sig.predict_proba(X)[:, i], name="Sigmoid", ax=axes[i], marker="v" + ) + axes[i].set_title(f"Class {c}") + axes[i].set_xlabel(None) + axes[i].set_ylabel(None) + axes[i].get_legend().remove() +fig.suptitle("Reliability Diagrams per Class") +fig.supxlabel("Mean Predicted Probability") +fig.supylabel("Fraction of Class") +fig.legend(*axes[0].get_legend_handles_labels(), loc=(0.72, 0.5)) +plt.subplots_adjust(right=0.7) +_ = fig.show() + +# %% +# Efficiency improvements in linear models +# ---------------------------------------- +# The fit time has been massively reduced for squared error based estimators +# with L1 penalty: `ElasticNet`, `Lasso`, `MultiTaskElasticNet`, +# `MultiTaskLasso` and their CV variants. The fit time improvement is mainly +# achieved by **gap safe screening rules**. They enable the coordinate descent +# solver to set feature coefficients to zero early on and not look at them +# again. The stronger the L1 penalty the earlier features can be excluded from +# further updates. + +from time import time + +from sklearn.datasets import make_regression +from sklearn.linear_model import ElasticNetCV + +X, y = make_regression(n_features=10_000, random_state=0) +model = ElasticNetCV() +tic = time() +model.fit(X, y) +toc = time() +print(f"Fitting ElasticNetCV took {toc - tic:.3} seconds.") + +# %% +# HTML representation of estimators +# --------------------------------- +# Hyperparameters in the dropdown table of the HTML representation now include +# links to the online documentation. Docstring descriptions are also shown as +# tooltips on hover. + +from sklearn.linear_model import LogisticRegression +from sklearn.pipeline import make_pipeline +from sklearn.preprocessing import StandardScaler + +clf = make_pipeline(StandardScaler(), LogisticRegression(random_state=0, C=10)) + +# %% +# Expand the estimator diagram below by clicking on "LogisticRegression" and then on +# "Parameters". + +clf + + +# %% +# DecisionTreeRegressor with `criterion="absolute_error"` +# ------------------------------------------------------ +# :class:`tree.DecisionTreeRegressor` with `criterion="absolute_error"` +# now runs much faster. It has now `O(n * log(n))` complexity compared to +# `O(n**2)` previously, which allows to scale to millions of data points. +# +# As an illustration, on a dataset with 100_000 samples and 1 feature, doing a +# single split takes of the order of 100 ms, compared to ~20 seconds before. + +import time + +from sklearn.datasets import make_regression +from sklearn.tree import DecisionTreeRegressor + +X, y = make_regression(n_samples=100_000, n_features=1) +tree = DecisionTreeRegressor(criterion="absolute_error", max_depth=1) + +tic = time.time() +tree.fit(X, y) +elapsed = time.time() - tic +print(f"Fit took {elapsed:.2f} seconds") + +# %% +# ClassicalMDS +# ------------ +# Classical MDS, also known as "Principal Coordinates Analysis" (PCoA) +# or "Torgerson's scaling" is now available within the `sklearn.manifold` +# module. Classical MDS is close to PCA and instead of approximating +# distances, it approximates pairwise scalar products, which has an exact +# analytic solution in terms of eigendecomposition. +# +# Let's illustrate this new addition by using it on an S-curve dataset to +# get a low-dimensional representation of the data. + +import matplotlib.pyplot as plt +from matplotlib import ticker + +from sklearn import datasets, manifold + +n_samples = 1500 +S_points, S_color = datasets.make_s_curve(n_samples, random_state=0) +md_classical = manifold.ClassicalMDS(n_components=2) +S_scaling = md_classical.fit_transform(S_points) + +fig = plt.figure(figsize=(8, 4)) +ax1 = fig.add_subplot(1, 2, 1, projection="3d") +x, y, z = S_points.T +ax1.scatter(x, y, z, c=S_color, s=50, alpha=0.8) +ax1.set_title("Original S-curve samples", size=16) +ax1.view_init(azim=-60, elev=9) +for axis in (ax1.xaxis, ax1.yaxis, ax1.zaxis): + axis.set_major_locator(ticker.MultipleLocator(1)) + +ax2 = fig.add_subplot(1, 2, 2) +x2, y2 = S_scaling.T +ax2.scatter(x2, y2, c=S_color, s=50, alpha=0.8) +ax2.set_title("Classical MDS", size=16) +for axis in (ax2.xaxis, ax2.yaxis): + axis.set_major_formatter(ticker.NullFormatter()) + +plt.show() From b04ad9520f09982b9093810bc55daacdf250a472 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Wed, 10 Dec 2025 00:32:48 +0100 Subject: [PATCH 039/462] MNT Update link to new build instruction location in `raise_build_error` (#32862) --- sklearn/__check_build/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/__check_build/__init__.py b/sklearn/__check_build/__init__.py index 0a4162d0dffc6..f272b008f85b9 100644 --- a/sklearn/__check_build/__init__.py +++ b/sklearn/__check_build/__init__.py @@ -42,7 +42,7 @@ def raise_build_error(e): If you have installed scikit-learn from source, please do not forget to build the package before using it. For detailed instructions, see: -https://scikit-learn.org/dev/developers/advanced_installation.html#building-from-source +https://scikit-learn.org/dev/developers/development_setup.html#install-editable-version-of-scikit-learn %s""" % (e, local_dir, "".join(dir_content).strip(), msg) ) From 9e24cf5666cc4d3247bc6169724431d65a6ad662 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Wed, 10 Dec 2025 08:52:52 +0100 Subject: [PATCH 040/462] FIX add quickfix for pandas warning causing CI error (#32865) Co-authored-by: Olivier Grisel --- .../tests/test_target_encoder.py | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/sklearn/preprocessing/tests/test_target_encoder.py b/sklearn/preprocessing/tests/test_target_encoder.py index 536f2e031bf77..84f04ec46f343 100644 --- a/sklearn/preprocessing/tests/test_target_encoder.py +++ b/sklearn/preprocessing/tests/test_target_encoder.py @@ -1,4 +1,5 @@ import re +import warnings import numpy as np import pytest @@ -20,6 +21,7 @@ LabelEncoder, TargetEncoder, ) +from sklearn.utils.fixes import parse_version def _encode_target(X_ordinal, y_numeric, n_categories, smooth): @@ -709,6 +711,25 @@ def test_pandas_copy_on_write(): Non-regression test for gh-27879. """ pd = pytest.importorskip("pandas", minversion="2.0") - with pd.option_context("mode.copy_on_write", True): + # Pandas currently warns that setting copy_on_write will be removed in pandas 4 + # (and copy-on-write will always be enabled). + # see https://github.com/scikit-learn/scikit-learn/issues/32829 + # TODO: remove this workaround when pandas 4 is our minimum version + if parse_version(pd.__version__) >= parse_version("4.0"): df = pd.DataFrame({"x": ["a", "b", "b"], "y": [4.0, 5.0, 6.0]}) TargetEncoder(target_type="continuous").fit(df[["x"]], df["y"]) + else: + with warnings.catch_warnings(): + expected_message = ( + "Copy-on-Write can no longer be disabled, " + "setting to False has no impact. This option will " + "be removed in pandas 4.0." + ) + warnings.filterwarnings( + "ignore", + message=re.escape(expected_message), + category=DeprecationWarning, + ) + with pd.option_context("mode.copy_on_write", True): + df = pd.DataFrame({"x": ["a", "b", "b"], "y": [4.0, 5.0, 6.0]}) + TargetEncoder(target_type="continuous").fit(df[["x"]], df["y"]) From 96df8e88e73592a34e7b89c30db676734595f811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Wed, 10 Dec 2025 09:06:53 +0100 Subject: [PATCH 041/462] DOC Update news for 1.8.0 (#32877) --- doc/templates/index.html | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/templates/index.html b/doc/templates/index.html index 08abde9895ea0..a7669f9b911b9 100644 --- a/doc/templates/index.html +++ b/doc/templates/index.html @@ -206,15 +206,13 @@

News

    -
  • On-going development: scikit-learn 1.8 (Changelog).
  • +
  • On-going development: scikit-learn 1.9 (Changelog).
  • +
  • December 2025. scikit-learn 1.8.0 is available for download (Changelog).
  • September 2025. scikit-learn 1.7.2 is available for download (Changelog).
  • July 2025. scikit-learn 1.7.1 is available for download (Changelog).
  • June 2025. scikit-learn 1.7.0 is available for download (Changelog).
  • January 2025. scikit-learn 1.6.1 is available for download (Changelog).
  • December 2024. scikit-learn 1.6.0 is available for download (Changelog).
  • -
  • September 2024. scikit-learn 1.5.2 is available for download (Changelog).
  • -
  • July 2024. scikit-learn 1.5.1 is available for download (Changelog).
  • -
  • May 2024. scikit-learn 1.5.0 is available for download (Changelog).
  • All releases: What's new (Changelog).
From 6f7b6c8ca82ede18dd65099c8eaa2b28e1531b00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Wed, 10 Dec 2025 10:09:37 +0100 Subject: [PATCH 042/462] DOC Fix too short underline in 1.8 release highlights (#32878) --- examples/release_highlights/plot_release_highlights_1_8_0.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/release_highlights/plot_release_highlights_1_8_0.py b/examples/release_highlights/plot_release_highlights_1_8_0.py index 3414a512724f4..a1d3da07849a6 100644 --- a/examples/release_highlights/plot_release_highlights_1_8_0.py +++ b/examples/release_highlights/plot_release_highlights_1_8_0.py @@ -226,7 +226,7 @@ # %% # DecisionTreeRegressor with `criterion="absolute_error"` -# ------------------------------------------------------ +# ------------------------------------------------------- # :class:`tree.DecisionTreeRegressor` with `criterion="absolute_error"` # now runs much faster. It has now `O(n * log(n))` complexity compared to # `O(n**2)` previously, which allows to scale to millions of data points. From 51df6d60512aabca3af27258ca885f7ffaa4a2a2 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Wed, 10 Dec 2025 10:42:34 +0100 Subject: [PATCH 043/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#32857) Co-authored-by: Lock file bot Co-authored-by: Olivier Grisel --- ...pylatest_pip_scipy_dev_linux-64_conda.lock | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index e5db81f2c3b5e..dcf27d5b939f7 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -6,31 +6,31 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_14.conda#91349c276f84f590487e4c7f6e90e077 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_14.conda#550dceb769d23bcf0e2f97fd4062d720 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_14.conda#6c13aaae36d7514f28bd5544da1a7bb8 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_14.conda#3078a2a9a58566a54e579b41b9e88c84 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_14.conda#8e96fe9b17d5871b5cf9d312cab832f6 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda#80c07c68d2f6870250959dcc95b209d1 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_14.conda#fa9d91abc5a9db36fa8dcd1b9a602e61 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_14.conda#9531f671a13eec0597941fa19e489b96 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-h3691f8a_4.conda#af7715829219de9043fcc5575e66d22e +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_14.conda#ab557953cdcf9c483e1d088e0d8ab238 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.0-h32b2ec7_102_cp314.conda#0a19d2cc6eb15881889b0c6fa7d6a78d +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-h32b2ec7_100_cp314.conda#1cef1236a05c3a98f68c33ae9425f656 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b @@ -44,10 +44,10 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip imagesize @ https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl#sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip markupsafe @ https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 -# pip meson @ https://files.pythonhosted.org/packages/9c/07/b48592d325cb86682829f05216e4efb2dc881762b8f1bafb48b57442307a/meson-1.9.1-py3-none-any.whl#sha256=f824ab770c041a202f532f69e114c971918ed2daff7ea56583d80642564598d0 +# pip meson @ https://files.pythonhosted.org/packages/d7/ab/115470e7c6dcce024e43e2e00986864c56e48c59554bb19f4b02ed72814c/meson-1.9.2-py3-none-any.whl#sha256=1a284dc1912929098a6462401af58dc49ae3f324e94814a38a8f1020cee07cba # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 -# pip platformdirs @ https://files.pythonhosted.org/packages/73/cb/ac7874b3e5d58441674fb70742e6c374b28b0c7cb988d37d991cde47166c/platformdirs-4.5.0-py3-none-any.whl#sha256=e578a81bb873cbb89a41fcc904c7ef523cc18284b7e3b3ccf06aca1403b7ebd3 +# pip platformdirs @ https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl#sha256=d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b # pip roman-numerals @ https://files.pythonhosted.org/packages/82/1d/7356f115a0e5faf8dc59894a3e9fc8b1821ab949163458b0072db0a12a68/roman_numerals-3.1.0-py3-none-any.whl#sha256=842ae5fd12912d62720c9aad8cab706e8c692556d01a38443e051ee6cc158d90 @@ -61,15 +61,15 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip sphinxcontrib-serializinghtml @ https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl#sha256=6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 # pip tabulate @ https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl#sha256=024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb -# pip urllib3 @ https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl#sha256=e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc +# pip urllib3 @ https://files.pythonhosted.org/packages/56/1a/9ffe814d317c5224166b23e7c47f606d6e473712a2fad0f704ea9b99f246/urllib3-2.6.0-py3-none-any.whl#sha256=c90f7a39f716c572c4e3e58509581ebd83f9b59cced005b7db7ad2d22b0db99f # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/c0/57/e69a1de45ec7a99a707e9f1a5defa035a48de0cae2d8582451c72d2db456/pyproject_metadata-0.10.0-py3-none-any.whl#sha256=b1e439a9f7560f9792ee5975dcf5e89d2510b1fc84a922d7e5d665aa9102d966 -# pip pytest @ https://files.pythonhosted.org/packages/0b/8b/6300fb80f858cda1c51ffa17075df5d846757081d11ab4aa35cef9e6258b/pytest-9.0.1-py3-none-any.whl#sha256=67be0030d194df2dfa7b556f2e56fb3c3315bd5c8822c6951162b92b32ce7dad +# pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 # pip meson-python @ https://files.pythonhosted.org/packages/28/58/66db620a8a7ccb32633de9f403fe49f1b63c68ca94e5c340ec5cceeb9821/meson_python-0.18.0-py3-none-any.whl#sha256=3b0fe051551cc238f5febb873247c0949cd60ded556efa130aa57021804868e2 # pip pooch @ https://files.pythonhosted.org/packages/a8/87/77cc11c7a9ea9fd05503def69e3d18605852cd0d4b0d3b8f15bbeb3ef1d1/pooch-1.8.2-py3-none-any.whl#sha256=3529a57096f7198778a5ceefd5ac3ef0e4d06a6ddaf9fc2d609b806f25302c47 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 -# pip sphinx @ https://files.pythonhosted.org/packages/fe/8b/76e2a1ce12b915399365873eef2b1197da9d032c99e661a71fd7e1490333/sphinx-9.0.0-py3-none-any.whl#sha256=3442bf635d378da2ba4e88aa8496f3a61b2d59ef145aeaf34353ab93fd79f1bf +# pip sphinx @ https://files.pythonhosted.org/packages/c6/3f/4bbd76424c393caead2e1eb89777f575dee5c8653e2d4b6afd7a564f5974/sphinx-9.0.4-py3-none-any.whl#sha256=5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb # pip numpydoc @ https://files.pythonhosted.org/packages/6c/45/56d99ba9366476cd8548527667f01869279cedb9e66b28eb4dfb27701679/numpydoc-1.8.0-py3-none-any.whl#sha256=72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541 From e0ca871b32cb123484630d9687093c49277ec076 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Wed, 10 Dec 2025 10:56:45 +0100 Subject: [PATCH 044/462] FIX missing RNG seeding in `test_sag_regressor` (#32879) --- sklearn/linear_model/tests/test_sag.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sklearn/linear_model/tests/test_sag.py b/sklearn/linear_model/tests/test_sag.py index 575838f8e8497..f6b0405c23168 100644 --- a/sklearn/linear_model/tests/test_sag.py +++ b/sklearn/linear_model/tests/test_sag.py @@ -577,7 +577,13 @@ def test_sag_regressor(seed, csr_container): # simple linear function with noise y = 0.5 * X.ravel() + rng.randn(n_samples, 1).ravel() - clf1 = Ridge(tol=tol, solver="sag", max_iter=max_iter, alpha=alpha * n_samples) + clf1 = Ridge( + tol=tol, + solver="sag", + max_iter=max_iter, + alpha=alpha * n_samples, + random_state=rng, + ) clf2 = clone(clf1) clf1.fit(X, y) clf2.fit(csr_container(X), y) From b59a67d655b1a41b88f14d706ea403f65ca1b9cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Wed, 10 Dec 2025 12:21:04 +0100 Subject: [PATCH 045/462] DOC Backport changelog changes from 1.8.X branch (#32876) --- .../array-api/27113.feature.rst | 3 - .../array-api/27961.feature.rst | 4 - .../array-api/29822.feature.rst | 5 - .../array-api/30562.feature.rst | 2 - .../array-api/30777.feature.rst | 4 - .../array-api/30878.feature.rst | 2 - .../array-api/31580.feature.rst | 2 - .../array-api/32246.feature.rst | 4 - .../array-api/32249.feature.rst | 3 - .../array-api/32270.feature.rst | 2 - .../array-api/32422.feature.rst | 4 - .../array-api/32497.feature.rst | 2 - .../array-api/32582.feature.rst | 3 - .../array-api/32586.feature.rst | 2 - .../array-api/32597.feature.rst | 2 - .../array-api/32600.feature.rst | 2 - .../array-api/32604.feature.rst | 2 - .../array-api/32613.feature.rst | 2 - .../array-api/32619.feature.rst | 2 - .../array-api/32693.feature.rst | 2 - .../upcoming_changes/array-api/32838.fix.rst | 2 - .../custom-top-level/32079.other.rst | 23 - .../many-modules/31775.efficiency.rst | 4 - .../metadata-routing/31898.fix.rst | 3 - .../sklearn.base/31928.feature.rst | 2 - .../sklearn.base/32341.fix.rst | 2 - .../sklearn.calibration/31068.feature.rst | 2 - .../sklearn.cluster/31973.fix.rst | 4 - .../sklearn.cluster/31991.efficiency.rst | 3 - .../sklearn.compose/32188.fix.rst | 3 - .../sklearn.covariance/31987.efficiency.rst | 6 - .../sklearn.covariance/31987.fix.rst | 6 - .../sklearn.covariance/32117.fix.rst | 4 - .../sklearn.decomposition/29310.fix.rst | 3 - .../31987.efficiency.rst | 11 - .../32077.enhancement.rst | 3 - .../32108.feature.rst | 6 - .../sklearn.ensemble/32825.fix.rst | 8 - .../31939.enhancement.rst | 3 - .../31431.efficiency.rst | 3 - .../sklearn.linear_model/29097.api.rst | 7 - .../sklearn.linear_model/31474.api.rst | 6 - .../sklearn.linear_model/31665.efficiency.rst | 4 - .../sklearn.linear_model/31848.efficiency.rst | 3 - .../sklearn.linear_model/31856.fix.rst | 6 - .../sklearn.linear_model/31880.efficiency.rst | 9 - .../sklearn.linear_model/31888.api.rst | 4 - .../31906.enhancement.rst | 9 - .../sklearn.linear_model/31933.fix.rst | 8 - .../sklearn.linear_model/31946.efficiency.rst | 4 - .../sklearn.linear_model/32014.efficiency.rst | 14 - .../sklearn.linear_model/32114.api.rst | 16 - .../sklearn.linear_model/32659.api.rst | 27 - .../sklearn.linear_model/32742.api.rst | 3 - .../sklearn.linear_model/32747.fix.rst | 4 - .../sklearn.manifold/31322.major-feature.rst | 3 - .../sklearn.manifold/32229.feature.rst | 6 - .../sklearn.manifold/32433.feature.rst | 2 - .../sklearn.metrics/28971.feature.rst | 2 - .../sklearn.metrics/30134.feature.rst | 3 - .../sklearn.metrics/30787.fix.rst | 6 - .../sklearn.metrics/31294.api.rst | 2 - .../sklearn.metrics/31406.enhancement.rst | 2 - .../sklearn.metrics/31701.fix.rst | 21 - .../sklearn.metrics/31764.fix.rst | 5 - .../sklearn.metrics/31891.fix.rst | 3 - .../sklearn.metrics/32047.enhancement.rst | 9 - .../sklearn.metrics/32310.api.rst | 3 - .../sklearn.metrics/32313.fix.rst | 5 - .../sklearn.metrics/32356.efficiency.rst | 3 - .../sklearn.metrics/32356.fix.rst | 4 - .../sklearn.metrics/32372.fix.rst | 4 - .../sklearn.metrics/32549.fix.rst | 7 - .../32265.enhancement.rst | 4 - .../sklearn.model_selection/32540.fix.rst | 3 - .../sklearn.multiclass/15504.fix.rst | 3 - .../sklearn.naive_bayes/32497.fix.rst | 3 - .../28043.enhancement.rst | 2 - .../29307.enhancement.rst | 4 - .../31790.enhancement.rst | 3 - .../sklearn.preprocessing/32592.fix.rst | 2 - .../sklearn.semi_supervised/31924.fix.rst | 4 - .../sklearn.tree/30041.fix.rst | 2 - .../sklearn.tree/31036.fix.rst | 3 - .../sklearn.tree/32100.efficiency.rst | 4 - .../sklearn.tree/32100.fix.rst | 6 - .../sklearn.tree/32259.fix.rst | 3 - .../sklearn.tree/32274.fix.rst | 6 - .../sklearn.tree/32280.fix.rst | 4 - .../sklearn.tree/32351.fix.rst | 3 - .../sklearn.utils/31564.enhancement.rst | 5 - .../sklearn.utils/31873.enhancement.rst | 4 - .../sklearn.utils/31951.enhancement.rst | 4 - .../sklearn.utils/31952.efficiency.rst | 5 - .../sklearn.utils/31969.enhancement.rst | 3 - .../sklearn.utils/32258.api.rst | 3 - .../sklearn.utils/32330.fix.rst | 2 - doc/whats_new/v1.8.rst | 673 +++++++++++++++++- 98 files changed, 672 insertions(+), 455 deletions(-) delete mode 100644 doc/whats_new/upcoming_changes/array-api/27113.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/27961.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/29822.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/30562.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/30777.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/30878.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/31580.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32246.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32249.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32270.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32422.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32497.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32582.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32586.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32597.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32600.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32604.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32613.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32619.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32693.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/array-api/32838.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/custom-top-level/32079.other.rst delete mode 100644 doc/whats_new/upcoming_changes/many-modules/31775.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/metadata-routing/31898.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.base/31928.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.base/32341.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.calibration/31068.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.cluster/31973.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.cluster/31991.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.compose/32188.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.covariance/31987.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.covariance/31987.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.covariance/32117.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.decomposition/29310.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.decomposition/31987.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.decomposition/32077.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.discriminant_analysis/32108.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.ensemble/32825.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.feature_selection/31939.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.gaussian_process/31431.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/29097.api.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/31474.api.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/31665.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/31848.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/31856.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/31880.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/31888.api.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/31906.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/31933.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/31946.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/32014.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/32114.api.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/32659.api.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/32742.api.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/32747.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.manifold/31322.major-feature.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.manifold/32229.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.manifold/32433.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/28971.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/30134.feature.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/30787.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/31294.api.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/31406.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/31701.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/31764.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/31891.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/32047.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/32310.api.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/32313.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/32356.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/32356.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/32372.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/32549.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.model_selection/32265.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.model_selection/32540.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.multiclass/15504.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.naive_bayes/32497.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.preprocessing/28043.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.preprocessing/29307.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.preprocessing/31790.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.preprocessing/32592.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.semi_supervised/31924.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/30041.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/31036.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/32100.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/32100.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/32259.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/32274.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/32280.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/32351.fix.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/31873.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/31951.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/31952.efficiency.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/31969.enhancement.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/32258.api.rst delete mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/32330.fix.rst diff --git a/doc/whats_new/upcoming_changes/array-api/27113.feature.rst b/doc/whats_new/upcoming_changes/array-api/27113.feature.rst deleted file mode 100644 index 5e044c82cd568..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/27113.feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`sklearn.preprocessing.StandardScaler` now supports Array API compliant inputs. - By :user:`Alexander Fabisch `, :user:`Edoardo Abati `, - :user:`Olivier Grisel ` and :user:`Charles Hill `. diff --git a/doc/whats_new/upcoming_changes/array-api/27961.feature.rst b/doc/whats_new/upcoming_changes/array-api/27961.feature.rst deleted file mode 100644 index 3dbea99e0f749..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/27961.feature.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`linear_model.RidgeCV`, :class:`linear_model.RidgeClassifier` and - :class:`linear_model.RidgeClassifierCV` now support array API compatible - inputs with `solver="svd"`. - By :user:`Jérôme Dockès `. diff --git a/doc/whats_new/upcoming_changes/array-api/29822.feature.rst b/doc/whats_new/upcoming_changes/array-api/29822.feature.rst deleted file mode 100644 index 4cd3dc8d300cb..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/29822.feature.rst +++ /dev/null @@ -1,5 +0,0 @@ -- :func:`metrics.pairwise.pairwise_kernels` for any kernel except - "laplacian" and - :func:`metrics.pairwise_distances` for metrics "cosine", - "euclidean" and "l2" now support array API inputs. - By :user:`Emily Chen ` and :user:`Lucy Liu ` diff --git a/doc/whats_new/upcoming_changes/array-api/30562.feature.rst b/doc/whats_new/upcoming_changes/array-api/30562.feature.rst deleted file mode 100644 index 3c1a58d90bfe5..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/30562.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.metrics.confusion_matrix` now supports Array API compatible inputs. - By :user:`Stefanie Senger ` diff --git a/doc/whats_new/upcoming_changes/array-api/30777.feature.rst b/doc/whats_new/upcoming_changes/array-api/30777.feature.rst deleted file mode 100644 index aec9bb4da1e71..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/30777.feature.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`sklearn.mixture.GaussianMixture` with - `init_params="random"` or `init_params="random_from_data"` and - `warm_start=False` now supports Array API compatible inputs. - By :user:`Stefanie Senger ` and :user:`Loïc Estève ` diff --git a/doc/whats_new/upcoming_changes/array-api/30878.feature.rst b/doc/whats_new/upcoming_changes/array-api/30878.feature.rst deleted file mode 100644 index fabb4c80f5713..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/30878.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.metrics.roc_curve` now supports Array API compatible inputs. - By :user:`Thomas Li ` diff --git a/doc/whats_new/upcoming_changes/array-api/31580.feature.rst b/doc/whats_new/upcoming_changes/array-api/31580.feature.rst deleted file mode 100644 index 3d7aaa4372109..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/31580.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :class:`preprocessing.PolynomialFeatures` now supports array API compatible inputs. - By :user:`Omar Salman ` diff --git a/doc/whats_new/upcoming_changes/array-api/32246.feature.rst b/doc/whats_new/upcoming_changes/array-api/32246.feature.rst deleted file mode 100644 index aaf015fd3ff79..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32246.feature.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`calibration.CalibratedClassifierCV` now supports array API compatible - inputs with `method="temperature"` and when the underlying `estimator` also - supports the array API. - By :user:`Omar Salman ` diff --git a/doc/whats_new/upcoming_changes/array-api/32249.feature.rst b/doc/whats_new/upcoming_changes/array-api/32249.feature.rst deleted file mode 100644 index f8102a540328f..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32249.feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :func:`sklearn.metrics.precision_recall_curve` now supports array API compatible - inputs. - By :user:`Lucy Liu ` diff --git a/doc/whats_new/upcoming_changes/array-api/32270.feature.rst b/doc/whats_new/upcoming_changes/array-api/32270.feature.rst deleted file mode 100644 index 1b2e4ce05090d..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32270.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.model_selection.cross_val_predict` now supports array API compatible inputs. - By :user:`Omar Salman ` diff --git a/doc/whats_new/upcoming_changes/array-api/32422.feature.rst b/doc/whats_new/upcoming_changes/array-api/32422.feature.rst deleted file mode 100644 index fa0cfe503d7f7..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32422.feature.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :func:`sklearn.metrics.brier_score_loss`, :func:`sklearn.metrics.log_loss`, - :func:`sklearn.metrics.d2_brier_score` and :func:`sklearn.metrics.d2_log_loss_score` - now support array API compatible inputs. - By :user:`Omar Salman ` diff --git a/doc/whats_new/upcoming_changes/array-api/32497.feature.rst b/doc/whats_new/upcoming_changes/array-api/32497.feature.rst deleted file mode 100644 index 1b02c72f043af..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32497.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :class:`naive_bayes.GaussianNB` now supports array API compatible inputs. - By :user:`Omar Salman ` diff --git a/doc/whats_new/upcoming_changes/array-api/32582.feature.rst b/doc/whats_new/upcoming_changes/array-api/32582.feature.rst deleted file mode 100644 index b3fefc594483b..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32582.feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`preprocessing.LabelBinarizer` and :func:`preprocessing.label_binarize` now - support numeric array API compatible inputs with `sparse_output=False`. - By :user:`Virgil Chan `. diff --git a/doc/whats_new/upcoming_changes/array-api/32586.feature.rst b/doc/whats_new/upcoming_changes/array-api/32586.feature.rst deleted file mode 100644 index 8770a2422140b..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32586.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.metrics.det_curve` now supports Array API compliant inputs. - By :user:`Josef Affourtit `. diff --git a/doc/whats_new/upcoming_changes/array-api/32597.feature.rst b/doc/whats_new/upcoming_changes/array-api/32597.feature.rst deleted file mode 100644 index 2d22190b4a052..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32597.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.metrics.pairwise.manhattan_distances` now supports array API compatible inputs. - By :user:`Omar Salman `. diff --git a/doc/whats_new/upcoming_changes/array-api/32600.feature.rst b/doc/whats_new/upcoming_changes/array-api/32600.feature.rst deleted file mode 100644 index f39aa06a6cb70..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32600.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.metrics.calinski_harabasz_score` now supports Array API compliant inputs. - By :user:`Josef Affourtit `. diff --git a/doc/whats_new/upcoming_changes/array-api/32604.feature.rst b/doc/whats_new/upcoming_changes/array-api/32604.feature.rst deleted file mode 100644 index 752ea5b9cb3b5..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32604.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.metrics.balanced_accuracy_score` now supports array API compatible inputs. - By :user:`Omar Salman `. diff --git a/doc/whats_new/upcoming_changes/array-api/32613.feature.rst b/doc/whats_new/upcoming_changes/array-api/32613.feature.rst deleted file mode 100644 index 34c73b653f475..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32613.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.metrics.pairwise.laplacian_kernel` now supports array API compatible inputs. - By :user:`Zubair Shakoor `. diff --git a/doc/whats_new/upcoming_changes/array-api/32619.feature.rst b/doc/whats_new/upcoming_changes/array-api/32619.feature.rst deleted file mode 100644 index ba3928cea8bce..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32619.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.metrics.cohen_kappa_score` now supports array API compatible inputs. - By :user:`Omar Salman `. diff --git a/doc/whats_new/upcoming_changes/array-api/32693.feature.rst b/doc/whats_new/upcoming_changes/array-api/32693.feature.rst deleted file mode 100644 index 466ae99f4e360..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32693.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`sklearn.metrics.cluster.davies_bouldin_score` now supports Array API compliant inputs. - By :user:`Josef Affourtit `. diff --git a/doc/whats_new/upcoming_changes/array-api/32838.fix.rst b/doc/whats_new/upcoming_changes/array-api/32838.fix.rst deleted file mode 100644 index ae689f8816841..0000000000000 --- a/doc/whats_new/upcoming_changes/array-api/32838.fix.rst +++ /dev/null @@ -1,2 +0,0 @@ -- Estimators with array API support no longer reject dataframe inputs when array API support is enabled. - By :user:`Tim Head ` diff --git a/doc/whats_new/upcoming_changes/custom-top-level/32079.other.rst b/doc/whats_new/upcoming_changes/custom-top-level/32079.other.rst deleted file mode 100644 index 0ac966843c075..0000000000000 --- a/doc/whats_new/upcoming_changes/custom-top-level/32079.other.rst +++ /dev/null @@ -1,23 +0,0 @@ -Free-threaded CPython 3.14 support ----------------------------------- - -scikit-learn has support for free-threaded CPython, in particular -free-threaded wheels are available for all of our supported platforms on Python -3.14. - -Free-threaded (also known as nogil) CPython is a version of CPython that aims at -enabling efficient multi-threaded use cases by removing the Global Interpreter -Lock (GIL). - -If you want to try out free-threaded Python, the recommendation is to use -Python 3.14, that has fixed a number of issues compared to Python 3.13. Feel -free to try free-threaded on your use case and report any issues! - -For more details about free-threaded CPython see `py-free-threading doc `_, -in particular `how to install a free-threaded CPython `_ -and `Ecosystem compatibility tracking `_. - -By :user:`Loïc Estève ` and :user:`Olivier Grisel ` and many -other people in the wider Scientific Python and CPython ecosystem, for example -:user:`Nathan Goldbaum `, :user:`Ralf Gommers `, -:user:`Edgar Andrés Margffoy Tuay `. diff --git a/doc/whats_new/upcoming_changes/many-modules/31775.efficiency.rst b/doc/whats_new/upcoming_changes/many-modules/31775.efficiency.rst deleted file mode 100644 index 5aa067aeeb7cf..0000000000000 --- a/doc/whats_new/upcoming_changes/many-modules/31775.efficiency.rst +++ /dev/null @@ -1,4 +0,0 @@ -- Improved CPU and memory usage in estimators and metric functions that rely on - weighted percentiles and better match NumPy and Scipy (un-weighted) implementations - of percentiles. - By :user:`Lucy Liu ` diff --git a/doc/whats_new/upcoming_changes/metadata-routing/31898.fix.rst b/doc/whats_new/upcoming_changes/metadata-routing/31898.fix.rst deleted file mode 100644 index bb4b71974ca60..0000000000000 --- a/doc/whats_new/upcoming_changes/metadata-routing/31898.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Fixed an issue where passing `sample_weight` to a :class:`Pipeline` inside a - :class:`GridSearchCV` would raise an error with metadata routing enabled. - By `Adrin Jalali`_. diff --git a/doc/whats_new/upcoming_changes/sklearn.base/31928.feature.rst b/doc/whats_new/upcoming_changes/sklearn.base/31928.feature.rst deleted file mode 100644 index 65b94b580f3de..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.base/31928.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- Refactored :meth:`dir` in :class:`BaseEstimator` to recognize condition check in :meth:`available_if`. - By :user:`John Hendricks ` and :user:`Miguel Parece `. diff --git a/doc/whats_new/upcoming_changes/sklearn.base/32341.fix.rst b/doc/whats_new/upcoming_changes/sklearn.base/32341.fix.rst deleted file mode 100644 index 0c43b4cfac930..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.base/32341.fix.rst +++ /dev/null @@ -1,2 +0,0 @@ -- Fixed the handling of pandas missing values in HTML display of all estimators. - By :user:`Dea María Léon `. diff --git a/doc/whats_new/upcoming_changes/sklearn.calibration/31068.feature.rst b/doc/whats_new/upcoming_changes/sklearn.calibration/31068.feature.rst deleted file mode 100644 index 4201db9ad0e59..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.calibration/31068.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- Added temperature scaling method in :class:`calibration.CalibratedClassifierCV`. - By :user:`Virgil Chan ` and :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.cluster/31973.fix.rst b/doc/whats_new/upcoming_changes/sklearn.cluster/31973.fix.rst deleted file mode 100644 index f04abbb889f7d..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.cluster/31973.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- The default value of the `copy` parameter in :class:`cluster.HDBSCAN` - will change from `False` to `True` in 1.10 to avoid data modification - and maintain consistency with other estimators. - By :user:`Sarthak Puri `. \ No newline at end of file diff --git a/doc/whats_new/upcoming_changes/sklearn.cluster/31991.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.cluster/31991.efficiency.rst deleted file mode 100644 index 955b8b9ef4c14..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.cluster/31991.efficiency.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :func:`cluster.kmeans_plusplus` now uses `np.cumsum` directly without extra - numerical stability checks and without casting to `np.float64`. - By :user:`Tiziano Zito ` diff --git a/doc/whats_new/upcoming_changes/sklearn.compose/32188.fix.rst b/doc/whats_new/upcoming_changes/sklearn.compose/32188.fix.rst deleted file mode 100644 index 1bd73934a426c..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.compose/32188.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- The :class:`compose.ColumnTransformer` now correctly fits on data provided as a - `polars.DataFrame` when any transformer has a sparse output. - By :user:`Phillipp Gnan `. diff --git a/doc/whats_new/upcoming_changes/sklearn.covariance/31987.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.covariance/31987.efficiency.rst deleted file mode 100644 index a05849fd84ad8..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.covariance/31987.efficiency.rst +++ /dev/null @@ -1,6 +0,0 @@ -- :class:`sklearn.covariance.GraphicalLasso`, - :class:`sklearn.covariance.GraphicalLassoCV` and - :func:`sklearn.covariance.graphical_lasso` with `mode="cd"` profit from the - fit time performance improvement of :class:`sklearn.linear_model.Lasso` by means of - gap safe screening rules. - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.covariance/31987.fix.rst b/doc/whats_new/upcoming_changes/sklearn.covariance/31987.fix.rst deleted file mode 100644 index 1728c7f9ead6e..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.covariance/31987.fix.rst +++ /dev/null @@ -1,6 +0,0 @@ -- Fixed uncontrollable randomness in :class:`sklearn.covariance.GraphicalLasso`, - :class:`sklearn.covariance.GraphicalLassoCV` and - :func:`sklearn.covariance.graphical_lasso`. For `mode="cd"`, they now use cyclic - coordinate descent. Before, it was random coordinate descent with uncontrollable - random number seeding. - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.covariance/32117.fix.rst b/doc/whats_new/upcoming_changes/sklearn.covariance/32117.fix.rst deleted file mode 100644 index fb8145e22e5ed..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.covariance/32117.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- Added correction to :class:`covariance.MinCovDet` to adjust for - consistency at the normal distribution. This reduces the bias present - when applying this method to data that is normally distributed. - By :user:`Daniel Herrera-Esposito ` diff --git a/doc/whats_new/upcoming_changes/sklearn.decomposition/29310.fix.rst b/doc/whats_new/upcoming_changes/sklearn.decomposition/29310.fix.rst deleted file mode 100644 index a6ff94cdac6ab..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.decomposition/29310.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Add input checks to the `inverse_transform` method of :class:`decomposition.PCA` - and :class:`decomposition.IncrementalPCA`. - :pr:`29310` by :user:`Ian Faust `. diff --git a/doc/whats_new/upcoming_changes/sklearn.decomposition/31987.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.decomposition/31987.efficiency.rst deleted file mode 100644 index 8edfdfcb74d31..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.decomposition/31987.efficiency.rst +++ /dev/null @@ -1,11 +0,0 @@ -- :class:`sklearn.decomposition.DictionaryLearning` and - :class:`sklearn.decomposition.MiniBatchDictionaryLearning` with `fit_algorithm="cd"`, - :class:`sklearn.decomposition.SparseCoder` with `transform_algorithm="lasso_cd"`, - :class:`sklearn.decomposition.MiniBatchSparsePCA`, - :class:`sklearn.decomposition.SparsePCA`, - :func:`sklearn.decomposition.dict_learning` and - :func:`sklearn.decomposition.dict_learning_online` with `method="cd"`, - :func:`sklearn.decomposition.sparse_encode` with `algorithm="lasso_cd"` - all profit from the fit time performance improvement of - :class:`sklearn.linear_model.Lasso` by means of gap safe screening rules. - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.decomposition/32077.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.decomposition/32077.enhancement.rst deleted file mode 100644 index aacff8ae1b76c..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.decomposition/32077.enhancement.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`decomposition.SparseCoder` now follows the transformer API of scikit-learn. - In addition, the :meth:`fit` method now validates the input and parameters. - By :user:`François Paugam `. diff --git a/doc/whats_new/upcoming_changes/sklearn.discriminant_analysis/32108.feature.rst b/doc/whats_new/upcoming_changes/sklearn.discriminant_analysis/32108.feature.rst deleted file mode 100644 index 1379a834c63a4..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.discriminant_analysis/32108.feature.rst +++ /dev/null @@ -1,6 +0,0 @@ -- Added `solver`, `covariance_estimator` and `shrinkage` in - :class:`discriminant_analysis.QuadraticDiscriminantAnalysis`. - The resulting class is more similar to - :class:`discriminant_analysis.LinearDiscriminantAnalysis` - and allows for more flexibility in the estimation of the covariance matrices. - By :user:`Daniel Herrera-Esposito `. diff --git a/doc/whats_new/upcoming_changes/sklearn.ensemble/32825.fix.rst b/doc/whats_new/upcoming_changes/sklearn.ensemble/32825.fix.rst deleted file mode 100644 index 604ec9421a424..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.ensemble/32825.fix.rst +++ /dev/null @@ -1,8 +0,0 @@ -- :class:`ensemble.BaggingClassifier`, :class:`ensemble.BaggingRegressor` and - :class:`ensemble.IsolationForest` now use `sample_weight` to draw the samples - instead of forwarding them multiplied by a uniformly sampled mask to the - underlying estimators. Furthermore, when `max_samples` is a float, it is now - interpreted as a fraction of `sample_weight.sum()` instead of `X.shape[0]`. - The new default `max_samples=None` draws `X.shape[0]` samples, irrespective - of `sample_weight`. - By :user:`Antoine Baker `. :pr:`31414` and diff --git a/doc/whats_new/upcoming_changes/sklearn.feature_selection/31939.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.feature_selection/31939.enhancement.rst deleted file mode 100644 index 8c038c35389ed..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.feature_selection/31939.enhancement.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`feature_selection.SelectFromModel` now does not force `max_features` to be - less than or equal to the number of input features. - By :user:`Thibault ` diff --git a/doc/whats_new/upcoming_changes/sklearn.gaussian_process/31431.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.gaussian_process/31431.efficiency.rst deleted file mode 100644 index 798f2ebb6bd2f..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.gaussian_process/31431.efficiency.rst +++ /dev/null @@ -1,3 +0,0 @@ -- make :class:`GaussianProcessRegressor.predict` faster when `return_cov` and - `return_std` are both `False`. - By :user:`Rafael Ayllón Gavilán `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/29097.api.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/29097.api.rst deleted file mode 100644 index 8cb6265a607a5..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/29097.api.rst +++ /dev/null @@ -1,7 +0,0 @@ -- :class:`linear_model.PassiveAggressiveClassifier` and - :class:`linear_model.PassiveAggressiveRegressor` are deprecated and will be removed - in 1.10. Equivalent estimators are available with :class:`linear_model.SGDClassifier` - and :class:`SGDRegressor`, both of which expose the options `learning_rate="pa1"` and - `"pa2"`. The parameter `eta0` can be used to specify the aggressiveness parameter of - the Passive-Aggressive-Algorithms, called C in the reference paper. - By :user:`Christian Lorentzen ` :pr:`31932` and diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31474.api.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31474.api.rst deleted file mode 100644 index 845b9b502b9f1..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31474.api.rst +++ /dev/null @@ -1,6 +0,0 @@ -- :class:`linear_model.SGDClassifier`, :class:`linear_model.SGDRegressor`, and - :class:`linear_model.SGDOneClassSVM` now deprecate negative values for the - `power_t` parameter. Using a negative value will raise a warning in version 1.8 - and will raise an error in version 1.10. A value in the range [0.0, inf) must be used - instead. - By :user:`Ritvi Alagusankar ` \ No newline at end of file diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31665.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31665.efficiency.rst deleted file mode 100644 index 24a8d53f80b23..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31665.efficiency.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`linear_model.ElasticNet` and :class:`linear_model.Lasso` with - `precompute=False` use less memory for dense `X` and are a bit faster. - Previously, they used twice the memory of `X` even for Fortran-contiguous `X`. - By :user:`Christian Lorentzen ` diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31848.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31848.efficiency.rst deleted file mode 100644 index b76b7cacc8328..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31848.efficiency.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`linear_model.ElasticNet` and :class:`linear_model.Lasso` avoid - double input checking and are therefore a bit faster. - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31856.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31856.fix.rst deleted file mode 100644 index 8d9138d2b449a..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31856.fix.rst +++ /dev/null @@ -1,6 +0,0 @@ -- Fix the convergence criteria for SGD models, to avoid premature convergence when - `tol != None`. This primarily impacts :class:`SGDOneClassSVM` but also affects - :class:`SGDClassifier` and :class:`SGDRegressor`. Before this fix, only the loss - function without penalty was used as the convergence check, whereas now, the full - objective with regularization is used. - By :user:`Guillaume Lemaitre ` and :user:`kostayScr ` diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31880.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31880.efficiency.rst deleted file mode 100644 index 195eb42d907eb..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31880.efficiency.rst +++ /dev/null @@ -1,9 +0,0 @@ -- :class:`linear_model.ElasticNet`, :class:`linear_model.ElasticNetCV`, - :class:`linear_model.Lasso`, :class:`linear_model.LassoCV`, - :class:`linear_model.MultiTaskElasticNet`, - :class:`linear_model.MultiTaskElasticNetCV`, - :class:`linear_model.MultiTaskLasso` and :class:`linear_model.MultiTaskLassoCV` - are faster to fit by avoiding a BLAS level 1 (axpy) call in the innermost loop. - Same for functions :func:`linear_model.enet_path` and - :func:`linear_model.lasso_path`. - By :user:`Christian Lorentzen ` :pr:`31956` and diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31888.api.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31888.api.rst deleted file mode 100644 index a1ac21999bb09..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31888.api.rst +++ /dev/null @@ -1,4 +0,0 @@ -- Raising error in :class:`sklearn.linear_model.LogisticRegression` when - liblinear solver is used and input X values are larger than 1e30, - the liblinear solver freezes otherwise. - By :user:`Shruti Nath `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31906.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31906.enhancement.rst deleted file mode 100644 index 8417c3dd2ac29..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31906.enhancement.rst +++ /dev/null @@ -1,9 +0,0 @@ -- :class:`linear_model.ElasticNet`, :class:`linear_model.ElasticNetCV`, - :class:`linear_model.Lasso`, :class:`linear_model.LassoCV`, - :class:`MultiTaskElasticNet`, :class:`MultiTaskElasticNetCV`, - :class:`MultiTaskLasso`, :class:`MultiTaskLassoCV`, as well as - :func:`linear_model.enet_path` and :func:`linear_model.lasso_path` - now use `dual gap <= tol` instead of `dual gap < tol` as stopping criterion. - The resulting coefficients might differ to previous versions of scikit-learn in - rare cases. - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31933.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31933.fix.rst deleted file mode 100644 index b4995b3908c35..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31933.fix.rst +++ /dev/null @@ -1,8 +0,0 @@ -- The allowed parameter range for the initial learning rate `eta0` in - :class:`linear_model.SGDClassifier`, :class:`linear_model.SGDOneClassSVM`, - :class:`linear_model.SGDRegressor` and :class:`linear_model.Perceptron` - changed from non-negative numbers to strictly positive numbers. - As a consequence, the default `eta0` of :class:`linear_model.SGDClassifier` - and :class:`linear_model.SGDOneClassSVM` changed from 0 to 0.01. But note that - `eta0` is not used by the default learning rate "optimal" of those two estimators. - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/31946.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/31946.efficiency.rst deleted file mode 100644 index 0a4fc0bccf2a6..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/31946.efficiency.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`linear_model.ElasticNetCV`, :class:`linear_model.LassoCV`, - :class:`linear_model.MultiTaskElasticNetCV` and :class:`linear_model.MultiTaskLassoCV` - avoid an additional copy of `X` with default `copy_X=True`. - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32014.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32014.efficiency.rst deleted file mode 100644 index 6bb68b2c68c12..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/32014.efficiency.rst +++ /dev/null @@ -1,14 +0,0 @@ -- :class:`linear_model.ElasticNet`, :class:`linear_model.ElasticNetCV`, - :class:`linear_model.Lasso`, :class:`linear_model.LassoCV`, - :class:`linear_model.MultiTaskElasticNet`, :class:`linear_model.MultiTaskElasticNetCV` - :class:`linear_model.MultiTaskLasso`, :class:`linear_model.MultiTaskLassoCV` - as well as - :func:`linear_model.lasso_path` and :func:`linear_model.enet_path` now implement - gap safe screening rules in the coordinate descent solver for dense and sparse `X`. - The speedup of fitting time is particularly pronounced (10-times is possible) when - computing regularization paths like the \*CV-variants of the above estimators do. - There is now an additional check of the stopping criterion before entering the main - loop of descent steps. As the stopping criterion requires the computation of the dual - gap, the screening happens whenever the dual gap is computed. - By :user:`Christian Lorentzen ` :pr:`31882`, :pr:`31986`, - :pr:`31987` and diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32114.api.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32114.api.rst deleted file mode 100644 index 7b6768464cf81..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/32114.api.rst +++ /dev/null @@ -1,16 +0,0 @@ -- :class:`linear_model.LogisticRegressionCV` got a new parameter - `use_legacy_attributes` to control the types and shapes of the fitted attributes - `C_`, `l1_ratio_`, `coefs_paths_`, `scores_` and `n_iter_`. - The current default value `True` keeps the legacy behaviour. If `False` then: - - - ``C_`` is a float. - - ``l1_ratio_`` is a float. - - ``coefs_paths_`` is an ndarray of shape - (n_folds, n_l1_ratios, n_cs, n_classes, n_features). - For binary problems (n_classes=2), the 2nd last dimension is 1. - - ``scores_`` is an ndarray of shape (n_folds, n_l1_ratios, n_cs). - - ``n_iter_`` is an ndarray of shape (n_folds, n_l1_ratios, n_cs). - - In version 1.10, the default will change to `False` and `use_legacy_attributes` will - be deprecated. In 1.12 `use_legacy_attributes` will be removed. - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32659.api.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32659.api.rst deleted file mode 100644 index 00b3cd23a7de3..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/32659.api.rst +++ /dev/null @@ -1,27 +0,0 @@ -- Parameter `penalty` of :class:`linear_model.LogisticRegression` and - :class:`linear_model.LogisticRegressionCV` is deprecated and will be removed in - version 1.10. The equivalent behaviour can be obtained as follows: - - - for :class:`linear_model.LogisticRegression` - - - use `l1_ratio=0` instead of `penalty="l2"` - - use `l1_ratio=1` instead of `penalty="l1"` - - use `0`. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32742.api.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32742.api.rst deleted file mode 100644 index 0fd15ccf7371e..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/32742.api.rst +++ /dev/null @@ -1,3 +0,0 @@ -- The `n_jobs` parameter of :class:`linear_model.LogisticRegression` is deprecated and - will be removed in 1.10. It has no effect since 1.8. - By :user:`Loïc Estève `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32747.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32747.fix.rst deleted file mode 100644 index 1f83d78aa24de..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/32747.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`linear_model.LogisticRegressionCV` is able to handle CV splits where - some class labels are missing in some folds. Before, it raised an error whenever a - class label were missing in a fold. - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.manifold/31322.major-feature.rst b/doc/whats_new/upcoming_changes/sklearn.manifold/31322.major-feature.rst deleted file mode 100644 index 0d1610d69747f..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.manifold/31322.major-feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`manifold.ClassicalMDS` was implemented to perform classical MDS - (eigendecomposition of the double-centered distance matrix). - By :user:`Dmitry Kobak ` and :user:`Meekail Zain ` diff --git a/doc/whats_new/upcoming_changes/sklearn.manifold/32229.feature.rst b/doc/whats_new/upcoming_changes/sklearn.manifold/32229.feature.rst deleted file mode 100644 index b1af155f5a1c3..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.manifold/32229.feature.rst +++ /dev/null @@ -1,6 +0,0 @@ -- :class:`manifold.MDS` now supports arbitrary distance metrics - (via `metric` and `metric_params` parameters) and - initialization via classical MDS (via `init` parameter). - The `dissimilarity` parameter was deprecated. The old `metric` parameter - was renamed into `metric_mds`. - By :user:`Dmitry Kobak ` diff --git a/doc/whats_new/upcoming_changes/sklearn.manifold/32433.feature.rst b/doc/whats_new/upcoming_changes/sklearn.manifold/32433.feature.rst deleted file mode 100644 index 6a65dd1ad56d9..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.manifold/32433.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :class:`manifold.TSNE` now supports PCA initialization with sparse input matrices. - By :user:`Arturo Amor `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/28971.feature.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/28971.feature.rst deleted file mode 100644 index 9a2379bc31114..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/28971.feature.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`metrics.d2_brier_score` has been added which calculates the D^2 for the Brier score. - By :user:`Omar Salman `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/30134.feature.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/30134.feature.rst deleted file mode 100644 index 09f0c99501395..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/30134.feature.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Add :func:`metrics.confusion_matrix_at_thresholds` function that returns the number of - true negatives, false positives, false negatives and true positives per threshold. - By :user:`Success Moses `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/30787.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/30787.fix.rst deleted file mode 100644 index 13edbdfc7874d..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/30787.fix.rst +++ /dev/null @@ -1,6 +0,0 @@ -- :func:`metrics.median_absolute_error` now uses `_averaged_weighted_percentile` - instead of `_weighted_percentile` to calculate median when `sample_weight` is not - `None`. This is equivalent to using the "averaged_inverted_cdf" instead of - the "inverted_cdf" quantile method, which gives results equivalent to `numpy.median` - if equal weights used. - By :user:`Lucy Liu ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/31294.api.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/31294.api.rst deleted file mode 100644 index d5afd1d46e6e0..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/31294.api.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`metrics.cluster.entropy` is deprecated and will be removed in v1.10. - By :user:`Lucy Liu ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/31406.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/31406.enhancement.rst deleted file mode 100644 index 4736c67c80132..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/31406.enhancement.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :func:`metrics.median_absolute_error` now supports Array API compatible inputs. - By :user:`Lucy Liu `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/31701.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/31701.fix.rst deleted file mode 100644 index 646cdb544f496..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/31701.fix.rst +++ /dev/null @@ -1,21 +0,0 @@ -- Additional `sample_weight` checking has been added to - :func:`metrics.accuracy_score`, - :func:`metrics.balanced_accuracy_score`, - :func:`metrics.brier_score_loss`, - :func:`metrics.class_likelihood_ratios`, - :func:`metrics.classification_report`, - :func:`metrics.cohen_kappa_score`, - :func:`metrics.confusion_matrix`, - :func:`metrics.f1_score`, - :func:`metrics.fbeta_score`, - :func:`metrics.hamming_loss`, - :func:`metrics.jaccard_score`, - :func:`metrics.matthews_corrcoef`, - :func:`metrics.multilabel_confusion_matrix`, - :func:`metrics.precision_recall_fscore_support`, - :func:`metrics.precision_score`, - :func:`metrics.recall_score` and - :func:`metrics.zero_one_loss`. - `sample_weight` can only be 1D, consistent to `y_true` and `y_pred` in length,and - all values must be finite and not complex. - By :user:`Lucy Liu `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/31764.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/31764.fix.rst deleted file mode 100644 index 8dab2fc772563..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/31764.fix.rst +++ /dev/null @@ -1,5 +0,0 @@ -- `y_pred` is deprecated in favour of `y_score` in - :func:`metrics.DetCurveDisplay.from_predictions` and - :func:`metrics.PrecisionRecallDisplay.from_predictions`. `y_pred` will be removed in - v1.10. - By :user:`Luis ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/31891.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/31891.fix.rst deleted file mode 100644 index f1f280859a1e5..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/31891.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- `repr` on a scorer which has been created with a `partial` `score_func` now correctly - works and uses the `repr` of the given `partial` object. - By `Adrin Jalali`_. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/32047.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/32047.enhancement.rst deleted file mode 100644 index 7fcad9a062ce7..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/32047.enhancement.rst +++ /dev/null @@ -1,9 +0,0 @@ -- Improved the error message for sparse inputs for the following metrics: - :func:`metrics.accuracy_score`, - :func:`metrics.multilabel_confusion_matrix`, :func:`metrics.jaccard_score`, - :func:`metrics.zero_one_loss`, :func:`metrics.f1_score`, - :func:`metrics.fbeta_score`, :func:`metrics.precision_recall_fscore_support`, - :func:`metrics.class_likelihood_ratios`, :func:`metrics.precision_score`, - :func:`metrics.recall_score`, :func:`metrics.classification_report`, - :func:`metrics.hamming_loss`. - By :user:`Lucy Liu `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/32310.api.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/32310.api.rst deleted file mode 100644 index ae7fc385b3bcc..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/32310.api.rst +++ /dev/null @@ -1,3 +0,0 @@ -- The `estimator_name` parameter is deprecated in favour of `name` in - :class:`metrics.PrecisionRecallDisplay` and will be removed in 1.10. - By :user:`Lucy Liu `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/32313.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/32313.fix.rst deleted file mode 100644 index b8f0fc21660da..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/32313.fix.rst +++ /dev/null @@ -1,5 +0,0 @@ -- kwargs specified in the `curve_kwargs` parameter of - :meth:`metrics.RocCurveDisplay.from_cv_results` now only overwrite their corresponding - default value before being passed to Matplotlib's `plot`. Previously, passing any - `curve_kwargs` would overwrite all default kwargs. - By :user:`Lucy Liu `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/32356.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/32356.efficiency.rst deleted file mode 100644 index 03b3e41f67911..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/32356.efficiency.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Avoid redundant input validation in :func:`metrics.d2_log_loss_score` - leading to a 1.2x speedup in large scale benchmarks. - By :user:`Olivier Grisel ` and :user:`Omar Salman ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/32356.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/32356.fix.rst deleted file mode 100644 index ac611096234b6..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/32356.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- Registered named scorer objects for :func:`metrics.d2_brier_score` and - :func:`metrics.d2_log_loss_score` and updated their input validation to be - consistent with related metric functions. - By :user:`Olivier Grisel ` and :user:`Omar Salman ` diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/32372.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/32372.fix.rst deleted file mode 100644 index 5fa8d2204b312..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/32372.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :meth:`metrics.RocCurveDisplay.from_cv_results` will now infer `pos_label` as - `estimator.classes_[-1]`, using the estimator from `cv_results`, when - `pos_label=None`. Previously, an error was raised when `pos_label=None`. - By :user:`Lucy Liu `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/32549.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/32549.fix.rst deleted file mode 100644 index 070e3d1e7fefe..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.metrics/32549.fix.rst +++ /dev/null @@ -1,7 +0,0 @@ -- All classification metrics now raise a `ValueError` when required input arrays - (`y_pred`, `y_true`, `y1`, `y2`, `pred_decision`, or `y_proba`) are empty. - Previously, `accuracy_score`, `class_likelihood_ratios`, `classification_report`, - `confusion_matrix`, `hamming_loss`, `jaccard_score`, `matthews_corrcoef`, - `multilabel_confusion_matrix`, and `precision_recall_fscore_support` did not raise - this error consistently. - By :user:`Stefanie Senger `. diff --git a/doc/whats_new/upcoming_changes/sklearn.model_selection/32265.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.model_selection/32265.enhancement.rst deleted file mode 100644 index b9c87bfec19d9..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.model_selection/32265.enhancement.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`model_selection.StratifiedShuffleSplit` will now specify which classes - have too few members when raising a ``ValueError`` if any class has less than 2 members. - This is useful to identify which classes are causing the error. - By :user:`Marc Bresson ` diff --git a/doc/whats_new/upcoming_changes/sklearn.model_selection/32540.fix.rst b/doc/whats_new/upcoming_changes/sklearn.model_selection/32540.fix.rst deleted file mode 100644 index ec15ecccee161..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.model_selection/32540.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Fix shuffle behaviour in :class:`model_selection.StratifiedGroupKFold`. Now - stratification among folds is also preserved when `shuffle=True`. - By :user:`Pau Folch `. diff --git a/doc/whats_new/upcoming_changes/sklearn.multiclass/15504.fix.rst b/doc/whats_new/upcoming_changes/sklearn.multiclass/15504.fix.rst deleted file mode 100644 index 177a7309ae3f3..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.multiclass/15504.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Fix tie-breaking behavior in :class:`multiclass.OneVsRestClassifier` to match - `np.argmax` tie-breaking behavior. - By :user:`Lakshmi Krishnan `. diff --git a/doc/whats_new/upcoming_changes/sklearn.naive_bayes/32497.fix.rst b/doc/whats_new/upcoming_changes/sklearn.naive_bayes/32497.fix.rst deleted file mode 100644 index 855dd8c238f4a..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.naive_bayes/32497.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`naive_bayes.GaussianNB` preserves the dtype of the fitted attributes - according to the dtype of `X`. - By :user:`Omar Salman ` diff --git a/doc/whats_new/upcoming_changes/sklearn.preprocessing/28043.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.preprocessing/28043.enhancement.rst deleted file mode 100644 index 8195352292539..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.preprocessing/28043.enhancement.rst +++ /dev/null @@ -1,2 +0,0 @@ -- :class:`preprocessing.SplineTransformer` can now handle missing values with the - parameter `handle_missing`. By :user:`Stefanie Senger `. diff --git a/doc/whats_new/upcoming_changes/sklearn.preprocessing/29307.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.preprocessing/29307.enhancement.rst deleted file mode 100644 index aa9b02400a0c0..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.preprocessing/29307.enhancement.rst +++ /dev/null @@ -1,4 +0,0 @@ -- The :class:`preprocessing.PowerTransformer` now returns a warning - when NaN values are encountered in the inverse transform, `inverse_transform`, typically - caused by extremely skewed data. - By :user:`Roberto Mourao ` \ No newline at end of file diff --git a/doc/whats_new/upcoming_changes/sklearn.preprocessing/31790.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.preprocessing/31790.enhancement.rst deleted file mode 100644 index caabc96b626fd..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.preprocessing/31790.enhancement.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :class:`preprocessing.MaxAbsScaler` can now clip out-of-range values in held-out data - with the parameter `clip`. - By :user:`Hleb Levitski `. diff --git a/doc/whats_new/upcoming_changes/sklearn.preprocessing/32592.fix.rst b/doc/whats_new/upcoming_changes/sklearn.preprocessing/32592.fix.rst deleted file mode 100644 index f22417a3566fb..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.preprocessing/32592.fix.rst +++ /dev/null @@ -1,2 +0,0 @@ -- Fixed a bug in :class:`preprocessing.OneHotEncoder` where `handle_unknown='warn'` incorrectly behaved like `'ignore'` instead of `'infrequent_if_exist'`. - By :user:`Nithurshen ` diff --git a/doc/whats_new/upcoming_changes/sklearn.semi_supervised/31924.fix.rst b/doc/whats_new/upcoming_changes/sklearn.semi_supervised/31924.fix.rst deleted file mode 100644 index fe21593d99680..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.semi_supervised/31924.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- User written kernel results are now normalized in - :class:`semi_supervised.LabelPropagation` - so all row sums equal 1 even if kernel gives asymmetric or non-uniform row sums. - By :user:`Dan Schult `. diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/30041.fix.rst b/doc/whats_new/upcoming_changes/sklearn.tree/30041.fix.rst deleted file mode 100644 index 98c90e31f36eb..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.tree/30041.fix.rst +++ /dev/null @@ -1,2 +0,0 @@ -- Make :func:`tree.export_text` thread-safe. - By :user:`Olivier Grisel `. diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/31036.fix.rst b/doc/whats_new/upcoming_changes/sklearn.tree/31036.fix.rst deleted file mode 100644 index 32e26e180595d..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.tree/31036.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :func:`~sklearn.tree.export_graphviz` now raises a `ValueError` if given feature - names are not all strings. - By :user:`Guilherme Peixoto ` diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/32100.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.tree/32100.efficiency.rst deleted file mode 100644 index 0df37311f22ce..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.tree/32100.efficiency.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :class:`tree.DecisionTreeRegressor` with `criterion="absolute_error"` - now runs much faster: O(n log n) complexity against previous O(n^2) - allowing to scale to millions of data points, even hundred of millions. - By :user:`Arthur Lacote ` diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/32100.fix.rst b/doc/whats_new/upcoming_changes/sklearn.tree/32100.fix.rst deleted file mode 100644 index 7d337131c25e6..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.tree/32100.fix.rst +++ /dev/null @@ -1,6 +0,0 @@ -- :class:`tree.DecisionTreeRegressor` with `criterion="absolute_error"` - would sometimes make sub-optimal splits - (i.e. splits that don't minimize the absolute error). - Now it's fixed. Hence retraining trees might gives slightly different - results. - By :user:`Arthur Lacote ` diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/32259.fix.rst b/doc/whats_new/upcoming_changes/sklearn.tree/32259.fix.rst deleted file mode 100644 index f25f0f2eec483..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.tree/32259.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Fixed a regression in :ref:`decision trees ` where almost constant features were - not handled properly. - By :user:`Sercan Turkmen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/32274.fix.rst b/doc/whats_new/upcoming_changes/sklearn.tree/32274.fix.rst deleted file mode 100644 index 84c1123cf26c8..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.tree/32274.fix.rst +++ /dev/null @@ -1,6 +0,0 @@ -- Fixed splitting logic during training in :class:`tree.DecisionTree*` - (and consequently in :class:`ensemble.RandomForest*`) - for nodes containing near-constant feature values and missing values. - Beforehand, trees were cut short if a constant feature was found, - even if there was more splitting that could be done on the basis of missing values. - By :user:`Arthur Lacote ` diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/32280.fix.rst b/doc/whats_new/upcoming_changes/sklearn.tree/32280.fix.rst deleted file mode 100644 index 5ff0a9b453e77..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.tree/32280.fix.rst +++ /dev/null @@ -1,4 +0,0 @@ -- Fix handling of missing values in method :func:`decision_path` of trees - (:class:`tree.DecisionTreeClassifier`, :class:`tree.DecisionTreeRegressor`, - :class:`tree.ExtraTreeClassifier` and :class:`tree.ExtraTreeRegressor`) - By :user:`Arthur Lacote `. diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/32351.fix.rst b/doc/whats_new/upcoming_changes/sklearn.tree/32351.fix.rst deleted file mode 100644 index 0c422d7a9e14c..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.tree/32351.fix.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Fix decision tree splitting with missing values present in some features. In some cases the last - non-missing sample would not be partitioned correctly. - By :user:`Tim Head ` and :user:`Arthur Lacote `. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst deleted file mode 100644 index 6b9ef89fdd01f..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/31564.enhancement.rst +++ /dev/null @@ -1,5 +0,0 @@ -- The parameter table in the HTML representation of all scikit-learn estimators and - more generally of estimators inheriting from :class:`base.BaseEstimator` - now displays the parameter description as a tooltip and has a link to the online - documentation for each parameter. - By :user:`Dea María Léon `. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/31873.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/31873.enhancement.rst deleted file mode 100644 index 6e82ce3713f5a..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/31873.enhancement.rst +++ /dev/null @@ -1,4 +0,0 @@ -- ``sklearn.utils._check_sample_weight`` now raises a clearer error message when the - provided weights are neither a scalar nor a 1-D array-like of the same size as the - input data. - By :user:`Kapil Parekh `. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/31951.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/31951.enhancement.rst deleted file mode 100644 index 556c406bff7b8..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/31951.enhancement.rst +++ /dev/null @@ -1,4 +0,0 @@ -- :func:`sklearn.utils.estimator_checks.parametrize_with_checks` now lets you configure - strict mode for xfailing checks. Tests that unexpectedly pass will lead to a test - failure. The default behaviour is unchanged. - By :user:`Tim Head `. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/31952.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.utils/31952.efficiency.rst deleted file mode 100644 index f334bfd81c8dd..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/31952.efficiency.rst +++ /dev/null @@ -1,5 +0,0 @@ -- The function :func:`sklearn.utils.extmath.safe_sparse_dot` was improved by a dedicated - Cython routine for the case of `a @ b` with sparse 2-dimensional `a` and `b` and when - a dense output is required, i.e., `dense_output=True`. This improves several - algorithms in scikit-learn when dealing with sparse arrays (or matrices). - By :user:`Christian Lorentzen `. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/31969.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/31969.enhancement.rst deleted file mode 100644 index 079b9c589bc91..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/31969.enhancement.rst +++ /dev/null @@ -1,3 +0,0 @@ -- Fixed the alignment of the "?" and "i" symbols and improved the color style of the - HTML representation of estimators. - By :user:`Guillaume Lemaitre `. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/32258.api.rst b/doc/whats_new/upcoming_changes/sklearn.utils/32258.api.rst deleted file mode 100644 index a8ab5744ddf87..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/32258.api.rst +++ /dev/null @@ -1,3 +0,0 @@ -- :func:`utils.extmath.stable_cumsum` is deprecated and will be removed - in v1.10. Use `np.cumulative_sum` with the desired dtype directly instead. - By :user:`Tiziano Zito `. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/32330.fix.rst b/doc/whats_new/upcoming_changes/sklearn.utils/32330.fix.rst deleted file mode 100644 index c2243ad2f7c3b..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.utils/32330.fix.rst +++ /dev/null @@ -1,2 +0,0 @@ -- Changes the way color are chosen when displaying an estimator as an HTML representation. Colors are not adapted anymore to the user's theme, but chosen based on theme declared color scheme (light or dark) for VSCode and JupyterLab. If theme does not declare a color scheme, scheme is chosen according to default text color of the page, if it fails fallbacks to a media query. - By :user:`Matt J. `. diff --git a/doc/whats_new/v1.8.rst b/doc/whats_new/v1.8.rst index 603373824d395..fa39c6f1fed43 100644 --- a/doc/whats_new/v1.8.rst +++ b/doc/whats_new/v1.8.rst @@ -26,9 +26,680 @@ Version 1.8 .. towncrier release notes start +.. _changes_1_8_0: + +Version 1.8.0 +============= + +**December 2025** + +Changes impacting many modules +------------------------------ + +- |Efficiency| Improved CPU and memory usage in estimators and metric functions that rely on + weighted percentiles and better match NumPy and Scipy (un-weighted) implementations + of percentiles. + By :user:`Lucy Liu ` :pr:`31775` + +Support for Array API +--------------------- + +Additional estimators and functions have been updated to include support for all +`Array API `_ compliant inputs. + +See :ref:`array_api` for more details. + +- |Feature| :class:`sklearn.preprocessing.StandardScaler` now supports Array API compliant inputs. + By :user:`Alexander Fabisch `, :user:`Edoardo Abati `, + :user:`Olivier Grisel ` and :user:`Charles Hill `. :pr:`27113` + +- |Feature| :class:`linear_model.RidgeCV`, :class:`linear_model.RidgeClassifier` and + :class:`linear_model.RidgeClassifierCV` now support array API compatible + inputs with `solver="svd"`. + By :user:`Jérôme Dockès `. :pr:`27961` + +- |Feature| :func:`metrics.pairwise.pairwise_kernels` for any kernel except + "laplacian" and + :func:`metrics.pairwise_distances` for metrics "cosine", + "euclidean" and "l2" now support array API inputs. + By :user:`Emily Chen ` and :user:`Lucy Liu ` :pr:`29822` + +- |Feature| :func:`sklearn.metrics.confusion_matrix` now supports Array API compatible inputs. + By :user:`Stefanie Senger ` :pr:`30562` + +- |Feature| :class:`sklearn.mixture.GaussianMixture` with + `init_params="random"` or `init_params="random_from_data"` and + `warm_start=False` now supports Array API compatible inputs. + By :user:`Stefanie Senger ` and :user:`Loïc Estève ` :pr:`30777` + +- |Feature| :func:`sklearn.metrics.roc_curve` now supports Array API compatible inputs. + By :user:`Thomas Li ` :pr:`30878` + +- |Feature| :class:`preprocessing.PolynomialFeatures` now supports array API compatible inputs. + By :user:`Omar Salman ` :pr:`31580` + +- |Feature| :class:`calibration.CalibratedClassifierCV` now supports array API compatible + inputs with `method="temperature"` and when the underlying `estimator` also + supports the array API. + By :user:`Omar Salman ` :pr:`32246` + +- |Feature| :func:`sklearn.metrics.precision_recall_curve` now supports array API compatible + inputs. + By :user:`Lucy Liu ` :pr:`32249` + +- |Feature| :func:`sklearn.model_selection.cross_val_predict` now supports array API compatible inputs. + By :user:`Omar Salman ` :pr:`32270` + +- |Feature| :func:`sklearn.metrics.brier_score_loss`, :func:`sklearn.metrics.log_loss`, + :func:`sklearn.metrics.d2_brier_score` and :func:`sklearn.metrics.d2_log_loss_score` + now support array API compatible inputs. + By :user:`Omar Salman ` :pr:`32422` + +- |Feature| :class:`naive_bayes.GaussianNB` now supports array API compatible inputs. + By :user:`Omar Salman ` :pr:`32497` + +- |Feature| :class:`preprocessing.LabelBinarizer` and :func:`preprocessing.label_binarize` now + support numeric array API compatible inputs with `sparse_output=False`. + By :user:`Virgil Chan `. :pr:`32582` + +- |Feature| :func:`sklearn.metrics.det_curve` now supports Array API compliant inputs. + By :user:`Josef Affourtit `. :pr:`32586` + +- |Feature| :func:`sklearn.metrics.pairwise.manhattan_distances` now supports array API compatible inputs. + By :user:`Omar Salman `. :pr:`32597` + +- |Feature| :func:`sklearn.metrics.calinski_harabasz_score` now supports Array API compliant inputs. + By :user:`Josef Affourtit `. :pr:`32600` + +- |Feature| :func:`sklearn.metrics.balanced_accuracy_score` now supports array API compatible inputs. + By :user:`Omar Salman `. :pr:`32604` + +- |Feature| :func:`sklearn.metrics.pairwise.laplacian_kernel` now supports array API compatible inputs. + By :user:`Zubair Shakoor `. :pr:`32613` + +- |Feature| :func:`sklearn.metrics.cohen_kappa_score` now supports array API compatible inputs. + By :user:`Omar Salman `. :pr:`32619` + +- |Feature| :func:`sklearn.metrics.cluster.davies_bouldin_score` now supports Array API compliant inputs. + By :user:`Josef Affourtit `. :pr:`32693` + +- |Fix| Estimators with array API support no longer reject dataframe inputs when array API support is enabled. + By :user:`Tim Head ` :pr:`32838` + +Metadata routing +---------------- + +Refer to the :ref:`Metadata Routing User Guide ` for +more details. + +- |Fix| Fixed an issue where passing `sample_weight` to a :class:`Pipeline` inside a + :class:`GridSearchCV` would raise an error with metadata routing enabled. + By `Adrin Jalali`_. :pr:`31898` + +Free-threaded CPython 3.14 support +---------------------------------- + +scikit-learn has support for free-threaded CPython, in particular +free-threaded wheels are available for all of our supported platforms on Python +3.14. + +Free-threaded (also known as nogil) CPython is a version of CPython that aims at +enabling efficient multi-threaded use cases by removing the Global Interpreter +Lock (GIL). + +If you want to try out free-threaded Python, the recommendation is to use +Python 3.14, that has fixed a number of issues compared to Python 3.13. Feel +free to try free-threaded on your use case and report any issues! + +For more details about free-threaded CPython see `py-free-threading doc `_, +in particular `how to install a free-threaded CPython `_ +and `Ecosystem compatibility tracking `_. + +By :user:`Loïc Estève ` and :user:`Olivier Grisel ` and many +other people in the wider Scientific Python and CPython ecosystem, for example +:user:`Nathan Goldbaum `, :user:`Ralf Gommers `, +:user:`Edgar Andrés Margffoy Tuay `. :pr:`32079` + +:mod:`sklearn.base` +------------------- + +- |Feature| Refactored :meth:`dir` in :class:`BaseEstimator` to recognize condition check in :meth:`available_if`. + By :user:`John Hendricks ` and :user:`Miguel Parece `. :pr:`31928` + +- |Fix| Fixed the handling of pandas missing values in HTML display of all estimators. + By :user:`Dea María Léon `. :pr:`32341` + +:mod:`sklearn.calibration` +-------------------------- + +- |Feature| Added temperature scaling method in :class:`calibration.CalibratedClassifierCV`. + By :user:`Virgil Chan ` and :user:`Christian Lorentzen `. :pr:`31068` + +:mod:`sklearn.cluster` +---------------------- + +- |Efficiency| :func:`cluster.kmeans_plusplus` now uses `np.cumsum` directly without extra + numerical stability checks and without casting to `np.float64`. + By :user:`Tiziano Zito ` :pr:`31991` + +- |Fix| The default value of the `copy` parameter in :class:`cluster.HDBSCAN` + will change from `False` to `True` in 1.10 to avoid data modification + and maintain consistency with other estimators. + By :user:`Sarthak Puri `. :pr:`31973` + +:mod:`sklearn.compose` +---------------------- + +- |Fix| The :class:`compose.ColumnTransformer` now correctly fits on data provided as a + `polars.DataFrame` when any transformer has a sparse output. + By :user:`Phillipp Gnan `. :pr:`32188` + +:mod:`sklearn.covariance` +------------------------- + +- |Efficiency| :class:`sklearn.covariance.GraphicalLasso`, + :class:`sklearn.covariance.GraphicalLassoCV` and + :func:`sklearn.covariance.graphical_lasso` with `mode="cd"` profit from the + fit time performance improvement of :class:`sklearn.linear_model.Lasso` by means of + gap safe screening rules. + By :user:`Christian Lorentzen `. :pr:`31987` + +- |Fix| Fixed uncontrollable randomness in :class:`sklearn.covariance.GraphicalLasso`, + :class:`sklearn.covariance.GraphicalLassoCV` and + :func:`sklearn.covariance.graphical_lasso`. For `mode="cd"`, they now use cyclic + coordinate descent. Before, it was random coordinate descent with uncontrollable + random number seeding. + By :user:`Christian Lorentzen `. :pr:`31987` + +- |Fix| Added correction to :class:`covariance.MinCovDet` to adjust for + consistency at the normal distribution. This reduces the bias present + when applying this method to data that is normally distributed. + By :user:`Daniel Herrera-Esposito ` :pr:`32117` + +:mod:`sklearn.decomposition` +---------------------------- + +- |Efficiency| :class:`sklearn.decomposition.DictionaryLearning` and + :class:`sklearn.decomposition.MiniBatchDictionaryLearning` with `fit_algorithm="cd"`, + :class:`sklearn.decomposition.SparseCoder` with `transform_algorithm="lasso_cd"`, + :class:`sklearn.decomposition.MiniBatchSparsePCA`, + :class:`sklearn.decomposition.SparsePCA`, + :func:`sklearn.decomposition.dict_learning` and + :func:`sklearn.decomposition.dict_learning_online` with `method="cd"`, + :func:`sklearn.decomposition.sparse_encode` with `algorithm="lasso_cd"` + all profit from the fit time performance improvement of + :class:`sklearn.linear_model.Lasso` by means of gap safe screening rules. + By :user:`Christian Lorentzen `. :pr:`31987` + +- |Enhancement| :class:`decomposition.SparseCoder` now follows the transformer API of scikit-learn. + In addition, the :meth:`fit` method now validates the input and parameters. + By :user:`François Paugam `. :pr:`32077` + +- |Fix| Add input checks to the `inverse_transform` method of :class:`decomposition.PCA` + and :class:`decomposition.IncrementalPCA`. + :pr:`29310` by :user:`Ian Faust `. :pr:`29310` + +:mod:`sklearn.discriminant_analysis` +------------------------------------ + +- |Feature| Added `solver`, `covariance_estimator` and `shrinkage` in + :class:`discriminant_analysis.QuadraticDiscriminantAnalysis`. + The resulting class is more similar to + :class:`discriminant_analysis.LinearDiscriminantAnalysis` + and allows for more flexibility in the estimation of the covariance matrices. + By :user:`Daniel Herrera-Esposito `. :pr:`32108` + +:mod:`sklearn.ensemble` +----------------------- + +- |Fix| :class:`ensemble.BaggingClassifier`, :class:`ensemble.BaggingRegressor` and + :class:`ensemble.IsolationForest` now use `sample_weight` to draw the samples + instead of forwarding them multiplied by a uniformly sampled mask to the + underlying estimators. Furthermore, when `max_samples` is a float, it is now + interpreted as a fraction of `sample_weight.sum()` instead of `X.shape[0]`. + The new default `max_samples=None` draws `X.shape[0]` samples, irrespective + of `sample_weight`. + By :user:`Antoine Baker `. :pr:`31414` and :pr:`32825` + +:mod:`sklearn.feature_selection` +-------------------------------- + +- |Enhancement| :class:`feature_selection.SelectFromModel` now does not force `max_features` to be + less than or equal to the number of input features. + By :user:`Thibault ` :pr:`31939` + +:mod:`sklearn.gaussian_process` +------------------------------- + +- |Efficiency| make :class:`GaussianProcessRegressor.predict` faster when `return_cov` and + `return_std` are both `False`. + By :user:`Rafael Ayllón Gavilán `. :pr:`31431` + +:mod:`sklearn.linear_model` +--------------------------- + +- |Efficiency| :class:`linear_model.ElasticNet` and :class:`linear_model.Lasso` with + `precompute=False` use less memory for dense `X` and are a bit faster. + Previously, they used twice the memory of `X` even for Fortran-contiguous `X`. + By :user:`Christian Lorentzen ` :pr:`31665` + +- |Efficiency| :class:`linear_model.ElasticNet` and :class:`linear_model.Lasso` avoid + double input checking and are therefore a bit faster. + By :user:`Christian Lorentzen `. :pr:`31848` + +- |Efficiency| :class:`linear_model.ElasticNet`, :class:`linear_model.ElasticNetCV`, + :class:`linear_model.Lasso`, :class:`linear_model.LassoCV`, + :class:`linear_model.MultiTaskElasticNet`, + :class:`linear_model.MultiTaskElasticNetCV`, + :class:`linear_model.MultiTaskLasso` and :class:`linear_model.MultiTaskLassoCV` + are faster to fit by avoiding a BLAS level 1 (axpy) call in the innermost loop. + Same for functions :func:`linear_model.enet_path` and + :func:`linear_model.lasso_path`. + By :user:`Christian Lorentzen ` :pr:`31956` and :pr:`31880` + +- |Efficiency| :class:`linear_model.ElasticNetCV`, :class:`linear_model.LassoCV`, + :class:`linear_model.MultiTaskElasticNetCV` and :class:`linear_model.MultiTaskLassoCV` + avoid an additional copy of `X` with default `copy_X=True`. + By :user:`Christian Lorentzen `. :pr:`31946` + +- |Efficiency| :class:`linear_model.ElasticNet`, :class:`linear_model.ElasticNetCV`, + :class:`linear_model.Lasso`, :class:`linear_model.LassoCV`, + :class:`linear_model.MultiTaskElasticNet`, :class:`linear_model.MultiTaskElasticNetCV` + :class:`linear_model.MultiTaskLasso`, :class:`linear_model.MultiTaskLassoCV` + as well as + :func:`linear_model.lasso_path` and :func:`linear_model.enet_path` now implement + gap safe screening rules in the coordinate descent solver for dense and sparse `X`. + The speedup of fitting time is particularly pronounced (10-times is possible) when + computing regularization paths like the \*CV-variants of the above estimators do. + There is now an additional check of the stopping criterion before entering the main + loop of descent steps. As the stopping criterion requires the computation of the dual + gap, the screening happens whenever the dual gap is computed. + By :user:`Christian Lorentzen ` :pr:`31882`, :pr:`31986`, + :pr:`31987` and :pr:`32014` + +- |Enhancement| :class:`linear_model.ElasticNet`, :class:`linear_model.ElasticNetCV`, + :class:`linear_model.Lasso`, :class:`linear_model.LassoCV`, + :class:`MultiTaskElasticNet`, :class:`MultiTaskElasticNetCV`, + :class:`MultiTaskLasso`, :class:`MultiTaskLassoCV`, as well as + :func:`linear_model.enet_path` and :func:`linear_model.lasso_path` + now use `dual gap <= tol` instead of `dual gap < tol` as stopping criterion. + The resulting coefficients might differ to previous versions of scikit-learn in + rare cases. + By :user:`Christian Lorentzen `. :pr:`31906` + +- |Fix| Fix the convergence criteria for SGD models, to avoid premature convergence when + `tol != None`. This primarily impacts :class:`SGDOneClassSVM` but also affects + :class:`SGDClassifier` and :class:`SGDRegressor`. Before this fix, only the loss + function without penalty was used as the convergence check, whereas now, the full + objective with regularization is used. + By :user:`Guillaume Lemaitre ` and :user:`kostayScr ` :pr:`31856` + +- |Fix| The allowed parameter range for the initial learning rate `eta0` in + :class:`linear_model.SGDClassifier`, :class:`linear_model.SGDOneClassSVM`, + :class:`linear_model.SGDRegressor` and :class:`linear_model.Perceptron` + changed from non-negative numbers to strictly positive numbers. + As a consequence, the default `eta0` of :class:`linear_model.SGDClassifier` + and :class:`linear_model.SGDOneClassSVM` changed from 0 to 0.01. But note that + `eta0` is not used by the default learning rate "optimal" of those two estimators. + By :user:`Christian Lorentzen `. :pr:`31933` + +- |Fix| :class:`linear_model.LogisticRegressionCV` is able to handle CV splits where + some class labels are missing in some folds. Before, it raised an error whenever a + class label were missing in a fold. + By :user:`Christian Lorentzen `. :pr:`32747` + +- |API| :class:`linear_model.PassiveAggressiveClassifier` and + :class:`linear_model.PassiveAggressiveRegressor` are deprecated and will be removed + in 1.10. Equivalent estimators are available with :class:`linear_model.SGDClassifier` + and :class:`SGDRegressor`, both of which expose the options `learning_rate="pa1"` and + `"pa2"`. The parameter `eta0` can be used to specify the aggressiveness parameter of + the Passive-Aggressive-Algorithms, called C in the reference paper. + By :user:`Christian Lorentzen ` :pr:`31932` and :pr:`29097` + +- |API| :class:`linear_model.SGDClassifier`, :class:`linear_model.SGDRegressor`, and + :class:`linear_model.SGDOneClassSVM` now deprecate negative values for the + `power_t` parameter. Using a negative value will raise a warning in version 1.8 + and will raise an error in version 1.10. A value in the range [0.0, inf) must be used + instead. + By :user:`Ritvi Alagusankar ` :pr:`31474` + +- |API| Raising error in :class:`sklearn.linear_model.LogisticRegression` when + liblinear solver is used and input X values are larger than 1e30, + the liblinear solver freezes otherwise. + By :user:`Shruti Nath `. :pr:`31888` + +- |API| :class:`linear_model.LogisticRegressionCV` got a new parameter + `use_legacy_attributes` to control the types and shapes of the fitted attributes + `C_`, `l1_ratio_`, `coefs_paths_`, `scores_` and `n_iter_`. + The current default value `True` keeps the legacy behaviour. If `False` then: + + - ``C_`` is a float. + - ``l1_ratio_`` is a float. + - ``coefs_paths_`` is an ndarray of shape + (n_folds, n_l1_ratios, n_cs, n_classes, n_features). + For binary problems (n_classes=2), the 2nd last dimension is 1. + - ``scores_`` is an ndarray of shape (n_folds, n_l1_ratios, n_cs). + - ``n_iter_`` is an ndarray of shape (n_folds, n_l1_ratios, n_cs). + + In version 1.10, the default will change to `False` and `use_legacy_attributes` will + be deprecated. In 1.12 `use_legacy_attributes` will be removed. + By :user:`Christian Lorentzen `. :pr:`32114` + +- |API| Parameter `penalty` of :class:`linear_model.LogisticRegression` and + :class:`linear_model.LogisticRegressionCV` is deprecated and will be removed in + version 1.10. The equivalent behaviour can be obtained as follows: + + - for :class:`linear_model.LogisticRegression` + + - use `l1_ratio=0` instead of `penalty="l2"` + - use `l1_ratio=1` instead of `penalty="l1"` + - use `0`. :pr:`32659` + +- |API| The `n_jobs` parameter of :class:`linear_model.LogisticRegression` is deprecated and + will be removed in 1.10. It has no effect since 1.8. + By :user:`Loïc Estève `. :pr:`32742` + +:mod:`sklearn.manifold` +----------------------- + +- |MajorFeature| :class:`manifold.ClassicalMDS` was implemented to perform classical MDS + (eigendecomposition of the double-centered distance matrix). + By :user:`Dmitry Kobak ` and :user:`Meekail Zain ` :pr:`31322` + +- |Feature| :class:`manifold.MDS` now supports arbitrary distance metrics + (via `metric` and `metric_params` parameters) and + initialization via classical MDS (via `init` parameter). + The `dissimilarity` parameter was deprecated. The old `metric` parameter + was renamed into `metric_mds`. + By :user:`Dmitry Kobak ` :pr:`32229` + +- |Feature| :class:`manifold.TSNE` now supports PCA initialization with sparse input matrices. + By :user:`Arturo Amor `. :pr:`32433` + +:mod:`sklearn.metrics` +---------------------- + +- |Feature| :func:`metrics.d2_brier_score` has been added which calculates the D^2 for the Brier score. + By :user:`Omar Salman `. :pr:`28971` + +- |Feature| Add :func:`metrics.confusion_matrix_at_thresholds` function that returns the number of + true negatives, false positives, false negatives and true positives per threshold. + By :user:`Success Moses `. :pr:`30134` + +- |Efficiency| Avoid redundant input validation in :func:`metrics.d2_log_loss_score` + leading to a 1.2x speedup in large scale benchmarks. + By :user:`Olivier Grisel ` and :user:`Omar Salman ` :pr:`32356` + +- |Enhancement| :func:`metrics.median_absolute_error` now supports Array API compatible inputs. + By :user:`Lucy Liu `. :pr:`31406` + +- |Enhancement| Improved the error message for sparse inputs for the following metrics: + :func:`metrics.accuracy_score`, + :func:`metrics.multilabel_confusion_matrix`, :func:`metrics.jaccard_score`, + :func:`metrics.zero_one_loss`, :func:`metrics.f1_score`, + :func:`metrics.fbeta_score`, :func:`metrics.precision_recall_fscore_support`, + :func:`metrics.class_likelihood_ratios`, :func:`metrics.precision_score`, + :func:`metrics.recall_score`, :func:`metrics.classification_report`, + :func:`metrics.hamming_loss`. + By :user:`Lucy Liu `. :pr:`32047` + +- |Fix| :func:`metrics.median_absolute_error` now uses `_averaged_weighted_percentile` + instead of `_weighted_percentile` to calculate median when `sample_weight` is not + `None`. This is equivalent to using the "averaged_inverted_cdf" instead of + the "inverted_cdf" quantile method, which gives results equivalent to `numpy.median` + if equal weights used. + By :user:`Lucy Liu ` :pr:`30787` + +- |Fix| Additional `sample_weight` checking has been added to + :func:`metrics.accuracy_score`, + :func:`metrics.balanced_accuracy_score`, + :func:`metrics.brier_score_loss`, + :func:`metrics.class_likelihood_ratios`, + :func:`metrics.classification_report`, + :func:`metrics.cohen_kappa_score`, + :func:`metrics.confusion_matrix`, + :func:`metrics.f1_score`, + :func:`metrics.fbeta_score`, + :func:`metrics.hamming_loss`, + :func:`metrics.jaccard_score`, + :func:`metrics.matthews_corrcoef`, + :func:`metrics.multilabel_confusion_matrix`, + :func:`metrics.precision_recall_fscore_support`, + :func:`metrics.precision_score`, + :func:`metrics.recall_score` and + :func:`metrics.zero_one_loss`. + `sample_weight` can only be 1D, consistent to `y_true` and `y_pred` in length,and + all values must be finite and not complex. + By :user:`Lucy Liu `. :pr:`31701` + +- |Fix| `y_pred` is deprecated in favour of `y_score` in + :func:`metrics.DetCurveDisplay.from_predictions` and + :func:`metrics.PrecisionRecallDisplay.from_predictions`. `y_pred` will be removed in + v1.10. + By :user:`Luis ` :pr:`31764` + +- |Fix| `repr` on a scorer which has been created with a `partial` `score_func` now correctly + works and uses the `repr` of the given `partial` object. + By `Adrin Jalali`_. :pr:`31891` + +- |Fix| kwargs specified in the `curve_kwargs` parameter of + :meth:`metrics.RocCurveDisplay.from_cv_results` now only overwrite their corresponding + default value before being passed to Matplotlib's `plot`. Previously, passing any + `curve_kwargs` would overwrite all default kwargs. + By :user:`Lucy Liu `. :pr:`32313` + +- |Fix| Registered named scorer objects for :func:`metrics.d2_brier_score` and + :func:`metrics.d2_log_loss_score` and updated their input validation to be + consistent with related metric functions. + By :user:`Olivier Grisel ` and :user:`Omar Salman ` :pr:`32356` + +- |Fix| :meth:`metrics.RocCurveDisplay.from_cv_results` will now infer `pos_label` as + `estimator.classes_[-1]`, using the estimator from `cv_results`, when + `pos_label=None`. Previously, an error was raised when `pos_label=None`. + By :user:`Lucy Liu `. :pr:`32372` + +- |Fix| All classification metrics now raise a `ValueError` when required input arrays + (`y_pred`, `y_true`, `y1`, `y2`, `pred_decision`, or `y_proba`) are empty. + Previously, `accuracy_score`, `class_likelihood_ratios`, `classification_report`, + `confusion_matrix`, `hamming_loss`, `jaccard_score`, `matthews_corrcoef`, + `multilabel_confusion_matrix`, and `precision_recall_fscore_support` did not raise + this error consistently. + By :user:`Stefanie Senger `. :pr:`32549` + +- |API| :func:`metrics.cluster.entropy` is deprecated and will be removed in v1.10. + By :user:`Lucy Liu ` :pr:`31294` + +- |API| The `estimator_name` parameter is deprecated in favour of `name` in + :class:`metrics.PrecisionRecallDisplay` and will be removed in 1.10. + By :user:`Lucy Liu `. :pr:`32310` + +:mod:`sklearn.model_selection` +------------------------------ + +- |Enhancement| :class:`model_selection.StratifiedShuffleSplit` will now specify which classes + have too few members when raising a ``ValueError`` if any class has less than 2 members. + This is useful to identify which classes are causing the error. + By :user:`Marc Bresson ` :pr:`32265` + +- |Fix| Fix shuffle behaviour in :class:`model_selection.StratifiedGroupKFold`. Now + stratification among folds is also preserved when `shuffle=True`. + By :user:`Pau Folch `. :pr:`32540` + +:mod:`sklearn.multiclass` +------------------------- + +- |Fix| Fix tie-breaking behavior in :class:`multiclass.OneVsRestClassifier` to match + `np.argmax` tie-breaking behavior. + By :user:`Lakshmi Krishnan `. :pr:`15504` + +:mod:`sklearn.naive_bayes` +-------------------------- + +- |Fix| :class:`naive_bayes.GaussianNB` preserves the dtype of the fitted attributes + according to the dtype of `X`. + By :user:`Omar Salman ` :pr:`32497` + +:mod:`sklearn.preprocessing` +---------------------------- + +- |Enhancement| :class:`preprocessing.SplineTransformer` can now handle missing values with the + parameter `handle_missing`. By :user:`Stefanie Senger `. :pr:`28043` + +- |Enhancement| The :class:`preprocessing.PowerTransformer` now returns a warning + when NaN values are encountered in the inverse transform, `inverse_transform`, typically + caused by extremely skewed data. + By :user:`Roberto Mourao ` :pr:`29307` + +- |Enhancement| :class:`preprocessing.MaxAbsScaler` can now clip out-of-range values in held-out data + with the parameter `clip`. + By :user:`Hleb Levitski `. :pr:`31790` + +- |Fix| Fixed a bug in :class:`preprocessing.OneHotEncoder` where `handle_unknown='warn'` incorrectly behaved like `'ignore'` instead of `'infrequent_if_exist'`. + By :user:`Nithurshen ` :pr:`32592` + +:mod:`sklearn.semi_supervised` +------------------------------ + +- |Fix| User written kernel results are now normalized in + :class:`semi_supervised.LabelPropagation` + so all row sums equal 1 even if kernel gives asymmetric or non-uniform row sums. + By :user:`Dan Schult `. :pr:`31924` + +:mod:`sklearn.tree` +------------------- + +- |Efficiency| :class:`tree.DecisionTreeRegressor` with `criterion="absolute_error"` + now runs much faster: O(n log n) complexity against previous O(n^2) + allowing to scale to millions of data points, even hundred of millions. + By :user:`Arthur Lacote ` :pr:`32100` + +- |Fix| Make :func:`tree.export_text` thread-safe. + By :user:`Olivier Grisel `. :pr:`30041` + +- |Fix| :func:`~sklearn.tree.export_graphviz` now raises a `ValueError` if given feature + names are not all strings. + By :user:`Guilherme Peixoto ` :pr:`31036` + +- |Fix| :class:`tree.DecisionTreeRegressor` with `criterion="absolute_error"` + would sometimes make sub-optimal splits + (i.e. splits that don't minimize the absolute error). + Now it's fixed. Hence retraining trees might gives slightly different + results. + By :user:`Arthur Lacote ` :pr:`32100` + +- |Fix| Fixed a regression in :ref:`decision trees ` where almost constant features were + not handled properly. + By :user:`Sercan Turkmen `. :pr:`32259` + +- |Fix| Fixed splitting logic during training in :class:`tree.DecisionTree*` + (and consequently in :class:`ensemble.RandomForest*`) + for nodes containing near-constant feature values and missing values. + Beforehand, trees were cut short if a constant feature was found, + even if there was more splitting that could be done on the basis of missing values. + By :user:`Arthur Lacote ` :pr:`32274` + +- |Fix| Fix handling of missing values in method :func:`decision_path` of trees + (:class:`tree.DecisionTreeClassifier`, :class:`tree.DecisionTreeRegressor`, + :class:`tree.ExtraTreeClassifier` and :class:`tree.ExtraTreeRegressor`) + By :user:`Arthur Lacote `. :pr:`32280` + +- |Fix| Fix decision tree splitting with missing values present in some features. In some cases the last + non-missing sample would not be partitioned correctly. + By :user:`Tim Head ` and :user:`Arthur Lacote `. :pr:`32351` + +:mod:`sklearn.utils` +-------------------- + +- |Efficiency| The function :func:`sklearn.utils.extmath.safe_sparse_dot` was improved by a dedicated + Cython routine for the case of `a @ b` with sparse 2-dimensional `a` and `b` and when + a dense output is required, i.e., `dense_output=True`. This improves several + algorithms in scikit-learn when dealing with sparse arrays (or matrices). + By :user:`Christian Lorentzen `. :pr:`31952` + +- |Enhancement| The parameter table in the HTML representation of all scikit-learn estimators and + more generally of estimators inheriting from :class:`base.BaseEstimator` + now displays the parameter description as a tooltip and has a link to the online + documentation for each parameter. + By :user:`Dea María Léon `. :pr:`31564` + +- |Enhancement| ``sklearn.utils._check_sample_weight`` now raises a clearer error message when the + provided weights are neither a scalar nor a 1-D array-like of the same size as the + input data. + By :user:`Kapil Parekh `. :pr:`31873` + +- |Enhancement| :func:`sklearn.utils.estimator_checks.parametrize_with_checks` now lets you configure + strict mode for xfailing checks. Tests that unexpectedly pass will lead to a test + failure. The default behaviour is unchanged. + By :user:`Tim Head `. :pr:`31951` + +- |Enhancement| Fixed the alignment of the "?" and "i" symbols and improved the color style of the + HTML representation of estimators. + By :user:`Guillaume Lemaitre `. :pr:`31969` + +- |Fix| Changes the way color are chosen when displaying an estimator as an HTML representation. Colors are not adapted anymore to the user's theme, but chosen based on theme declared color scheme (light or dark) for VSCode and JupyterLab. If theme does not declare a color scheme, scheme is chosen according to default text color of the page, if it fails fallbacks to a media query. + By :user:`Matt J. `. :pr:`32330` + +- |API| :func:`utils.extmath.stable_cumsum` is deprecated and will be removed + in v1.10. Use `np.cumulative_sum` with the desired dtype directly instead. + By :user:`Tiziano Zito `. :pr:`32258` + .. rubric:: Code and documentation contributors Thanks to everyone who has contributed to the maintenance and improvement of the project since version 1.7, including: -TODO: update at the time of the release. +$id, 4hm3d, Acciaro Gennaro Daniele, achyuthan.s, Adam J. Stewart, Adriano +Leão, Adrien Linares, Adrin Jalali, Aitsaid Azzedine Idir, Alexander Fabisch, +Alexandre Abraham, Andrés H. Zapke, Anne Beyer, Anthony Gitter, AnthonyPrudent, +antoinebaker, Arpan Mukherjee, Arthur, Arthur Lacote, Arturo Amor, +ayoub.agouzoul, Ayrat, Ayush, Ayush Tanwar, Basile Jezequel, Bhavya Patwa, +BRYANT MUSI BABILA, Casey Heath, Chems Ben, Christian Lorentzen, Christian +Veenhuis, Christine P. Chai, cstec, C. Titus Brown, Daniel Herrera-Esposito, +Dan Schult, dbXD320, Dea María Léon, Deepyaman Datta, dependabot[bot], Dhyey +Findoriya, Dimitri Papadopoulos Orfanos, Dipak Dhangar, Dmitry Kobak, +elenafillo, Elham Babaei, EmilyXinyi, Emily (Xinyi) Chen, Eugen-Bleck, Evgeni +Burovski, fabarca, Fabrizio Damicelli, Faizan-Ul Huda, François Goupil, +François Paugam, Gaetan, GaetandeCast, Gesa Loof, Gonçalo Guiomar, Gordon Grey, +Gowtham Kumar K., Guilherme Peixoto, Guillaume Lemaitre, hakan çanakçı, Harshil +Sanghvi, Henri Bonamy, Hleb Levitski, HulusiOzy, hvtruong, Ian Faust, Imad +Saddik, Jérémie du Boisberranger, Jérôme Dockès, John Hendricks, Joris Van den +Bossche, Josef Affourtit, Josh, jshn9515, Junaid, KALLA GANASEKHAR, Kapil +Parekh, Kenneth Enevoldsen, Kian Eliasi, kostayScr, Krishnan Vignesh, kryggird, +Kyle S, Lakshmi Krishnan, Leomax, Loic Esteve, Luca Bittarello, Lucas Colley, +Lucy Liu, Luigi Giugliano, Luis, Mahdi Abid, Mahi Dhiman, Maitrey Talware, +Mamduh Zabidi, Manikandan Gobalakrishnan, Marc Bresson, Marco Edward Gorelli, +Marek Pokropiński, Maren Westermann, Marie Sacksick, Marija Vlajic, Matt J., +Mayank Raj, Michael Burkhart, Michael Šimáček, Miguel Fernandes, Miro Hrončok, +Mohamed DHIFALLAH, Muhammad Waseem, MUHAMMED SINAN D, Natalia Mokeeva, Nicholas +Farr, Nicolas Bolle, Nicolas Hug, nithish-74, Nithurshen, Nitin Pratap Singh, +NotAceNinja, Olivier Grisel, omahs, Omar Salman, Patrick Walsh, Peter Holzer, +pfolch, ph-ll-pp, Prashant Bansal, Quan H. Nguyen, Radovenchyk, Rafael Ayllón +Gavilán, Raghvender, Ranjodh Singh, Ravichandranayakar, Remi Gau, Reshama +Shaikh, Richard Harris, RishiP2006, Ritvi Alagusankar, Roberto Mourao, Robert +Pollak, Roshangoli, roychan, R Sagar Shresti, Sarthak Puri, saskra, +scikit-learn-bot, Scott Huberty, Sercan Turkmen, Sergio P, Shashank S, Shaurya +Bisht, Shivam, Shruti Nath, SIKAI ZHANG, sisird864, SiyuJin-1, S. M. Mohiuddin +Khan Shiam, Somdutta Banerjee, sotagg, Sota Goto, Spencer Bradkin, Stefan, +Stefanie Senger, Steffen Rehberg, Steven Hur, Success Moses, Sylvain Combettes, +ThibaultDECO, Thomas J. Fan, Thomas Li, Thomas S., Tim Head, Tingwei Zhu, +Tiziano Zito, TJ Norred, Username46786, Utsab Dahal, Vasanth K, Veghit, +VirenPassi, Virgil Chan, Vivaan Nanavati, Xiao Yuan, xuzhang0327, Yaroslav +Halchenko, Yaswanth Kumar, Zijun yi, zodchi94, Zubair Shakoor From 7f0900c265936eac9a89bba37eb19ee66208d46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Thu, 11 Dec 2025 03:07:51 +0100 Subject: [PATCH 046/462] MNT Update SECURITY.md for 1.8.0 (#32881) --- SECURITY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 9760e345b3e47..961e8e2e195c4 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -4,8 +4,8 @@ | Version | Supported | | ------------- | ------------------ | -| 1.7.2 | :white_check_mark: | -| < 1.7.2 | :x: | +| 1.8.0 | :white_check_mark: | +| < 1.8.0 | :x: | ## Reporting a Vulnerability From de3816631818fa905ba14a26c2fa721aa91ffa09 Mon Sep 17 00:00:00 2001 From: Andres Nayeem Mejia <50155815+andresnmejia@users.noreply.github.com> Date: Thu, 11 Dec 2025 21:47:11 -0500 Subject: [PATCH 047/462] Fix typo in cross-validation definition (#32890) --- doc/glossary.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/glossary.rst b/doc/glossary.rst index 1f214a11b7320..2a03332c34f1a 100644 --- a/doc/glossary.rst +++ b/doc/glossary.rst @@ -231,7 +231,7 @@ General Concepts cross validation A resampling method that iteratively partitions data into mutually exclusive 'train' and 'test' subsets so model performance can be - evaluated on unseen data. This conserves data as avoids the need to hold + evaluated on unseen data. This conserves data as it avoids the need to hold out a 'validation' dataset and accounts for variability as multiple rounds of cross validation are generally performed. See :ref:`User Guide ` for more details. From 92fb813359bf27a4abe8ac1caec0d9cad9256959 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Fri, 12 Dec 2025 10:19:17 +0100 Subject: [PATCH 048/462] FIX activate gap safe screening in MultiTaskElasticNet and MultiTaskLasso (#32842) --- sklearn/linear_model/_coordinate_descent.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index efa5a76adfad5..5fc734c33a078 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -2763,6 +2763,7 @@ def fit(self, X, y): self.tol, check_random_state(self.random_state), random, + do_screening=True, ) # account for different objective scaling here and in cd_fast From b5f8f1c6aadd97a5eb0f76b40f0a797b434b4f0b Mon Sep 17 00:00:00 2001 From: Virgil Chan Date: Fri, 12 Dec 2025 02:58:18 -0800 Subject: [PATCH 049/462] ENH add Array API support for `d2_pinball_score` and `d2_absolute_error_score` (#31671) Co-authored-by: Olivier Grisel --- doc/modules/array_api.rst | 2 + .../array-api/31671.feature.rst | 3 + .../sklearn.metrics/31671.fix.rst | 8 +++ sklearn/metrics/_regression.py | 67 +++++++++---------- sklearn/metrics/tests/test_common.py | 25 +++++++ 5 files changed, 70 insertions(+), 35 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/31671.feature.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/31671.fix.rst diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index 7771cc92f338c..b3cf4dd7476f0 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -164,8 +164,10 @@ Metrics - :func:`sklearn.metrics.cluster.calinski_harabasz_score` - :func:`sklearn.metrics.cohen_kappa_score` - :func:`sklearn.metrics.confusion_matrix` +- :func:`sklearn.metrics.d2_absolute_error_score` - :func:`sklearn.metrics.d2_brier_score` - :func:`sklearn.metrics.d2_log_loss_score` +- :func:`sklearn.metrics.d2_pinball_score` - :func:`sklearn.metrics.d2_tweedie_score` - :func:`sklearn.metrics.det_curve` - :func:`sklearn.metrics.explained_variance_score` diff --git a/doc/whats_new/upcoming_changes/array-api/31671.feature.rst b/doc/whats_new/upcoming_changes/array-api/31671.feature.rst new file mode 100644 index 0000000000000..f9d6a6aecb0b0 --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/31671.feature.rst @@ -0,0 +1,3 @@ +- :func:`sklearn.metrics.d2_absolute_error_score` and + :func:`sklearn.metrics.d2_pinball_score` now support array API compatible inputs. + By :user:`Virgil Chan `. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/31671.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/31671.fix.rst new file mode 100644 index 0000000000000..9bfcd7827bedd --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.metrics/31671.fix.rst @@ -0,0 +1,8 @@ +- :func:`metrics.d2_pinball_score` and :func:`metrics.d2_absolute_error_score` now + always use the `"averaged_inverted_cdf"` quantile method, both with and + without sample weights. Previously, the `"linear"` quantile method was used only + for the unweighted case leading the surprising discrepancies when comparing the + results with unit weights. Note that all quantile interpolation methods are + asymptotically equivalent in the large sample limit, but this fix can cause score + value changes on small evaluation sets (without weights). + By :user:`Virgil Chan `. diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 955014484fc5d..855912ca2d4a4 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -936,7 +936,7 @@ def median_absolute_error( return float(_average(output_errors, weights=multioutput, xp=xp)) -def _assemble_r2_explained_variance( +def _assemble_fraction_of_explained_deviance( numerator, denominator, n_outputs, multioutput, force_finite, xp, device ): """Common part used by explained variance score and :math:`R^2` score.""" @@ -1121,7 +1121,7 @@ def explained_variance_score( (y_true - y_true_avg) ** 2, weights=sample_weight, axis=0, xp=xp ) - return _assemble_r2_explained_variance( + return _assemble_fraction_of_explained_deviance( numerator=numerator, denominator=denominator, n_outputs=y_true.shape[1], @@ -1300,7 +1300,7 @@ def r2_score( axis=0, ) - return _assemble_r2_explained_variance( + return _assemble_fraction_of_explained_deviance( numerator=numerator, denominator=denominator, n_outputs=y_true.shape[1], @@ -1779,9 +1779,9 @@ def d2_pinball_score( >>> d2_pinball_score(y_true, y_pred) 0.5 >>> d2_pinball_score(y_true, y_pred, alpha=0.9) - 0.772... + 0.666... >>> d2_pinball_score(y_true, y_pred, alpha=0.1) - -1.045... + -1.999... >>> d2_pinball_score(y_true, y_true, alpha=0.1) 1.0 @@ -1803,9 +1803,14 @@ def d2_pinball_score( >>> grid.best_params_ {'fit_intercept': True} """ - _, y_true, y_pred, sample_weight, multioutput = _check_reg_targets( + xp, _, device_ = get_namespace_and_device( y_true, y_pred, sample_weight, multioutput ) + _, y_true, y_pred, sample_weight, multioutput = ( + _check_reg_targets_with_floating_dtype( + y_true, y_pred, sample_weight, multioutput, xp=xp + ) + ) if _num_samples(y_pred) < 2: msg = "D^2 score is not well-defined with less than two samples." @@ -1821,16 +1826,18 @@ def d2_pinball_score( ) if sample_weight is None: - y_quantile = np.tile( - np.percentile(y_true, q=alpha * 100, axis=0), (len(y_true), 1) - ) - else: - y_quantile = np.tile( - _weighted_percentile( - y_true, sample_weight=sample_weight, percentile_rank=alpha * 100 - ), - (len(y_true), 1), - ) + sample_weight = xp.ones([y_true.shape[0]], dtype=y_true.dtype, device=device_) + + y_quantile = xp.tile( + _weighted_percentile( + y_true, + sample_weight=sample_weight, + percentile_rank=alpha * 100, + average=True, + xp=xp, + ), + (y_true.shape[0], 1), + ) denominator = mean_pinball_loss( y_true, @@ -1840,25 +1847,15 @@ def d2_pinball_score( multioutput="raw_values", ) - nonzero_numerator = numerator != 0 - nonzero_denominator = denominator != 0 - valid_score = nonzero_numerator & nonzero_denominator - output_scores = np.ones(y_true.shape[1]) - - output_scores[valid_score] = 1 - (numerator[valid_score] / denominator[valid_score]) - output_scores[nonzero_numerator & ~nonzero_denominator] = 0.0 - - if isinstance(multioutput, str): - if multioutput == "raw_values": - # return scores individually - return output_scores - else: # multioutput == "uniform_average" - # passing None as weights to np.average results in uniform mean - avg_weights = None - else: - avg_weights = multioutput - - return float(np.average(output_scores, weights=avg_weights)) + return _assemble_fraction_of_explained_deviance( + numerator=numerator, + denominator=denominator, + n_outputs=y_true.shape[1], + multioutput=multioutput, + force_finite=True, + xp=xp, + device=device_, + ) @validate_params( diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 34bfbc8b26252..6007a279eedb5 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -148,6 +148,11 @@ "mean_compound_poisson_deviance": partial(mean_tweedie_deviance, power=1.4), "d2_tweedie_score": partial(d2_tweedie_score, power=1.4), "d2_pinball_score": d2_pinball_score, + # The default `alpha=0.5` (median) masks differences between quantile methods, + # so we also test `alpha=0.1` and `alpha=0.9` to ensure correctness + # for non-median quantiles. + "d2_pinball_score_01": partial(d2_pinball_score, alpha=0.1), + "d2_pinball_score_09": partial(d2_pinball_score, alpha=0.9), "d2_absolute_error_score": d2_absolute_error_score, } @@ -492,6 +497,8 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "mean_absolute_percentage_error", "mean_pinball_loss", "d2_pinball_score", + "d2_pinball_score_01", + "d2_pinball_score_09", "d2_absolute_error_score", } @@ -563,6 +570,8 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "mean_compound_poisson_deviance", "d2_tweedie_score", "d2_pinball_score", + "d2_pinball_score_01", + "d2_pinball_score_09", "d2_absolute_error_score", "mean_absolute_percentage_error", } @@ -2358,6 +2367,22 @@ def check_array_api_metric_pairwise(metric, array_namespace, device, dtype_name) check_array_api_regression_metric, check_array_api_regression_metric_multioutput, ], + d2_absolute_error_score: [ + check_array_api_regression_metric, + check_array_api_regression_metric_multioutput, + ], + d2_pinball_score: [ + check_array_api_regression_metric, + check_array_api_regression_metric_multioutput, + ], + partial(d2_pinball_score, alpha=0.1): [ + check_array_api_regression_metric, + check_array_api_regression_metric_multioutput, + ], + partial(d2_pinball_score, alpha=0.9): [ + check_array_api_regression_metric, + check_array_api_regression_metric_multioutput, + ], d2_tweedie_score: [ check_array_api_regression_metric, ], From 6f7eef1ad439914f7620cc11a0252e023d62ae4a Mon Sep 17 00:00:00 2001 From: Omar Salman Date: Fri, 12 Dec 2025 19:30:10 +0500 Subject: [PATCH 050/462] Reverts the screening refactoring in enet_coordinate_descent_gram (#32860) --- sklearn/linear_model/_cd_fast.pyx | 109 +++++++++++------------------- 1 file changed, 41 insertions(+), 68 deletions(-) diff --git a/sklearn/linear_model/_cd_fast.pyx b/sklearn/linear_model/_cd_fast.pyx index c227100ec066e..5ca5160fcb127 100644 --- a/sklearn/linear_model/_cd_fast.pyx +++ b/sklearn/linear_model/_cd_fast.pyx @@ -914,48 +914,6 @@ cdef (floating, floating) gap_enet_gram( return gap, dual_norm_XtA -cdef inline uint32_t screen_features_enet_gram( - const floating[:, ::1] Q, - const floating[::1] XtA, - floating[::1] w, - floating[::1] Qw, - uint32_t[::1] active_set, - uint8_t[::1] excluded_set, - floating alpha, - floating beta, - floating gap, - floating dual_norm_XtA, - uint32_t n_features, -) noexcept nogil: - """Apply gap safe screening for all features within enet_coordinate_descent_gram""" - cdef floating d_j - cdef floating Xj_theta - cdef uint32_t n_active = 0 - # Due to floating point issues, gap might be negative. - cdef floating radius = sqrt(2 * fabs(gap)) / alpha - - for j in range(n_features): - if Q[j, j] == 0: - w[j] = 0 - excluded_set[j] = 1 - continue - - Xj_theta = XtA[j] / fmax(alpha, dual_norm_XtA) # X[:,j] @ dual_theta - d_j = (1 - fabs(Xj_theta)) / sqrt(Q[j, j] + beta) - if d_j <= radius: - # include feature j - active_set[n_active] = j - excluded_set[j] = 0 - n_active += 1 - else: - # Qw -= w[j] * Q[j] # Update Qw = Q @ w - _axpy(n_features, -w[j], &Q[j, 0], 1, &Qw[0], 1) - w[j] = 0 - excluded_set[j] = 1 - - return n_active - - def enet_coordinate_descent_gram( floating[::1] w, floating alpha, @@ -1007,6 +965,9 @@ def enet_coordinate_descent_gram( cdef floating[::1] XtA = np.zeros(n_features, dtype=dtype) cdef floating y_norm2 = np.dot(y, y) + cdef floating d_j + cdef floating radius + cdef floating Xj_theta cdef floating tmp cdef floating w_j cdef floating d_w_max @@ -1050,19 +1011,26 @@ def enet_coordinate_descent_gram( # Gap Safe Screening Rules, see https://arxiv.org/abs/1802.07481, Eq. 11 if do_screening: - n_active = screen_features_enet_gram( - Q=Q, - XtA=XtA, - w=w, - Qw=Qw, - active_set=active_set, - excluded_set=excluded_set, - alpha=alpha, - beta=beta, - gap=gap, - dual_norm_XtA=dual_norm_XtA, - n_features=n_features, - ) + # Due to floating point issues, gap might be negative. + radius = sqrt(2 * fabs(gap)) / alpha + n_active = 0 + for j in range(n_features): + if Q[j, j] == 0: + w[j] = 0 + excluded_set[j] = 1 + continue + Xj_theta = XtA[j] / fmax(alpha, dual_norm_XtA) # X[:,j] @ dual_theta + d_j = (1 - fabs(Xj_theta)) / sqrt(Q[j, j] + beta) + if d_j <= radius: + # include feature j + active_set[n_active] = j + excluded_set[j] = 0 + n_active += 1 + else: + # Qw -= w[j] * Q[j] # Update Qw = Q @ w + _axpy(n_features, -w[j], &Q[j, 0], 1, &Qw[0], 1) + w[j] = 0 + excluded_set[j] = 1 for n_iter in range(max_iter): w_max = 0.0 @@ -1116,19 +1084,24 @@ def enet_coordinate_descent_gram( # Gap Safe Screening Rules, see https://arxiv.org/abs/1802.07481, Eq. 11 if do_screening: - n_active = screen_features_enet_gram( - Q=Q, - XtA=XtA, - w=w, - Qw=Qw, - active_set=active_set, - excluded_set=excluded_set, - alpha=alpha, - beta=beta, - gap=gap, - dual_norm_XtA=dual_norm_XtA, - n_features=n_features, - ) + # Due to floating point issues, gap might be negative. + radius = sqrt(2 * fabs(gap)) / alpha + n_active = 0 + for j in range(n_features): + if excluded_set[j]: + continue + Xj_theta = XtA[j] / fmax(alpha, dual_norm_XtA) # X @ dual_theta + d_j = (1 - fabs(Xj_theta)) / sqrt(Q[j, j] + beta) + if d_j <= radius: + # include feature j + active_set[n_active] = j + excluded_set[j] = 0 + n_active += 1 + else: + # Qw -= w[j] * Q[j] # Update Qw = Q @ w + _axpy(n_features, -w[j], &Q[j, 0], 1, &Qw[0], 1) + w[j] = 0 + excluded_set[j] = 1 else: # for/else, runs if for doesn't end with a `break` From a1cae3ea26d4703f7eedd79464c18e6825c8f2cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= Date: Fri, 12 Dec 2025 15:39:05 +0100 Subject: [PATCH 051/462] ENH Order user-set parameters before default parameters on HTML Display (#32802) --- sklearn/base.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/sklearn/base.py b/sklearn/base.py index b897e5c8f3ea8..2854334450006 100644 --- a/sklearn/base.py +++ b/sklearn/base.py @@ -318,19 +318,30 @@ def is_non_default(param_name, param_value): return False - # reorder the parameters from `self.get_params` using the `__init__` - # signature - remaining_params = [name for name in out if name not in init_default_params] - ordered_out = {name: out[name] for name in init_default_params if name in out} - ordered_out.update({name: out[name] for name in remaining_params}) - - non_default_ls = tuple( - [name for name, value in ordered_out.items() if is_non_default(name, value)] + # Sort parameters so non-default parameters are shown first + unordered_params = { + name: out[name] for name in init_default_params if name in out + } + unordered_params.update( + { + name: value + for name, value in out.items() + if name not in init_default_params + } ) + non_default_params, default_params = [], [] + for name, value in unordered_params.items(): + if is_non_default(name, value): + non_default_params.append(name) + else: + default_params.append(name) + + params = {name: out[name] for name in non_default_params + default_params} + return ParamsDict( - params=ordered_out, - non_default=non_default_ls, + params=params, + non_default=tuple(non_default_params), estimator_class=self.__class__, doc_link=doc_link, ) From c7d040e4f23e7888125de0af52e640329c8b9a5a Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Sun, 14 Dec 2025 07:50:39 +0100 Subject: [PATCH 052/462] TST make pandas warning message regex more generic (#32895) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lucy Liu Co-authored-by: Loïc Estève --- sklearn/preprocessing/tests/test_target_encoder.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sklearn/preprocessing/tests/test_target_encoder.py b/sklearn/preprocessing/tests/test_target_encoder.py index 84f04ec46f343..fca0df3f16d55 100644 --- a/sklearn/preprocessing/tests/test_target_encoder.py +++ b/sklearn/preprocessing/tests/test_target_encoder.py @@ -721,13 +721,12 @@ def test_pandas_copy_on_write(): else: with warnings.catch_warnings(): expected_message = ( - "Copy-on-Write can no longer be disabled, " - "setting to False has no impact. This option will " - "be removed in pandas 4.0." + ".*Copy-on-Write can no longer be disabled.*This option will" + r" be removed in pandas 4\.0" ) warnings.filterwarnings( "ignore", - message=re.escape(expected_message), + message=expected_message, category=DeprecationWarning, ) with pd.option_context("mode.copy_on_write", True): From 3e4a985d3558eaf5ad91876c41da64a88df41be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= Date: Mon, 15 Dec 2025 00:34:12 +0100 Subject: [PATCH 053/462] FIX: Tooltip position using CSS anchor positioning (#32887) --- .../upcoming_changes/sklearn.utils/32887.fix.rst | 6 ++++++ sklearn/utils/_repr_html/params.css | 16 ++++++++++++++++ sklearn/utils/_repr_html/params.py | 5 ++++- sklearn/utils/_repr_html/tests/test_params.py | 10 ++++++++-- 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/32887.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/32887.fix.rst b/doc/whats_new/upcoming_changes/sklearn.utils/32887.fix.rst new file mode 100644 index 0000000000000..765e4f62b9a58 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.utils/32887.fix.rst @@ -0,0 +1,6 @@ +- The parameter table in the HTML representation of all scikit-learn + estimators inheritiging from :class:`base.BaseEstimator`, displays + each parameter documentation as a tooltip. The last tooltip of a + parameter in the last table of any HTML representation was partially hidden. + This issue has been fixed. + By :user:`Dea María Léon ` diff --git a/sklearn/utils/_repr_html/params.css b/sklearn/utils/_repr_html/params.css index 10d1a0a79a68b..c20acdd8d243c 100644 --- a/sklearn/utils/_repr_html/params.css +++ b/sklearn/utils/_repr_html/params.css @@ -83,6 +83,14 @@ a.param-doc-link:visited { padding: .5em; } +@supports(anchor-name: --doc-link) { + a.param-doc-link, + a.param-doc-link:link, + a.param-doc-link:visited { + anchor-name: --doc-link; + } +} + /* "hack" to make the entire area of the cell containing the link clickable */ a.param-doc-link::before { position: absolute; @@ -109,6 +117,14 @@ a.param-doc-link::before { border: thin solid var(--sklearn-color-unfitted-level-3); } +@supports(position-area: center right) { + .param-doc-description { + position-area: center right; + position: fixed; + margin-left: 0; + } +} + /* Fitted state for parameter tooltips */ .fitted .param-doc-description { /* fitted */ diff --git a/sklearn/utils/_repr_html/params.py b/sklearn/utils/_repr_html/params.py index 011dde246198d..2bc523f7d6e17 100644 --- a/sklearn/utils/_repr_html/params.py +++ b/sklearn/utils/_repr_html/params.py @@ -89,9 +89,12 @@ def _params_html_repr(params): PARAM_AVAILABLE_DOC_LINK_TEMPLATE = """ {param_name} - {param_description} + + {param_description} """ estimator_class_docs = inspect.getdoc(params.estimator_class) diff --git a/sklearn/utils/_repr_html/tests/test_params.py b/sklearn/utils/_repr_html/tests/test_params.py index a2fe8d54c0a6d..4cbd1302ee2dd 100644 --- a/sklearn/utils/_repr_html/tests/test_params.py +++ b/sklearn/utils/_repr_html/tests/test_params.py @@ -108,10 +108,13 @@ class MockEstimator: html_param_a = ( r'' r'\s*' r"\s*a" - r'\s*a: int

' + r'\s*\s*a:' + r"\sint

" r"Description of a\.
" r"\s*
" r"\s*" @@ -120,10 +123,13 @@ class MockEstimator: html_param_b = ( r'' r'.*' r"\s*b" - r'\s*b: str

' + r'\s*\s*b:' + r"\sstr

" r"\s*
" r"\s*" ) From 9db90d21440d1712fb073761547b68ae1f98b3a0 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Mon, 15 Dec 2025 22:50:36 +1100 Subject: [PATCH 054/462] TST Add `confusion_matrix_at_thresholds` to common tests (#32883) --- sklearn/metrics/tests/test_common.py | 61 ++++++++++++++++++---------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 6007a279eedb5..6beb495af194b 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -18,6 +18,7 @@ classification_report, cohen_kappa_score, confusion_matrix, + confusion_matrix_at_thresholds, coverage_error, d2_absolute_error_score, d2_brier_score, @@ -161,17 +162,13 @@ "balanced_accuracy_score": balanced_accuracy_score, "adjusted_balanced_accuracy_score": partial(balanced_accuracy_score, adjusted=True), "unnormalized_accuracy_score": partial(accuracy_score, normalize=False), - # `confusion_matrix` returns absolute values and hence behaves unnormalized - # . Naming it with an unnormalized_ prefix is necessary for this module to - # skip sample_weight scaling checks which will fail for unnormalized - # metrics. - "unnormalized_confusion_matrix": confusion_matrix, + "confusion_matrix": confusion_matrix, "normalized_confusion_matrix": lambda *args, **kwargs: ( confusion_matrix(*args, **kwargs).astype("float") / confusion_matrix(*args, **kwargs).sum(axis=1)[:, np.newaxis] ), - "unnormalized_multilabel_confusion_matrix": multilabel_confusion_matrix, - "unnormalized_multilabel_confusion_matrix_sample": partial( + "multilabel_confusion_matrix": multilabel_confusion_matrix, + "multilabel_confusion_matrix_sample": partial( multilabel_confusion_matrix, samplewise=True ), "hamming_loss": hamming_loss, @@ -245,6 +242,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): CURVE_METRICS = { + "confusion_matrix_at_thresholds": confusion_matrix_at_thresholds, "roc_curve": roc_curve, "precision_recall_curve": precision_recall_curve_padded_thresholds, "det_curve": det_curve, @@ -310,7 +308,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "samples_recall_score", "samples_jaccard_score", "coverage_error", - "unnormalized_multilabel_confusion_matrix_sample", + "multilabel_confusion_matrix_sample", "label_ranking_loss", "label_ranking_average_precision_score", "dcg_score", @@ -332,6 +330,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "f2_score", "f0.5_score", # curves + "confusion_matrix_at_thresholds", "roc_curve", "precision_recall_curve", "det_curve", @@ -361,6 +360,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): # Metrics with a "pos_label" argument METRICS_WITH_POS_LABEL = { + "confusion_matrix_at_thresholds", "roc_curve", "precision_recall_curve", "det_curve", @@ -382,7 +382,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): # TODO: Handle multi_class metrics that has a labels argument as well as a # decision function argument. e.g hinge_loss METRICS_WITH_LABELS = { - "unnormalized_confusion_matrix", + "confusion_matrix", "normalized_confusion_matrix", "roc_curve", "precision_recall_curve", @@ -411,8 +411,8 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "macro_precision_score", "macro_recall_score", "macro_jaccard_score", - "unnormalized_multilabel_confusion_matrix", - "unnormalized_multilabel_confusion_matrix_sample", + "multilabel_confusion_matrix", + "multilabel_confusion_matrix_sample", "cohen_kappa_score", "log_loss", "d2_log_loss_score", @@ -475,7 +475,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "micro_precision_score", "micro_recall_score", "micro_jaccard_score", - "unnormalized_multilabel_confusion_matrix", + "multilabel_confusion_matrix", "samples_f0.5_score", "samples_f1_score", "samples_f2_score", @@ -545,8 +545,9 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "adjusted_balanced_accuracy_score", "explained_variance_score", "r2_score", - "unnormalized_confusion_matrix", + "confusion_matrix", "normalized_confusion_matrix", + "confusion_matrix_at_thresholds", "roc_curve", "precision_recall_curve", "det_curve", @@ -559,7 +560,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "weighted_f2_score", "weighted_precision_score", "weighted_jaccard_score", - "unnormalized_multilabel_confusion_matrix", + "multilabel_confusion_matrix", "macro_f0.5_score", "macro_f2_score", "macro_precision_score", @@ -584,6 +585,19 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "weighted_ovo_roc_auc", } +WEIGHT_SCALE_DEPENDENT_METRICS = { + # 'confusion_matrix' metrics returns absolute `tps`, `fps` etc values, which + # are scaled by weights, so will vary e.g., scaling by 3 will result in 3 * `tps` + "confusion_matrix", + "confusion_matrix_at_thresholds", + "multilabel_confusion_matrix", + "multilabel_confusion_matrix_sample", + # Metrics where we set `normalize=False` + "unnormalized_accuracy_score", + "unnormalized_zero_one_loss", + "unnormalized_log_loss", +} + METRICS_REQUIRE_POSITIVE_Y = { "mean_poisson_deviance", "mean_gamma_deviance", @@ -1621,12 +1635,15 @@ def check_sample_weight_invariance(name, metric, y1, y2, sample_weight=None): % (weighted_score_zeroed, weighted_score_subset, name), ) - if not name.startswith("unnormalized"): - # check that the score is invariant under scaling of the weights by a - # common factor - # Due to numerical instability of floating points in `cumulative_sum` in - # `median_absolute_error`, it is not always equivalent when scaling by a float. - scaling_values = [2] if name == "median_absolute_error" else [2, 0.3] + # Check the score is invariant under scaling of weights by a constant factor + if name not in WEIGHT_SCALE_DEPENDENT_METRICS: + # Numerical instability of floating points in `cumulative_sum` in + # `median_absolute_error`, and in `diff` when in calculating collinear points + # and points in between to drop `roc_curve` means they are not always + # equivalent when scaling by a float. + scaling_values = ( + [2] if name in {"median_absolute_error", "roc_curve"} else [2, 0.3] + ) for scaling in scaling_values: assert_allclose( weighted_score, @@ -1724,7 +1741,7 @@ def test_binary_sample_weight_invariance(name): y_pred = random_state.randint(0, 2, size=(n_samples,)) y_score = random_state.random_sample(size=(n_samples,)) metric = ALL_METRICS[name] - if name in CONTINUOUS_CLASSIFICATION_METRICS: + if name in (CONTINUOUS_CLASSIFICATION_METRICS | CURVE_METRICS.keys()): check_sample_weight_invariance(name, metric, y_true, y_score) else: check_sample_weight_invariance(name, metric, y_true, y_pred) @@ -1825,7 +1842,7 @@ def test_no_averaging_labels(): @pytest.mark.parametrize( - "name", sorted(MULTILABELS_METRICS - {"unnormalized_multilabel_confusion_matrix"}) + "name", sorted(MULTILABELS_METRICS - {"multilabel_confusion_matrix"}) ) def test_multilabel_label_permutations_invariance(name): random_state = check_random_state(0) From e4610c6ec809523d64ead99d68bba61d82be5167 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Mon, 15 Dec 2025 15:11:13 +0100 Subject: [PATCH 055/462] ENH add clearer error message when instance is passed instead of class (#32888) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger Co-authored-by: Adrin Jalali --- .../many-modules/32888.enhancement.rst | 4 ++++ sklearn/compose/_column_transformer.py | 1 + .../compose/tests/test_column_transformer.py | 17 +++++++++++++++ sklearn/pipeline.py | 2 ++ sklearn/tests/test_pipeline.py | 21 +++++++++++++++++++ sklearn/utils/metaestimators.py | 8 +++++++ 6 files changed, 53 insertions(+) create mode 100644 doc/whats_new/upcoming_changes/many-modules/32888.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/many-modules/32888.enhancement.rst b/doc/whats_new/upcoming_changes/many-modules/32888.enhancement.rst new file mode 100644 index 0000000000000..09247f7d02ee7 --- /dev/null +++ b/doc/whats_new/upcoming_changes/many-modules/32888.enhancement.rst @@ -0,0 +1,4 @@ +- :class:`pipeline.Pipeline`, :class:`pipeline.FeatureUnion` and + :class:`compose.ColumnTransformer` now raise a clearer + error message when an estimator class is passed instead of an instance. + By :user:`Anne Beyer ` diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index e2c196f84d313..00986f7cf1c1f 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -513,6 +513,7 @@ def _validate_transformers(self): self._validate_names(names) # validate estimators + self._check_estimators_are_instances(transformers) for t in transformers: if t in ("drop", "passthrough"): continue diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index a4c9ba38f460b..7a6f243c14a92 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -93,6 +93,23 @@ def transform(self, X, y=None): raise ValueError("specific message") +@pytest.mark.parametrize( + "transformers", + [ + [("trans1", Trans, [0]), ("trans2", Trans(), [1])], + [("trans1", Trans(), [0]), ("trans2", Trans, [1])], + [("drop", "drop", [0]), ("trans2", Trans, [1])], + [("trans1", Trans, [0]), ("passthrough", "passthrough", [1])], + ], +) +def test_column_transformer_raises_class_not_instance_error(transformers): + # non-regression tests for https://github.com/scikit-learn/scikit-learn/issues/32719 + ct = ColumnTransformer(transformers) + msg = "Expected an estimator instance (.*()), got estimator class instead (.*)." + with pytest.raises(TypeError, match=msg): + ct.fit([[1]]) + + def test_column_transformer(): X_array = np.array([[0, 1, 2], [2, 4, 6]]).T diff --git a/sklearn/pipeline.py b/sklearn/pipeline.py index c0652840ff862..32dc4dd187d84 100644 --- a/sklearn/pipeline.py +++ b/sklearn/pipeline.py @@ -296,6 +296,7 @@ def _validate_steps(self): self._validate_names(names) # validate estimators + self._check_estimators_are_instances(estimators) transformers = estimators[:-1] estimator = estimators[-1] @@ -1698,6 +1699,7 @@ def _validate_transformers(self): self._validate_names(names) # validate estimators + self._check_estimators_are_instances(transformers) for t in transformers: if t in ("drop", "passthrough"): continue diff --git a/sklearn/tests/test_pipeline.py b/sklearn/tests/test_pipeline.py index b2eb7deb4a712..00bddae53d34e 100644 --- a/sklearn/tests/test_pipeline.py +++ b/sklearn/tests/test_pipeline.py @@ -282,6 +282,27 @@ def test_pipeline_invalid_parameters(): assert params == params2 +@pytest.mark.parametrize( + "meta_estimators", + [ + Pipeline([("pca", PCA)]), + Pipeline([("pca", PCA), ("ident", None)]), + Pipeline([("passthrough", "passthrough"), ("pca", PCA)]), + Pipeline([("passthrough", None), ("pca", PCA)]), + Pipeline([("scale", StandardScaler), ("pca", PCA())]), + FeatureUnion([("pca", PCA), ("svd", TruncatedSVD())]), + FeatureUnion([("pca", PCA()), ("svd", TruncatedSVD)]), + FeatureUnion([("drop", "drop"), ("svd", TruncatedSVD)]), + FeatureUnion([("pca", PCA), ("passthrough", "passthrough")]), + ], +) +def test_meta_estimator_raises_class_not_instance_error(meta_estimators): + # non-regression tests for https://github.com/scikit-learn/scikit-learn/issues/32719 + msg = "Expected an estimator instance (.*()), got estimator class instead (.*)." + with pytest.raises(TypeError, match=msg): + meta_estimators.fit([[1]]) + + def test_empty_pipeline(): X = iris.data y = iris.target diff --git a/sklearn/utils/metaestimators.py b/sklearn/utils/metaestimators.py index 1674972772b67..5f2a38f16f96d 100644 --- a/sklearn/utils/metaestimators.py +++ b/sklearn/utils/metaestimators.py @@ -100,6 +100,14 @@ def _validate_names(self, names): "Estimator names must not contain __: got {0!r}".format(invalid_names) ) + def _check_estimators_are_instances(self, estimators): + for estimator in estimators: + if isinstance(estimator, type): + raise TypeError( + "Expected an estimator instance ({estimator.__name__}()), got " + "estimator class instead ({estimator.__name__})." + ) + def _safe_split(estimator, X, y, indices, train_indices=None): """Create subset of dataset and properly handle kernels. From 895ffbf0d44569b6c5895fdd05c943ddfb1cc6b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= Date: Tue, 16 Dec 2025 10:55:35 +0100 Subject: [PATCH 056/462] MNT Remove `unnasign.yml` file to avoid automatic `help wanted` label (#32905) --- .github/workflows/unassign.yml | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 .github/workflows/unassign.yml diff --git a/.github/workflows/unassign.yml b/.github/workflows/unassign.yml deleted file mode 100644 index 94a50d49839d6..0000000000000 --- a/.github/workflows/unassign.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Unassign -#Runs when a contributor has unassigned themselves from the issue and adds 'help wanted' -on: - issues: - types: unassigned - -# Restrict the permissions granted to the use of secrets.GITHUB_TOKEN in this -# github actions workflow: -# https://docs.github.com/en/actions/security-guides/automatic-token-authentication -permissions: - issues: write - -jobs: - one: - runs-on: ubuntu-latest - steps: - - name: - if: github.event.issue.state == 'open' - run: | - echo "Marking issue ${{ github.event.issue.number }} as help wanted" - gh issue edit $ISSUE --add-label "help wanted" - env: - GH_TOKEN: ${{ github.token }} - ISSUE: ${{ github.event.issue.html_url }} From a4db9a9dc45bbd39e397ea4ebf9c5dcc6a658500 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Wed, 17 Dec 2025 14:12:04 +1100 Subject: [PATCH 057/462] DOC Add reference to user guide for `MultiLabelBinarizer` (#32894) --- doc/modules/preprocessing_targets.rst | 2 ++ sklearn/preprocessing/_label.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/doc/modules/preprocessing_targets.rst b/doc/modules/preprocessing_targets.rst index f8035bc059af4..c0d3769b69263 100644 --- a/doc/modules/preprocessing_targets.rst +++ b/doc/modules/preprocessing_targets.rst @@ -41,6 +41,8 @@ that support the label indicator matrix format. For more information about multiclass classification, refer to :ref:`multiclass_classification`. +.. _multilabelbinarizer: + MultiLabelBinarizer ------------------- diff --git a/sklearn/preprocessing/_label.py b/sklearn/preprocessing/_label.py index 5a0e254ba5849..2d9d57df94c55 100644 --- a/sklearn/preprocessing/_label.py +++ b/sklearn/preprocessing/_label.py @@ -800,6 +800,8 @@ class MultiLabelBinarizer(TransformerMixin, BaseEstimator, auto_wrap_output_keys intuitive format and the supported multilabel format: a (samples x classes) binary matrix indicating the presence of a class label. + Read more in the :ref:`User Guide `. + Parameters ---------- classes : array-like of shape (n_classes,), default=None From 15da556eb10a122113a3c854d327319b7e3f6fa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Wed, 17 Dec 2025 18:09:18 +0100 Subject: [PATCH 058/462] CI: Make one tracking isssue per build for the unit-tests GHA (#32832) --- .github/workflows/unit-tests.yml | 27 +++++++++++----- .github/workflows/update_tracking_issue.yml | 2 +- maint_tools/update_tracking_issue.py | 35 ++++++++++++++++++--- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 008e32b1acb48..5d91ee3ad2217 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -205,11 +205,22 @@ jobs: token: ${{ secrets.CODECOV_TOKEN }} disable_search: true - update-tracker: - uses: ./.github/workflows/update_tracking_issue.yml - if: ${{ always() }} - needs: [unit-tests] - with: - job_status: ${{ needs.unit-tests.result }} - secrets: - BOT_GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} + - name: Update tracking issue + if: ${{ always() && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')}} + run: | + set -ex + if [[ ${{ job.status }} == "success" ]]; then + TESTS_PASSED=true + else + TESTS_PASSED=false + fi + + pip install defusedxml PyGithub + python maint_tools/update_tracking_issue.py \ + ${{ secrets.BOT_GITHUB_TOKEN }} \ + "$GITHUB_WORKFLOW ${{ matrix.name }}" \ + "$GITHUB_REPOSITORY" \ + https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID \ + --tests-passed $TESTS_PASSED \ + --auto-close false \ + --job-name "${{ matrix.name }}" diff --git a/.github/workflows/update_tracking_issue.yml b/.github/workflows/update_tracking_issue.yml index 00db4f4493cbd..e130f3847864d 100644 --- a/.github/workflows/update_tracking_issue.yml +++ b/.github/workflows/update_tracking_issue.yml @@ -27,7 +27,7 @@ on: jobs: update_tracking_issue: runs-on: ubuntu-latest - if: github.repository == 'scikit-learn/scikit-learn' && github.event_name == 'schedule' + if: github.repository == 'scikit-learn/scikit-learn' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') steps: - uses: actions/checkout@v5 - uses: actions/setup-python@v6 diff --git a/maint_tools/update_tracking_issue.py b/maint_tools/update_tracking_issue.py index 6a02c48d24bf6..8de186bed2f68 100644 --- a/maint_tools/update_tracking_issue.py +++ b/maint_tools/update_tracking_issue.py @@ -13,6 +13,7 @@ import argparse import sys +import warnings from datetime import datetime, timezone from pathlib import Path @@ -28,12 +29,21 @@ parser.add_argument("ci_name", help="Name of CI run instance") parser.add_argument("issue_repo", help="Repo to track issues") parser.add_argument("link_to_ci_run", help="URL to link to") +parser.add_argument( + "--job-name", + help=( + "Name of the job. If provided the job ID will be added to the log URL so that" + " it points to log of the job and not the whole workflow." + ), + default=None, +) parser.add_argument("--junit-file", help="JUnit file to determine if tests passed") parser.add_argument( "--tests-passed", help=( "If --tests-passed is true, then the original issue is closed if the issue " - "exists. If tests-passed is false, then the an issue is updated or created." + "exists, unless --auto-close is set to false. If tests-passed is false, then " + "the issue is updated or created." ), ) parser.add_argument( @@ -62,6 +72,23 @@ title_query = f"CI failed on {args.ci_name}" title = f"⚠️ {title_query} (last failure: {date_str}) ⚠️" +url = args.link_to_ci_run + +if args.job_name is not None: + run_id = int(args.link_to_ci_run.split("/")[-1]) + workflow_run = issue_repo.get_workflow_run(run_id) + jobs = workflow_run.jobs() + + for job in jobs: + if job.name == args.job_name: + url = f"{url}/job/{job.id}" + break + else: + warnings.warn( + f"Job '{args.job_name}' not found, the URL in the issue will link to the" + " whole workflow's log rather than the job's one." + ) + def get_issue(): login = gh.get_user().login @@ -76,7 +103,7 @@ def get_issue(): def create_or_update_issue(body=""): # Interact with GitHub API to create issue - link = f"[{args.ci_name}]({args.link_to_ci_run})" + link = f"[{args.ci_name}]({url})" issue = get_issue() max_body_length = 60_000 @@ -107,9 +134,7 @@ def close_issue_if_opened(): issue = get_issue() if issue is not None: header_str = "## CI is no longer failing!" - comment_str = ( - f"{header_str} ✅\n\n[Successful run]({args.link_to_ci_run}) on {date_str}" - ) + comment_str = f"{header_str} ✅\n\n[Successful run]({url}) on {date_str}" print(f"Commented on issue #{issue.number}") # New comment if "## CI is no longer failing!" comment does not exist From e8642f721c42bfe591feb36ed49c222241baace9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Thu, 18 Dec 2025 10:04:02 +0100 Subject: [PATCH 059/462] MNT Use consistent ruff version in pre-commit and linting (#32849) --- .pre-commit-config.yaml | 2 ++ benchmarks/bench_tsne_mnist.py | 2 +- doc/developers/development_setup.rst | 12 ++++++------ pyproject.toml | 2 +- sklearn/_min_dependencies.py | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8bdb3e9eefd36..4c9be22b6a660 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,8 @@ repos: - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit + # WARNING if you update ruff version here, remember to update + # sklearn/_min_dependencies.py and doc .rst files mentioning ruff== rev: v0.12.2 hooks: - id: ruff-check diff --git a/benchmarks/bench_tsne_mnist.py b/benchmarks/bench_tsne_mnist.py index 8649c7a46b629..4eba94828434a 100644 --- a/benchmarks/bench_tsne_mnist.py +++ b/benchmarks/bench_tsne_mnist.py @@ -15,6 +15,7 @@ import numpy as np from joblib import Memory +from sklearn.utils._openmp_helpers import _openmp_effective_n_threads from sklearn.datasets import fetch_openml from sklearn.decomposition import PCA @@ -22,7 +23,6 @@ from sklearn.neighbors import NearestNeighbors from sklearn.utils import check_array from sklearn.utils import shuffle as _shuffle -from sklearn.utils._openmp_helpers import _openmp_effective_n_threads LOG_DIR = "mnist_tsne_output" if not os.path.exists(LOG_DIR): diff --git a/doc/developers/development_setup.rst b/doc/developers/development_setup.rst index 28f7eb70ad050..6dd0901e12cfd 100644 --- a/doc/developers/development_setup.rst +++ b/doc/developers/development_setup.rst @@ -129,7 +129,7 @@ the required packages. conda create -n sklearn-dev -c conda-forge ^ python numpy scipy cython meson-python ninja ^ - pytest pytest-cov ruff==0.11.2 mypy numpydoc ^ + pytest pytest-cov ruff==0.12.2 mypy numpydoc ^ joblib threadpoolctl pre-commit Activate the newly created conda environment: @@ -167,7 +167,7 @@ the required packages. .. prompt:: pip install wheel numpy scipy cython meson-python ninja ^ - pytest pytest-cov ruff==0.11.2 mypy numpydoc ^ + pytest pytest-cov ruff==0.12.2 mypy numpydoc ^ joblib threadpoolctl pre-commit @@ -199,7 +199,7 @@ the required packages. conda create -n sklearn-dev -c conda-forge python \ numpy scipy cython meson-python ninja \ - pytest pytest-cov ruff==0.11.2 mypy numpydoc \ + pytest pytest-cov ruff==0.12.2 mypy numpydoc \ joblib threadpoolctl compilers llvm-openmp pre-commit and activate the newly created conda environment: @@ -244,7 +244,7 @@ the required packages. .. prompt:: pip install wheel numpy scipy cython meson-python ninja \ - pytest pytest-cov ruff==0.11.2 mypy numpydoc \ + pytest pytest-cov ruff==0.12.2 mypy numpydoc \ joblib threadpoolctl pre-commit .. tab-item:: Linux @@ -267,7 +267,7 @@ the required packages. conda create -n sklearn-dev -c conda-forge python \ numpy scipy cython meson-python ninja \ - pytest pytest-cov ruff==0.11.2 mypy numpydoc \ + pytest pytest-cov ruff==0.12.2 mypy numpydoc \ joblib threadpoolctl compilers pre-commit and activate the newly created environment: @@ -327,7 +327,7 @@ the required packages. .. prompt:: pip install wheel numpy scipy cython meson-python ninja \ - pytest pytest-cov ruff==0.11.2 mypy numpydoc \ + pytest pytest-cov ruff==0.12.2 mypy numpydoc \ joblib threadpoolctl pre-commit diff --git a/pyproject.toml b/pyproject.toml index e21d5824e8f4e..4eb1bd4c53371 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -81,7 +81,7 @@ tests = [ "pandas>=1.5.0", "pytest>=7.1.2", "pytest-cov>=2.9.0", - "ruff>=0.11.7", + "ruff>=0.12.2", "mypy>=1.15", "pyamg>=5.0.0", "polars>=0.20.30", diff --git a/sklearn/_min_dependencies.py b/sklearn/_min_dependencies.py index 82475f039e32b..e187bb604168f 100644 --- a/sklearn/_min_dependencies.py +++ b/sklearn/_min_dependencies.py @@ -32,7 +32,7 @@ "memory_profiler": ("0.57.0", "benchmark, docs"), "pytest": (PYTEST_MIN_VERSION, "tests"), "pytest-cov": ("2.9.0", "tests"), - "ruff": ("0.11.7", "tests"), + "ruff": ("0.12.2", "tests"), "mypy": ("1.15", "tests"), "pyamg": ("5.0.0", "tests"), "polars": ("0.20.30", "docs, tests"), From bf567c7904daf001ad97390a4e96dd97ffc59255 Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Thu, 18 Dec 2025 11:22:37 +0100 Subject: [PATCH 060/462] MNT cleanup numpy wor-karound in metrics functions (#32917) --- sklearn/metrics/_classification.py | 5 +---- sklearn/metrics/_ranking.py | 4 +--- sklearn/metrics/tests/test_classification.py | 2 +- sklearn/metrics/tests/test_common.py | 4 ++-- sklearn/metrics/tests/test_ranking.py | 2 +- sklearn/utils/_array_api.py | 8 -------- 6 files changed, 6 insertions(+), 19 deletions(-) diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 06db74153b776..81f8712af0232 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -39,7 +39,6 @@ _is_xp_namespace, _isin, _max_precision_float_dtype, - _tolist, _union1d, get_namespace, get_namespace_and_device, @@ -1862,9 +1861,7 @@ def _check_set_wise_labels(y_true, y_pred, average, labels, pos_label): y_true, y_pred = attach_unique(y_true, y_pred) y_type, y_true, y_pred, _ = _check_targets(y_true, y_pred) - # Convert to Python primitive type to avoid NumPy type / Python str - # comparison. See https://github.com/numpy/numpy/issues/6784 - present_labels = _tolist(unique_labels(y_true, y_pred)) + present_labels = unique_labels(y_true, y_pred) if average == "binary": if y_type == "binary": if pos_label not in present_labels: diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index eeb88f8bb0d98..d1f8dab912acf 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -239,9 +239,7 @@ def _binary_uninterpolated_average_precision( y_type = type_of_target(y_true, input_name="y_true") - # Convert to Python primitive type to avoid NumPy type / Python str - # comparison. See https://github.com/numpy/numpy/issues/6784 - present_labels = np.unique(y_true).tolist() + present_labels = np.unique(y_true) if y_type == "binary": if len(present_labels) == 2 and pos_label not in present_labels: diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index 958dfa5fd86f6..6642fce16d64e 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -1571,7 +1571,7 @@ def test_multilabel_hamming_loss(): def test_jaccard_score_validation(): y_true = np.array([0, 1, 0, 1, 1]) y_pred = np.array([0, 1, 0, 1, 1]) - err_msg = r"pos_label=2 is not a valid label. It should be one of \[0, 1\]" + err_msg = re.escape("pos_label=2 is not a valid label. It should be one of [0 1]") with pytest.raises(ValueError, match=err_msg): jaccard_score(y_true, y_pred, average="binary", pos_label=2) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 6beb495af194b..b64d200a01522 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -1966,8 +1966,8 @@ def test_metrics_pos_label_error_str(metric, y_pred_threshold, dtype_y_str): "specified: either make y_true take value in {0, 1} or {-1, 1} or " "pass pos_label explicit" ) - err_msg_pos_label_1 = ( - r"pos_label=1 is not a valid label. It should be one of \['eggs', 'spam'\]" + err_msg_pos_label_1 = re.escape( + "pos_label=1 is not a valid label. It should be one of ['eggs' 'spam']" ) pos_label_default = signature(metric).parameters["pos_label"].default diff --git a/sklearn/metrics/tests/test_ranking.py b/sklearn/metrics/tests/test_ranking.py index 0a108ecfb1cca..821537571ea1a 100644 --- a/sklearn/metrics/tests/test_ranking.py +++ b/sklearn/metrics/tests/test_ranking.py @@ -1191,7 +1191,7 @@ def test_average_precision_score_binary_pos_label_errors(): # Raise an error when pos_label is not in binary y_true y_true = np.array([0, 1]) y_pred = np.array([0, 1]) - err_msg = r"pos_label=2 is not a valid label. It should be one of \[0, 1\]" + err_msg = re.escape("pos_label=2 is not a valid label. It should be one of [0 1]") with pytest.raises(ValueError, match=err_msg): average_precision_score(y_true, y_pred, pos_label=2) diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 9b6cc6d9774ba..8bcf8bde132ea 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -1104,14 +1104,6 @@ def _bincount(array, weights=None, minlength=None, xp=None): return xp.asarray(bin_out, device=device(array)) -def _tolist(array, xp=None): - xp, _ = get_namespace(array, xp=xp) - if _is_numpy_namespace(xp): - return array.tolist() - array_np = _convert_to_numpy(array, xp=xp) - return [element.item() for element in array_np] - - def _logsumexp(array, axis=None, xp=None): # TODO replace by scipy.special.logsumexp when # https://github.com/scipy/scipy/pull/22683 is part of a release. From 86acf4547ed8e183cb75c07bcd68ef186a223f06 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Fri, 19 Dec 2025 00:08:39 +0100 Subject: [PATCH 061/462] MNT Remove unused `class_of_interest` from `_check_boundary_response_method` (#32921) --- sklearn/inspection/_plot/decision_boundary.py | 12 ++-------- .../tests/test_boundary_decision_display.py | 23 +++++++------------ 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index 33c8a15bb4fe7..ab7728739604c 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -19,7 +19,7 @@ ) -def _check_boundary_response_method(estimator, response_method, class_of_interest): +def _check_boundary_response_method(estimator, response_method): """Validate the response methods to be used with the fitted estimator. Parameters @@ -32,12 +32,6 @@ def _check_boundary_response_method(estimator, response_method, class_of_interes :term:`predict` as the target response. If set to 'auto', the response method is tried in the before mentioned order. - class_of_interest : int, float, bool, str or None - The class considered when plotting the decision. Cannot be None if - multiclass and `response_method` is 'predict_proba' or 'decision_function'. - - .. versionadded:: 1.4 - Returns ------- prediction_method : list of str or str @@ -503,9 +497,7 @@ def from_estimator( columns=X.columns, ) - prediction_method = _check_boundary_response_method( - estimator, response_method, class_of_interest - ) + prediction_method = _check_boundary_response_method(estimator, response_method) try: response, _, response_method_used = _get_response_values( estimator, diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index f409a50ab58c0..388b65d199029 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -63,57 +63,50 @@ class MultiLabelClassifier: err_msg = "Multi-label and multi-output multi-class classifiers are not supported" with pytest.raises(ValueError, match=err_msg): - _check_boundary_response_method(MultiLabelClassifier(), "predict", None) + _check_boundary_response_method(MultiLabelClassifier(), "predict") @pytest.mark.parametrize( - "estimator, response_method, class_of_interest, expected_prediction_method", + "estimator, response_method, expected_prediction_method", [ - (DecisionTreeRegressor(), "predict", None, "predict"), - (DecisionTreeRegressor(), "auto", None, "predict"), - (LogisticRegression().fit(*load_iris_2d_scaled()), "predict", None, "predict"), + (DecisionTreeRegressor(), "predict", "predict"), + (DecisionTreeRegressor(), "auto", "predict"), + (LogisticRegression().fit(*load_iris_2d_scaled()), "predict", "predict"), ( LogisticRegression().fit(*load_iris_2d_scaled()), "auto", - None, ["decision_function", "predict_proba", "predict"], ), ( LogisticRegression().fit(*load_iris_2d_scaled()), "predict_proba", - 0, "predict_proba", ), ( LogisticRegression().fit(*load_iris_2d_scaled()), "decision_function", - 0, "decision_function", ), ( LogisticRegression().fit(X, y), "auto", - None, ["decision_function", "predict_proba", "predict"], ), - (LogisticRegression().fit(X, y), "predict", None, "predict"), + (LogisticRegression().fit(X, y), "predict", "predict"), ( LogisticRegression().fit(X, y), ["predict_proba", "decision_function"], - None, ["predict_proba", "decision_function"], ), ], ) def test_check_boundary_response_method( - estimator, response_method, class_of_interest, expected_prediction_method + estimator, response_method, expected_prediction_method ): """Check the behaviour of `_check_boundary_response_method` for the supported cases. """ - prediction_method = _check_boundary_response_method( - estimator, response_method, class_of_interest - ) + prediction_method = _check_boundary_response_method(estimator, response_method) assert prediction_method == expected_prediction_method From 8a98df038ce00a7c016f6ce4abdee1f53e81b811 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Sun, 21 Dec 2025 14:48:44 +1100 Subject: [PATCH 062/462] FIX array API support when `pos_label=None` for brier score metrics (#32923) --- .../upcoming_changes/array-api/32923.fix.rst | 3 ++ sklearn/metrics/_classification.py | 9 ++--- sklearn/metrics/tests/test_classification.py | 34 +++++++++++++++++-- 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/32923.fix.rst diff --git a/doc/whats_new/upcoming_changes/array-api/32923.fix.rst b/doc/whats_new/upcoming_changes/array-api/32923.fix.rst new file mode 100644 index 0000000000000..ea18ff7aabaca --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/32923.fix.rst @@ -0,0 +1,3 @@ +- Fixes how `pos_label` is inferred when `pos_label` is set to `None`, in + :func:`sklearn.metrics.brier_score_loss` and + :func:`sklearn.metrics.d2_brier_score`. By :user:`Lucy Liu `. diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 81f8712af0232..227a3a6d7e416 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -3614,10 +3614,11 @@ def _validate_binary_probabilistic_prediction(y_true, y_prob, sample_weight, pos try: pos_label = _check_pos_label_consistency(pos_label, y_true) except ValueError: - classes = np.unique(y_true) - if classes.dtype.kind not in ("O", "U", "S"): - # for backward compatibility, if classes are not string then - # `pos_label` will correspond to the greater label + xp_y_true, _ = get_namespace(y_true) + classes = xp_y_true.unique_values(y_true) + # For backward compatibility, if classes are not string then + # `pos_label` will correspond to the greater label. + if not (_is_numpy_namespace(xp_y_true) and classes.dtype.kind in "OUS"): pos_label = classes[-1] else: raise diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index 6642fce16d64e..eb267ccf5e696 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -45,12 +45,13 @@ from sklearn.preprocessing import LabelBinarizer, label_binarize from sklearn.tree import DecisionTreeClassifier from sklearn.utils._array_api import ( - device as array_api_device, -) -from sklearn.utils._array_api import ( + _get_namespace_device_dtype_ids, get_namespace, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._mocking import MockDataFrame from sklearn.utils._testing import ( _array_api_for_tests, @@ -3743,3 +3744,30 @@ def test_probabilistic_metrics_multilabel_array_api( metric_score_xp = prob_metric(y_true_xp, y_prob_xp, sample_weight=sample_weight) assert metric_score_xp == pytest.approx(metric_score_np) + + +@pytest.mark.parametrize( + "array_namespace, device_, dtype_name", + yield_namespace_device_dtype_combinations(), + ids=_get_namespace_device_dtype_ids, +) +@pytest.mark.parametrize("prob_metric", [brier_score_loss, d2_brier_score]) +def test_pos_label_in_brier_score_metrics_array_api( + prob_metric, array_namespace, device_, dtype_name +): + """Check `pos_label` handled correctly when labels not in {-1, 1} or {0, 1}.""" + # For 'brier_score' metrics, when `pos_label=None` and labels are not strings, + # `pos_label` defaults to the largest label. + xp = _array_api_for_tests(array_namespace, device_) + y_true_pos_1 = xp.asarray(np.array([1, 0, 1, 0]), device=device_) + # Result should be the same when we use 2's for the label instead of 1's + y_true_pos_2 = xp.asarray(np.array([2, 0, 2, 0]), device=device_) + y_prob = xp.asarray( + np.array([0.5, 0.2, 0.7, 0.6], dtype=dtype_name), device=device_ + ) + + with config_context(array_api_dispatch=True): + metric_pos_1 = prob_metric(y_true_pos_1, y_prob) + metric_pos_2 = prob_metric(y_true_pos_2, y_prob) + + assert metric_pos_1 == pytest.approx(metric_pos_2) From c3d5bae8c3dd56dc75e0f540ca620c94910558bc Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Mon, 22 Dec 2025 14:57:11 +1100 Subject: [PATCH 063/462] DOC Add link to glossary "label indicator matrix" for classification metric docstrings (#32893) --- doc/glossary.rst | 8 ++++++-- sklearn/metrics/_ranking.py | 12 ++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/doc/glossary.rst b/doc/glossary.rst index 2a03332c34f1a..ab6b54bf170e9 100644 --- a/doc/glossary.rst +++ b/doc/glossary.rst @@ -518,14 +518,18 @@ General Concepts :term:`memory mapping`. See :ref:`parallelism` for more information. + label indicator format label indicator matrix multilabel indicator matrix multilabel indicator matrices - The format used to represent multilabel data, where each row of a 2d - array or sparse matrix corresponds to a sample, each column + This format can be used to represent binary or multilabel data. Each row of + a 2d array or sparse matrix corresponds to a sample, each column corresponds to a class, and each element is 1 if the sample is labeled with the class and 0 if not. + :ref:`LabelBinarizer ` can be used to create a + multilabel indicator matrix from :term:`multiclass` labels. + leakage data leakage A problem in cross validation where generalization performance can be diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index d1f8dab912acf..8226e49bff6d0 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -142,7 +142,7 @@ def average_precision_score( Parameters ---------- y_true : array-like of shape (n_samples,) or (n_samples, n_classes) - True binary labels or binary label indicators. + True binary labels or :term:`multilabel indicator matrix`. y_score : array-like of shape (n_samples,) or (n_samples, n_classes) Target scores, can either be probability estimates of the positive @@ -500,9 +500,9 @@ def roc_auc_score( Parameters ---------- y_true : array-like of shape (n_samples,) or (n_samples, n_classes) - True labels or binary label indicators. The binary and multiclass cases + True labels or :term:`label indicator matrix`. The binary and multiclass cases expect labels with shape (n_samples,) while the multilabel case expects - binary label indicators with shape (n_samples, n_classes). + a :term:`multilabel indicator matrix` with shape (n_samples, n_classes). y_score : array-like of shape (n_samples,) or (n_samples, n_classes) Target scores. @@ -1335,7 +1335,7 @@ def label_ranking_average_precision_score(y_true, y_score, *, sample_weight=None Parameters ---------- y_true : {array-like, sparse matrix} of shape (n_samples, n_labels) - True binary labels in binary indicator format. + True binary labels in :term:`label indicator format`. y_score : array-like of shape (n_samples, n_labels) Target scores, can either be probability estimates of the positive @@ -1437,7 +1437,7 @@ def coverage_error(y_true, y_score, *, sample_weight=None): Parameters ---------- y_true : array-like of shape (n_samples, n_labels) - True binary labels in binary indicator format. + True binary labels in :term:`label indicator format`. y_score : array-like of shape (n_samples, n_labels) Target scores, can either be probability estimates of the positive @@ -1514,7 +1514,7 @@ def label_ranking_loss(y_true, y_score, *, sample_weight=None): Parameters ---------- y_true : {array-like, sparse matrix} of shape (n_samples, n_labels) - True binary labels in binary indicator format. + True binary labels in :term:`label indicator format`. y_score : array-like of shape (n_samples, n_labels) Target scores, can either be probability estimates of the positive From ce9a2623c2fd51f60c665ecb1f49dd007077be27 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Mon, 22 Dec 2025 09:44:45 +0100 Subject: [PATCH 064/462] TST add tests for pyproject minimum dependency checks (#32826) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- sklearn/tests/test_min_dependencies_readme.py | 248 +++++++++++++----- 1 file changed, 185 insertions(+), 63 deletions(-) diff --git a/sklearn/tests/test_min_dependencies_readme.py b/sklearn/tests/test_min_dependencies_readme.py index 0f894103a8e27..9a51041e2321f 100644 --- a/sklearn/tests/test_min_dependencies_readme.py +++ b/sklearn/tests/test_min_dependencies_readme.py @@ -2,6 +2,7 @@ import os import re +import tomllib from collections import defaultdict from pathlib import Path @@ -11,18 +12,79 @@ from sklearn._min_dependencies import dependent_packages from sklearn.utils.fixes import parse_version -min_depencies_tag_to_packages_without_version = defaultdict(list) -for package, (min_version, extras) in dependent_packages.items(): - for extra in extras.split(", "): - min_depencies_tag_to_packages_without_version[extra].append(package) +# minimal dependencies and pyproject definitions for testing the pyproject tests -pyproject_section_to_min_dependencies_tag = { - "build-system.requires": "build", - "project.dependencies": "install", +TOY_MIN_DEPENDENCIES_PY_INFO = { + "joblib": ("1.3.0", "install"), + "scipy": ("1.10.0", "build, install"), + "conda-lock": ("3.0.1", "maintenance"), } -for tag in min_depencies_tag_to_packages_without_version: - section = f"project.optional-dependencies.{tag}" - pyproject_section_to_min_dependencies_tag[section] = tag + +TOY_MATCHING_PYPROJECT_SECTIONS = """ +[project] +dependencies = ["joblib>=1.3.0", "scipy>=1.10.0"] +[project.optional-dependencies] +build = ["scipy>=1.10.0"] +install = ["joblib>=1.3.0", "scipy>=1.10.0"] +maintenance = ["conda-lock==3.0.1"] +[build-system] +requires = ["scipy>=1.10.0"] +""" + +TOY_MATCHING_PYPROJECT_SECTIONS_WITH_UPPER_BOUND = """ +[project] +dependencies = ["joblib>=1.3.0,<2.0", "scipy>=1.10.0"] +[project.optional-dependencies] +build = ["scipy>=1.10.0,<1.19.0"] +install = ["joblib>=1.3.0,<2.0", "scipy>=1.10.0"] +maintenance = ["conda-lock==3.0.1"] +[build-system] +requires = ["scipy>=1.10.0,<1.19.0"] +""" + +TOY_WRONG_SYMBOL_PYPROJECT_SECTIONS = """ +[project] +dependencies = ["scipy<1.10.0"] +[project.optional-dependencies] +build = ["scipy>=1.10.0"] +install = ["scipy>=1.10.0"] +maintenance = ["conda-lock==3.0.1"] +[build-system] +requires = ["scipy>=1.10.0"] +""" + +TOY_MISSING_PACKAGE_PYPROJECT_SECTIONS = """ +[project] +dependencies = ["scipy>=1.10.0"] +[project.optional-dependencies] +build = ["scipy>=1.10.0"] +install = ["scipy>=1.10.0"] +maintenance = ["conda-lock==3.0.1"] +[build-system] +requires = ["scipy>=1.10.0"] +""" + +TOY_ADDITIONAL_PACKAGE_PYPROJECT_SECTIONS = """ +[project] +dependencies = ["joblib>=1.3.0", "scipy>=1.10.0"] +[project.optional-dependencies] +build = ["scipy>=1.10.0", "package_not_in_min_dependencies_py_file>=4.2"] +install = ["joblib>=1.3.0", "scipy>=1.10.0"] +maintenance = ["conda-lock==3.0.1"] +[build-system] +requires = ["scipy>=1.10.0"] +""" + +TOY_NON_MATCHING_VERSION_PYPROJECT_SECTIONS = """ +[project] +dependencies = ["joblib>=1.42.0", "scipy>=1.10.0"] +[project.optional-dependencies] +build = ["scipy>=1.10.0"] +install = ["joblib>=1.3.0", "scipy>=1.10.0"] +maintenance = ["conda-lock==3.0.1"] +[build-system] +requires = ["scipy>=1.10.0"] +""" def test_min_dependencies_readme(): @@ -66,18 +128,79 @@ def test_min_dependencies_readme(): assert version == min_version, message -def check_pyproject_section( - pyproject_section, min_dependencies_tag, skip_version_check_for=None -): - # tomllib is available in Python 3.11 - tomllib = pytest.importorskip("tomllib") +def extract_packages_and_pyproject_tags(dependencies): + min_depencies_tag_to_packages_without_version = defaultdict(list) + for package, (min_version, tags) in dependencies.items(): + for t in tags.split(", "): + min_depencies_tag_to_packages_without_version[t].append(package) + + pyproject_section_to_min_dependencies_tag = { + "build-system.requires": "build", + "project.dependencies": "install", + } + for tag in min_depencies_tag_to_packages_without_version: + section = f"project.optional-dependencies.{tag}" + pyproject_section_to_min_dependencies_tag[section] = tag + + return ( + min_depencies_tag_to_packages_without_version, + pyproject_section_to_min_dependencies_tag, + ) + + +def check_pyproject_sections(pyproject_toml, min_dependencies): + packages, pyproject_tags = extract_packages_and_pyproject_tags(min_dependencies) + + for pyproject_section, min_dependencies_tag in pyproject_tags.items(): + # Special situation for numpy: we have numpy>=2 in + # build-system.requires to make sure we build wheels against numpy>=2. + # TODO remove this when our minimum supported numpy version is >=2. + skip_version_check_for = ( + ["numpy"] if pyproject_section == "build-system.requires" else [] + ) + + expected_packages = packages[min_dependencies_tag] + + pyproject_section_keys = pyproject_section.split(".") + info = pyproject_toml + # iterate through nested keys to get packages and version + for key in pyproject_section_keys: + info = info[key] + + pyproject_build_min_versions = {} + # Assuming pyproject.toml build section has something like "my-package>=2.3.0" + pattern = r"([\w-]+)\s*[>=]=\s*([\d\w.]+)" + for requirement in info: + match = re.search(pattern, requirement) + if match is None: + raise NotImplementedError( + f"{requirement} does not match expected regex {pattern!r}. " + "Only >= and == are supported for version requirements" + ) + + package, version = match.group(1), match.group(2) - if skip_version_check_for is None: - skip_version_check_for = [] + pyproject_build_min_versions[package] = version - expected_packages = min_depencies_tag_to_packages_without_version[ - min_dependencies_tag - ] + msg = f"Packages in {pyproject_section} differ from _min_depencies.py" + + assert sorted(pyproject_build_min_versions) == sorted(expected_packages), msg + + for package, version in pyproject_build_min_versions.items(): + version = parse_version(version) + expected_min_version = parse_version(min_dependencies[package][0]) + if package in skip_version_check_for: + continue + + message = ( + f"{package} has inconsistent minimum versions in pyproject.toml and" + f" _min_depencies.py: {version} != {expected_min_version}" + ) + assert version == expected_min_version, message + + +def test_min_dependencies_pyproject_toml(): + """Check versions in pyproject.toml is consistent with _min_dependencies.""" root_directory = Path(sklearn.__file__).parent.parent pyproject_toml_path = root_directory / "pyproject.toml" @@ -90,54 +213,53 @@ def check_pyproject_section( with pyproject_toml_path.open("rb") as f: pyproject_toml = tomllib.load(f) - pyproject_section_keys = pyproject_section.split(".") - info = pyproject_toml - for key in pyproject_section_keys: - info = info[key] - - pyproject_build_min_versions = {} - # Assuming pyproject.toml build section has something like "my-package>=2.3.0" - # Warning: if you try to modify this regex, bear in mind that there can be upper - # bounds in release branches so "my-package>=2.3.0,<2.5.0" - pattern = r"([\w-]+)\s*[>=]=\s*([\d\w.]+)" - for requirement in info: - match = re.search(pattern, requirement) - if match is None: - raise NotImplementedError( - f"{requirement} does not match expected regex {pattern!r}. " - "Only >= and == are supported for version requirements" - ) - - package, version = match.group(1), match.group(2) + check_pyproject_sections(pyproject_toml, dependent_packages) - pyproject_build_min_versions[package] = version - assert sorted(pyproject_build_min_versions) == sorted(expected_packages) +@pytest.mark.parametrize( + "example_pyproject", + [ + TOY_MATCHING_PYPROJECT_SECTIONS, + TOY_MATCHING_PYPROJECT_SECTIONS_WITH_UPPER_BOUND, + ], +) +def test_check_matching_pyproject_section(example_pyproject): + """Test the version check for matching packages.""" - for package, version in pyproject_build_min_versions.items(): - version = parse_version(version) - expected_min_version = parse_version(dependent_packages[package][0]) - if package in skip_version_check_for: - continue + pyproject_toml = tomllib.loads(example_pyproject) - message = ( - f"{package} has inconsistent minimum versions in pyproject.toml and" - f" _min_depencies.py: {version} != {expected_min_version}" - ) - assert version == expected_min_version, message + check_pyproject_sections(pyproject_toml, TOY_MIN_DEPENDENCIES_PY_INFO) @pytest.mark.parametrize( - "pyproject_section, min_dependencies_tag", - pyproject_section_to_min_dependencies_tag.items(), + "example_non_matching_pyproject, error_msg", + [ + ( + TOY_WRONG_SYMBOL_PYPROJECT_SECTIONS, + ".* does not match expected regex .*. " + "Only >= and == are supported for version requirements", + ), + ( + TOY_MISSING_PACKAGE_PYPROJECT_SECTIONS, + "Packages in .* differ from _min_depencies.py", + ), + ( + TOY_ADDITIONAL_PACKAGE_PYPROJECT_SECTIONS, + "Packages in .* differ from _min_depencies.py", + ), + ( + TOY_NON_MATCHING_VERSION_PYPROJECT_SECTIONS, + ".* has inconsistent minimum versions in pyproject.toml and" + " _min_depencies.py: .* != .*", + ), + ], ) -def test_min_dependencies_pyproject_toml(pyproject_section, min_dependencies_tag): - """Check versions in pyproject.toml is consistent with _min_dependencies.""" - # NumPy is more complex because build-time (>=1.25) and run-time (>=1.19.5) - # requirement currently don't match - skip_version_check_for = ["numpy"] if min_dependencies_tag == "build" else None - check_pyproject_section( - pyproject_section, - min_dependencies_tag, - skip_version_check_for=skip_version_check_for, - ) +def test_check_non_matching_pyproject_section( + example_non_matching_pyproject, error_msg +): + """Test the version check for non-matching packages and versions.""" + + pyproject_toml = tomllib.loads(example_non_matching_pyproject) + + with pytest.raises(Exception, match=error_msg): + check_pyproject_sections(pyproject_toml, TOY_MIN_DEPENDENCIES_PY_INFO) From ee6911a44b881e84b7c712a228aed7ac1d4edcc1 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 22 Dec 2025 12:08:22 +0100 Subject: [PATCH 065/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#32901) Co-authored-by: Lock file bot --- ...a_forge_cuda_array-api_linux-64_conda.lock | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 130e53ea4b032..426250152c39c 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -7,42 +7,42 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 -https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_8.conda#ff007ab0f0fdc53d245972bba8a6d40c +https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.18.0-ha770c72_1.conda#4fb055f57404920a43b147031471e03b https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2024.2.2-ha770c72_17.conda#c18fd07c02239a7eb744ea728db39630 https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-h8577fbf_0.conda#338201218b54cadff2e774ac27733990 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.7-h4922eb0_0.conda#ec29f865968a81e1961b3c2f2765eebb -https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_8.conda#1bad93f0aa428d618875ef3a588a889e +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 +https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.0-hb9d3cd8_0.conda#f65c946f28f0518f41ced702f44c52b7 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc -https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda#f7f0d6cc2dc986d42ac2689ec88192be +https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb03c661_4.conda#1d29d2e33fe59954af82ef54a8af3fe1 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.10.0-h202a827_0.conda#0f98f3e95272d118f7931b6bef69bfe5 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 @@ -67,18 +67,18 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_1.conda#ad1fd565aff83b543d726382c0ab0af2 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda#7fa07cb0fb1b625a089ccc01218ee5b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 -https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 +https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.14-h6c98b2b_0.conda#efab4ad81ba5731b2fefa0ab4359e884 https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd @@ -86,7 +86,7 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.con https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.17.0-h3dad3f2_6.conda#3a127d28266cdc0da93384d1f59fe8df https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb03c661_4.conda#ca4ed8015764937c81b830f7f5b68543 @@ -98,7 +98,7 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.28.3-h6128344_1.conda#d8703f1ffe5a06356f06467f1d0b9464 @@ -120,7 +120,7 @@ https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce9 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.1.4-h7d33bf5_0.conda#93fe78190bc6fe40d5e7a737c8065286 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_0.conda#01e149d4a53185622dc2e788281961f2 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_1.conda#117499f93e892ea1e57fdca16c2e8351 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a @@ -142,10 +142,10 @@ https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#e https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py313hc80a56d_0.conda#a14fa0e1f58e2fce8d6fddf8f54ed500 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.3-py313hc80a56d_0.conda#83f8ba04486916b1d161bc391b781bc7 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda#9bcbd351966dc56a24fc0c368da5ad99 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda#66b8b26023b8efdf8fcb23bac4b6325d +https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.1-pyhd8ed1ab_0.conda#81a651287d3000eb12f0860ade0a1b41 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.12.0-pyhd8ed1ab_0.conda#a3b9510e2491c20c7fc0f5e730227fbb https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 @@ -158,11 +158,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.cond https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda#74e91c36d0eef3557915c68b6c2bef96 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h7a3aeb2_0.conda#31059dc620fa57d787e3899ed0421e6d https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/networkx-3.6-pyhcf101f3_0.conda#6725bfdf8ea7a8bf6415f096f3f1ffa5 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h80991f8_2.conda#37ca27d2f726f29a068230d8f6917ce4 @@ -171,14 +171,14 @@ https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7 https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py313h07c4f96_2.conda#7824f18e343d1f846dcde7b23c9bf31a +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py313h07c4f96_0.conda#82da2dcf1ea3e298f2557b50459809e0 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 @@ -190,14 +190,14 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.7.13-h822ba82_2.conda#9cf2c3c13468f2209ee814be2c88655f https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.10.0-h113e628_0.conda#73f73f60854f325a55f1d31459f2ab73 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.8.0-h736e048_1.conda#13de36be8de3ae3f05ba127631599213 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.12.0-py313h3dea7bd_0.conda#8ef99d298907bfd688a95cc714662ae7 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.0-py313h3dea7bd_0.conda#dbf9a488eb9568f9f25c3af44cbbb03e https://conda.anaconda.org/conda-forge/linux-64/cudnn-9.10.1.4-haad7af6_0.conda#8382d957333e0d3280dcbf5691516dc1 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py313h3dea7bd_0.conda#92f09729a821c52943d4b0b3749a2380 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py313h3dea7bd_0.conda#c0f36dfbb130da4f6ce2df31f6b25ea8 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.0-default_h99862b1_1.conda#d599b346638b9216c1e8f9146713df05 https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.0-default_h746c552_1.conda#327c78a8ce710782425a89df851392f7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.36.0-h2b5623c_0.conda#c96ca58ad3352a964bfcb85de6cd1496 @@ -222,13 +222,13 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-37_h5875eb1_mkl.conda#888c2ae634bce09709dffd739ba9f1bc https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2024.2.2-ha770c72_17.conda#e67269e07e58be5672f06441316f05f2 -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.35.2-py310hffdcd12_0.conda#2b90c3aaf73a5b6028b068cf3c76e0b7 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda#af35229f34c80dcfab5a40414440df23 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/libarrow-19.0.1-hc7b3859_3_cpu.conda#9ed3ded6da29dec8417f2e1db68798f2 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-37_hfef963f_mkl.conda#f66eb9a9396715013772b8a3ef7396be https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-37_h5e43f62_mkl.conda#0c4af651539e79160cd3f0783391e918 -https://conda.anaconda.org/conda-forge/noarch/polars-1.35.2-pyh6a1acc5_0.conda#24e8f78d79881b3c035f89f4b83c565c +https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda#160b41862a43936cbe509d1879d67f54 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.2-h5bd77bc_1.conda#f7bfe5b8e7641ce7d11ea10cfd9f33cc https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-19.0.1-hcb10f89_3_cpu.conda#8f8dc214d89e06933f1bc1dcd2310b9c https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-37_hdba1596_mkl.conda#4e76080972d13c913f178c90726b21ce @@ -244,7 +244,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.6.0-py313hc2a895b_2 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-19.0.1-hcb10f89_3_cpu.conda#a28f04b6e68a1c76de76783108ad729d https://conda.anaconda.org/conda-forge/linux-64/libmagma_sparse-2.9.0-h45b15fe_0.conda#beac0a5bbe0af75db6b16d3d8fd24f7e https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_2.conda#8a69ea71fdd37bfe42a28f0967dbb75a -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h11c21cd_1.conda#26b089b9e5fcdcdca714b01f8008d808 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 https://conda.anaconda.org/conda-forge/linux-64/blas-2.137-mkl.conda#9deb2d32720cc73c9991dbd9e24b499e https://conda.anaconda.org/conda-forge/linux-64/cupy-13.6.0-py313h66a2ee2_2.conda#9d83bdb568a47daf7fc38117db17fe4e https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-19.0.1-h08228c5_3_cpu.conda#a58e4763af8293deaac77b63bc7804d8 From 08d554601d33d1d7b54cc8ab500978265196188a Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 22 Dec 2025 12:08:53 +0100 Subject: [PATCH 066/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#32900) Co-authored-by: Lock file bot --- ...pylatest_free_threaded_linux-64_conda.lock | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index a38cc403d1a05..89ce3107f6017 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -4,44 +4,45 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#3251796e09870c978e0f69fa05e38fb6 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-h8577fbf_0.conda#338201218b54cadff2e774ac27733990 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda#518e9bbbc3e3486d6a4519192ba690f8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 -https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 +https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-4_h4a7cf45_openblas.conda#14ff9fdfbd8bd590fca383b995470711 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-he1279bd_0_cp314t.conda#08a2a24f4e6907bea0ebfe22eecae6be https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.2-py314hd8ed1ab_0.conda#d0ce45508dd9dffaec3795252897bd7a -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py314h3f98dc2_0.conda#af078f15b212d1414633e888166dd2bf +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.3-py314h3f98dc2_0.conda#1ce59325e72dfa9a1bfc46cdde4420d5 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-4_h0358290_openblas.conda#25f5e5af61cee1ffedd9b4c9947d3af8 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-4_h47877c9_openblas.conda#8ba8431802764597f400ee3e99026367 -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -51,11 +52,11 @@ https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.c https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py314hd4f4903_0.conda#f9c8cd3ab6c388232550c806379856d5 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.2-h92d6c8b_0.conda#f4db4d53331f31ec695670d5b3cedabb https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py314hf5b80f4_1.conda#b010b4d97f99c579c759996db97e53c0 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py314h529d2a9_2.conda#eda5b8c13cf149dc41ca6796d127fcab https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.0-pyhd8ed1ab_0.conda#7d545e76cfc231cf246f99963bcd27b0 From 3a9c4f533a0cb9e8c5e08c0ff9117931f460f307 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 22 Dec 2025 12:09:26 +0100 Subject: [PATCH 067/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#32899) Co-authored-by: Lock file bot --- ...pylatest_pip_scipy_dev_linux-64_conda.lock | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index dcf27d5b939f7..1cd9d1e24f716 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -4,31 +4,32 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-h8577fbf_0.conda#338201218b54cadff2e774ac27733990 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 -https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda#518e9bbbc3e3486d6a4519192ba690f8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-h32b2ec7_100_cp314.conda#1cef1236a05c3a98f68c33ae9425f656 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a @@ -37,20 +38,20 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 # pip certifi @ https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl#sha256=97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b # pip charset-normalizer @ https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 -# pip coverage @ https://files.pythonhosted.org/packages/d9/1d/9529d9bd44049b6b05bb319c03a3a7e4b0a8a802d28fa348ad407e10706d/coverage-7.12.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=fdba9f15849534594f60b47c9a30bc70409b54947319a7c4fd0e8e3d8d2f355d -# pip docutils @ https://files.pythonhosted.org/packages/11/a8/c6a4b901d17399c77cd81fb001ce8961e9f5e04d3daf27e8925cb012e163/docutils-0.22.3-py3-none-any.whl#sha256=bd772e4aca73aff037958d44f2be5229ded4c09927fcf8690c577b66234d6ceb +# pip coverage @ https://files.pythonhosted.org/packages/23/2d/3c7ff8b2e0e634c1f58d095f071f52ed3c23ff25be524b0ccae8b71f99f8/coverage-7.13.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=3188936845cd0cb114fa6a51842a304cdbac2958145d03be2377ec41eb285d19 +# pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea # pip imagesize @ https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl#sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip markupsafe @ https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 -# pip meson @ https://files.pythonhosted.org/packages/d7/ab/115470e7c6dcce024e43e2e00986864c56e48c59554bb19f4b02ed72814c/meson-1.9.2-py3-none-any.whl#sha256=1a284dc1912929098a6462401af58dc49ae3f324e94814a38a8f1020cee07cba +# pip meson @ https://files.pythonhosted.org/packages/32/4f/c398c6f06ece1c6c246e008d5dac3824c98f54d3eb3d8014f4910afd6d48/meson-1.10.0-py3-none-any.whl#sha256=4b27aafce281e652dcb437b28007457411245d975c48b5db3a797d3e93ae1585 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 # pip platformdirs @ https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl#sha256=d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b -# pip roman-numerals @ https://files.pythonhosted.org/packages/82/1d/7356f115a0e5faf8dc59894a3e9fc8b1821ab949163458b0072db0a12a68/roman_numerals-3.1.0-py3-none-any.whl#sha256=842ae5fd12912d62720c9aad8cab706e8c692556d01a38443e051ee6cc158d90 +# pip roman-numerals @ https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl#sha256=647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7 # pip six @ https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl#sha256=4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 # pip snowballstemmer @ https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl#sha256=6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 # pip sphinxcontrib-applehelp @ https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl#sha256=4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 @@ -61,7 +62,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip sphinxcontrib-serializinghtml @ https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl#sha256=6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 # pip tabulate @ https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl#sha256=024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb -# pip urllib3 @ https://files.pythonhosted.org/packages/56/1a/9ffe814d317c5224166b23e7c47f606d6e473712a2fad0f704ea9b99f246/urllib3-2.6.0-py3-none-any.whl#sha256=c90f7a39f716c572c4e3e58509581ebd83f9b59cced005b7db7ad2d22b0db99f +# pip urllib3 @ https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl#sha256=ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/c0/57/e69a1de45ec7a99a707e9f1a5defa035a48de0cae2d8582451c72d2db456/pyproject_metadata-0.10.0-py3-none-any.whl#sha256=b1e439a9f7560f9792ee5975dcf5e89d2510b1fc84a922d7e5d665aa9102d966 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b From 521a5b08bbc6db7c5a0bced9c799febb70c338dc Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Mon, 22 Dec 2025 16:04:08 +0100 Subject: [PATCH 068/462] MNT/DOC Autoclose schedule doesn't run on forks and improved structuring (#32889) --- .github/workflows/autoclose-comment.yml | 47 ++++++++++-------------- .github/workflows/autoclose-schedule.yml | 1 + .github/workflows/needs-decision.yml | 4 +- doc/developers/contributing.rst | 3 +- doc/faq.rst | 13 ++++--- 5 files changed, 32 insertions(+), 36 deletions(-) diff --git a/.github/workflows/autoclose-comment.yml b/.github/workflows/autoclose-comment.yml index 619933b1940c1..a22eb28829b8e 100644 --- a/.github/workflows/autoclose-comment.yml +++ b/.github/workflows/autoclose-comment.yml @@ -39,36 +39,29 @@ jobs: Thank you for your contribution to scikit-learn and for the effort you have put into this PR. This pull request does not yet meet the quality and - clarity needed for an effective review. Reviewing time is limited, and our - goal is to prioritize well-prepared contributions to keep scikit-learn - maintainable. Unless this PR is improved, it will be automatically closed - after two weeks. + clarity needed for an effective review. Project maintainers have limited + time for code reviews, and our goal is to prioritize well-prepared + contributions to keep scikit-learn maintainable. - To avoid autoclose and increase the chance of a productive review, please: + To increase the chance of a productive review, please refer to: [How do I + improve my issue or pull + request?](https://scikit-learn.org/dev/faq.html#how-do-i-improve-my-issue-or-pull-request) + As the author, you are responsible for driving this PR, which entails doing + necessary background research as well as presenting its context and your + thought process. If you are a [new + contributor](https://scikit-learn.org/dev/developers/contributing.html#new-contributors), + or do not know how to fulfill these requirements, we recommend that you + familiarise yourself with scikit-learn's development conventions via other + contribution types (e.g., reviewing PRs) before submitting code. - - Ensure your contribution aligns with our - [contribution guide](https://scikit-learn.org/dev/developers/contributing.html). - - Include a clear motivation and concise explanation in the pull request - description of why you chose this solution. + Scikit-learn maintainers cannot provide one-to-one guidance on this PR. + However, if you ask focused, well-researched questions, a community + member may be willing to help. 💬 - - Make sure the code runs and passes tests locally (`pytest`) and in the CI. - - Submit only code you can explain and maintain; reviewers will ask for - clarifications and changes. Disclose any AI assistance per our - [Automated Contributions Policy](https://scikit-learn.org/dev/developers/contributing.html#automated-contributions-policy). - - - Keep the changes minimal and directly relevant to the described issue or - enhancement. - - - We cannot provide one-to-one guidance on every PR, though we - encourage you to ask focused, actionable questions that show you have tried - to explore the problem and are interested to engage with the project. 💬 - Sometimes a maintainer or someone else from the community might be able to - offer pointers. - - - If you improve your PR within the two-week window, the `autoclose` label can - be removed by maintainers. + If you substantially improve this PR within two weeks, a team member may + remove the `autoclose` label and the PR stays open. Cosmetic changes or + incomplete fixes will not be sufficient. Maintainers will assess + improvements on their own schedule. Please do not ping (`@`) maintainers. diff --git a/.github/workflows/autoclose-schedule.yml b/.github/workflows/autoclose-schedule.yml index 4507f6685c275..086118e15e84b 100644 --- a/.github/workflows/autoclose-schedule.yml +++ b/.github/workflows/autoclose-schedule.yml @@ -18,6 +18,7 @@ jobs: autoclose: name: autoclose labeled PRs runs-on: ubuntu-latest + if: github.repository == 'scikit-learn/scikit-learn' steps: - uses: actions/checkout@v5 - uses: actions/setup-python@v6 diff --git a/.github/workflows/needs-decision.yml b/.github/workflows/needs-decision.yml index 592b24c925107..8079a39cdab36 100644 --- a/.github/workflows/needs-decision.yml +++ b/.github/workflows/needs-decision.yml @@ -33,14 +33,16 @@ jobs: /repos/$GH_REPO/issues/$ISSUE_NUMBER/comments \ -f "body=$BODY" env: - BODY: | + BODY: > Thanks for the work you've done so far. The goal of this comment is to set expectations. + Deciding on new features or substantial changes is a lengthy process. It frequently happens that no maintainer is available to take on this task right now. + Please do not create a Pull Request before a decision has been made regarding the proposed work. Making this decision can often take a significant amount of time and effort. diff --git a/doc/developers/contributing.rst b/doc/developers/contributing.rst index 7e79b6bc19d33..c51d092708862 100644 --- a/doc/developers/contributing.rst +++ b/doc/developers/contributing.rst @@ -37,8 +37,7 @@ See :ref:`ways_to_contribute` to learn how to make meaningful contributions. .. topic:: **Our community, our values** - We are a community based on openness and friendly, didactic, - discussions. + We are a community based on openness and friendly, didactic discussions. We aspire to treat everybody equally, and value their contributions. We are particularly seeking people from underrepresented backgrounds in Open diff --git a/doc/faq.rst b/doc/faq.rst index 271e2c9e73938..48a115e8c874a 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -313,17 +313,18 @@ being reviewed, you can try: * follow our :ref:`contribution guidelines `, in particular :ref:`automated_contributions_policy`, :ref:`filing_bugs`, - :ref:`stalled_pull_request` and :ref:`stalled_unclaimed_issues`. -* complete the provided issue and pull request templates, including a clear and - concise description of the issue or motivation for the pull request. + :ref:`stalled_pull_request` and :ref:`stalled_unclaimed_issues`, +* complete all sections of the issue or pull request template provided by GitHub, + including a clear description of the issue or motivation and thought process behind + the pull request * ensure the title clearly describes the issue or pull request and does not include an issue number. For your pull requests specifically, the following will make it easier to review: -* ensure your PR satisfies all items in the - :ref:`Pull request checklist `. -* ensure your PR addresses an issue for which there is clear consensus on the solution. +* ensure your PR addresses an issue for which there is clear consensus on the solution + (see :ref:`issues_tagged_needs_triage`), +* ensure the PR satisfies all items in the :ref:`Pull request checklist `, * ensure the changes are minimal and directly relevant to the described issue. What does the "spam" label for issues or pull requests mean? From 485c7bc7d11ceb6e2c9219bbbd331f04000c1096 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Mon, 22 Dec 2025 17:03:50 +0100 Subject: [PATCH 069/462] DOC Fix response values shape (#32918) --- sklearn/utils/_response.py | 4 ++- sklearn/utils/tests/test_response.py | 52 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/sklearn/utils/_response.py b/sklearn/utils/_response.py index 16c0ff0f4cf68..1344a532c777f 100644 --- a/sklearn/utils/_response.py +++ b/sklearn/utils/_response.py @@ -125,7 +125,9 @@ def _get_response_values( The response values are predictions such that it follows the following shape: - for binary classification, it is a 1d array of shape `(n_samples,)`; - - for multiclass classification, it is a 2d array of shape `(n_samples, n_classes)`; + - for multiclass classification + - with response_method="predict", it is a 1d array of shape `(n_samples,)`; + - otherwise, it is a 2d array of shape `(n_samples, n_classes)`; - for multilabel classification, it is a 2d array of shape `(n_samples, n_outputs)`; - for outlier detection, it is a 1d array of shape `(n_samples,)`; - for regression, it is a 1d array of shape `(n_samples,)`. diff --git a/sklearn/utils/tests/test_response.py b/sklearn/utils/tests/test_response.py index 273279357e11c..4e9a2c489e1c6 100644 --- a/sklearn/utils/tests/test_response.py +++ b/sklearn/utils/tests/test_response.py @@ -394,3 +394,55 @@ def test_response_values_type_of_target_on_classes_no_warning(): warnings.simplefilter("error", UserWarning) _get_response_values(clf, X, response_method="predict_proba") + + +@pytest.mark.parametrize( + "estimator, response_method, target_type, expected_shape", + [ + (LogisticRegression(), "predict", "binary", (10,)), + (LogisticRegression(), "predict_proba", "binary", (10,)), + (LogisticRegression(), "decision_function", "binary", (10,)), + (LogisticRegression(), "predict", "multiclass", (10,)), + (LogisticRegression(), "predict_proba", "multiclass", (10, 4)), + (LogisticRegression(), "decision_function", "multiclass", (10, 4)), + (ClassifierChain(LogisticRegression()), "predict", "multilabel", (10, 2)), + (ClassifierChain(LogisticRegression()), "predict_proba", "multilabel", (10, 2)), + ( + ClassifierChain(LogisticRegression()), + "decision_function", + "multilabel", + (10, 2), + ), + (IsolationForest(), "predict", "binary", (10,)), + (IsolationForest(), "predict", "multiclass", (10,)), + (DecisionTreeRegressor(), "predict", "binary", (10,)), + (DecisionTreeRegressor(), "predict", "multiclass", (10,)), + ], +) +def test_response_values_output_shape_( + estimator, response_method, target_type, expected_shape +): + """ + Check that output shape corresponds to docstring description + + - for binary classification, it is a 1d array of shape `(n_samples,)`; + - for multiclass classification + - with response_method="predict", it is a 1d array of shape `(n_samples,)`; + - otherwise, it is a 2d array of shape `(n_samples, n_classes)`; + - for multilabel classification, it is a 2d array of shape `(n_samples, n_outputs)`; + - for outlier detection, it is a 1d array of shape `(n_samples,)`; + - for regression, it is a 1d array of shape `(n_samples,)`. + """ + X = np.random.RandomState(0).randn(10, 2) + if target_type == "binary": + y = np.array([0, 1] * 5) + elif target_type == "multiclass": + y = [0, 1, 2, 3, 0, 1, 2, 3, 3, 0] + else: # multilabel + y = np.array([[0, 1], [1, 0]] * 5) + + clf = estimator.fit(X, y) + + y_pred, _ = _get_response_values(clf, X, response_method=response_method) + + assert y_pred.shape == expected_shape From b0ba8b029c298e0cc545206d2df4757be0ec2ac2 Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre Date: Mon, 22 Dec 2025 20:32:59 +0100 Subject: [PATCH 070/462] DOC add link to brand guidelines (#32907) --- doc/about.rst | 5 +++++ doc/faq.rst | 3 +++ 2 files changed, 8 insertions(+) diff --git a/doc/about.rst b/doc/about.rst index fc5868b590b2b..d8f9f95807e8d 100644 --- a/doc/about.rst +++ b/doc/about.rst @@ -159,9 +159,14 @@ Bibtex entry:: pages = {108--122}, } +.. _branding-and-logos: + Branding & Logos ================ +The scikit-learn brand is subject to the following `terms of use and guidelines +`_. + High quality PNG and SVG logos are available in the `doc/logos `_ source directory. The color palette is available in the diff --git a/doc/faq.rst b/doc/faq.rst index 48a115e8c874a..95cd7ae5e18d6 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -78,6 +78,9 @@ can be used via the `BSD 3-Clause License your work. Citations of scikit-learn are highly encouraged and appreciated. See :ref:`citing scikit-learn `. +However, the scikit-learn logo is subject to some terms and conditions. +See :ref:`branding-and-logos`. + Implementation decisions ------------------------ From 0e366004a64444c2ee7124bfc28d49d87faabae2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Tue, 23 Dec 2025 17:28:28 +0100 Subject: [PATCH 071/462] FIX Avoid LogisticRegression spurious warning with `C=np.inf` (#32932) Co-authored-by: Jack <72348727+Jack-GitHub12@users.noreply.github.com> --- sklearn/linear_model/_logistic.py | 4 ++-- sklearn/linear_model/tests/test_logistic.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index b494a2495e356..e3ce9dd12efa0 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -1165,8 +1165,8 @@ def fit(self, X, y, sample_weight=None): if penalty == "elasticnet" and self.l1_ratio is None: raise ValueError("l1_ratio must be specified when penalty is elasticnet.") - if penalty is None: - if self.C != 1.0: # default values + if self.penalty is None: + if self.C != 1.0: # default value warnings.warn( "Setting penalty=None will ignore the C and l1_ratio parameters" ) diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index 9cf34d9552307..da5df658f8099 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -2257,6 +2257,23 @@ def test_penalty_none(global_random_seed, solver): assert_array_equal(pred_none, pred_l2_C_inf) +# TODO(1.10): remove whole test with the removal of penalty +@pytest.mark.parametrize("solver", sorted(set(SOLVERS) - set(["liblinear"]))) +def test_c_inf_no_warning(solver): + """Test that C=np.inf (recommended approach) produces no warnings. + + Non-regression test for: + https://github.com/scikit-learn/scikit-learn/issues/32927 + """ + X, y = make_classification(n_samples=100, n_redundant=0, random_state=42) + + lr = LogisticRegression(C=np.inf, solver=solver) + with warnings.catch_warnings(): + warnings.simplefilter("error") + warnings.filterwarnings("ignore", category=ConvergenceWarning) + lr.fit(X, y) + + # XXX: investigate thread-safety bug that might be related to: # https://github.com/scikit-learn/scikit-learn/issues/31883 @pytest.mark.thread_unsafe From eec13ccc9c81027ce9387e1fce6f04fd22e80d4d Mon Sep 17 00:00:00 2001 From: Omar Salman Date: Tue, 23 Dec 2025 23:00:58 +0500 Subject: [PATCH 072/462] FIX Correct the formulation of `alpha` in `SGDOneClassSVM` (#32778) --- doc/modules/sgd.rst | 4 +- .../sklearn.linear_model/32778.fix.rst | 5 + sklearn/linear_model/_sgd_fast.pyx.tp | 8 +- sklearn/linear_model/_stochastic_gradient.py | 4 +- sklearn/linear_model/tests/test_sgd.py | 109 +++++++++++++----- 5 files changed, 94 insertions(+), 36 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/32778.fix.rst diff --git a/doc/modules/sgd.rst b/doc/modules/sgd.rst index 360ba2f11c994..8f6043521b82e 100644 --- a/doc/modules/sgd.rst +++ b/doc/modules/sgd.rst @@ -283,7 +283,7 @@ variant can be several orders of magnitude faster. This is similar to the optimization problems studied in section :ref:`sgd_mathematical_formulation` with :math:`y_i = 1, 1 \leq i \leq n` and - :math:`\alpha = \nu/2`, :math:`L` being the hinge loss function and :math:`R` + :math:`\alpha = \nu`, :math:`L` being the hinge loss function and :math:`R` being the :math:`L_2` norm. We just need to add the term :math:`b\nu` in the optimization loop. @@ -457,7 +457,7 @@ misclassification error (Zero-one loss) as shown in the Figure below. Popular choices for the regularization term :math:`R` (the `penalty` parameter) include: -- :math:`L_2` norm: :math:`R(w) := \frac{1}{2} \sum_{j=1}^{m} w_j^2 = ||w||_2^2`, +- :math:`L_2` norm: :math:`R(w) := \frac{1}{2} \sum_{j=1}^{m} w_j^2 = \frac{1}{2} ||w||_2^2`, - :math:`L_1` norm: :math:`R(w) := \sum_{j=1}^{m} |w_j|`, which leads to sparse solutions. - Elastic Net: :math:`R(w) := \frac{\rho}{2} \sum_{j=1}^{n} w_j^2 + diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32778.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32778.fix.rst new file mode 100644 index 0000000000000..5dedb5f37e6e2 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/32778.fix.rst @@ -0,0 +1,5 @@ +- Correct the formulation of `alpha` within :class:`linear_model.SGDOneClassSVM`. + The corrected value is `alpha = nu` instead of `alpha = nu / 2`. + Note: This might result in changed values for the fitted attributes like + `coef_` and `offset_` as well as the predictions made using this class. + By :user:`Omar Salman `. diff --git a/sklearn/linear_model/_sgd_fast.pyx.tp b/sklearn/linear_model/_sgd_fast.pyx.tp index 79699247f7a07..6170444aefe2b 100644 --- a/sklearn/linear_model/_sgd_fast.pyx.tp +++ b/sklearn/linear_model/_sgd_fast.pyx.tp @@ -493,7 +493,7 @@ def _plain_sgd{{name_suffix}}( objective_sum += cur_loss_val # for PA1/PA2 (passive/aggressive model, online algorithm) use only the loss if learning_rate != PA1 and learning_rate != PA2: - # sum up all the terms in the optimization objective function + # sum up all the terms in the optimization objective function # (i.e. also include regularization in addition to the loss) # Note: for the L2 term SGD optimizes 0.5 * L2**2, due to using # weight decay that's why the 0.5 coefficient is required @@ -503,8 +503,8 @@ def _plain_sgd{{name_suffix}}( l1_ratio * w.l1norm() ) if one_class: # specific to One-Class SVM - # nu is alpha * 2 (alpha is set as nu / 2 by the caller) - objective_sum += intercept * (alpha * 2) + # nu is alpha + objective_sum += intercept * alpha if y > 0.0: class_weight = weight_pos @@ -549,7 +549,7 @@ def _plain_sgd{{name_suffix}}( if fit_intercept == 1: intercept_update = update if one_class: # specific for One-Class SVM - intercept_update -= 2. * eta * alpha + intercept_update -= eta * alpha if intercept_update != 0: intercept += intercept_update * intercept_decay diff --git a/sklearn/linear_model/_stochastic_gradient.py b/sklearn/linear_model/_stochastic_gradient.py index c65cdbdcf51ce..1c969dc1a141a 100644 --- a/sklearn/linear_model/_stochastic_gradient.py +++ b/sklearn/linear_model/_stochastic_gradient.py @@ -2492,7 +2492,7 @@ def partial_fit(self, X, y=None, sample_weight=None): if not hasattr(self, "coef_"): self._more_validate_params(for_partial_fit=True) - alpha = self.nu / 2 + alpha = self.nu return self._partial_fit( X, alpha, @@ -2596,7 +2596,7 @@ def fit(self, X, y=None, coef_init=None, offset_init=None, sample_weight=None): """ self._more_validate_params() - alpha = self.nu / 2 + alpha = self.nu self._fit( X, alpha=alpha, diff --git a/sklearn/linear_model/tests/test_sgd.py b/sklearn/linear_model/tests/test_sgd.py index ad48cfec3938c..23cb2441143f7 100644 --- a/sklearn/linear_model/tests/test_sgd.py +++ b/sklearn/linear_model/tests/test_sgd.py @@ -6,9 +6,11 @@ import numpy as np import pytest import scipy.sparse as sp +from scipy.optimize import minimize from sklearn import datasets, linear_model, metrics from sklearn.base import clone, is_classifier +from sklearn.datasets import make_blobs from sklearn.exceptions import ConvergenceWarning from sklearn.kernel_approximation import Nystroem from sklearn.linear_model import _sgd_fast as sgd_fast @@ -1496,7 +1498,7 @@ def asgd_oneclass(klass, X, eta, nu, coef_init=None, offset_init=0.0): gradient = -1 else: gradient = 0 - coef *= max(0, 1.0 - (eta * nu / 2)) + coef *= max(0, 1.0 - eta * nu) coef += -(eta * gradient * entry) intercept += -(eta * (nu + gradient)) * decay @@ -1708,28 +1710,6 @@ def test_average_sparse_oneclass(klass): assert_allclose(clf.offset_, average_offset) -def test_sgd_oneclass(): - # Test fit, decision_function, predict and score_samples on a toy - # dataset - X_train = np.array([[-2, -1], [-1, -1], [1, 1]]) - X_test = np.array([[0.5, -2], [2, 2]]) - clf = SGDOneClassSVM( - nu=0.5, eta0=1, learning_rate="constant", shuffle=False, max_iter=1 - ) - clf.fit(X_train) - assert_allclose(clf.coef_, np.array([-0.125, 0.4375])) - assert clf.offset_[0] == -0.5 - - scores = clf.score_samples(X_test) - assert_allclose(scores, np.array([-0.9375, 0.625])) - - dec = clf.score_samples(X_test) - clf.offset_ - assert_allclose(clf.decision_function(X_test), dec) - - pred = clf.predict(X_test) - assert_array_equal(pred, np.array([-1, 1])) - - def test_ocsvm_vs_sgdocsvm(): # Checks SGDOneClass SVM gives a good approximation of kernelized # One-Class SVM @@ -1785,12 +1765,13 @@ def test_sgd_oneclass_convergence(): assert model.n_iter_ > 6 -def test_sgd_oneclass_vs_linear_oneclass(): +@pytest.mark.parametrize("eta0, max_iter", [(1e-3, 10000), (3e-4, 20000)]) +def test_sgd_oneclass_vs_linear_oneclass(eta0, max_iter): # Test convergence vs. liblinear `OneClassSVM` with kernel="linear" for nu in [0.1, 0.5, 0.9]: # allow enough iterations, small dataset model = SGDOneClassSVM( - nu=nu, max_iter=20000, tol=None, learning_rate="constant", eta0=1e-3 + nu=nu, max_iter=max_iter, tol=None, learning_rate="constant", eta0=eta0 ) model_ref = OneClassSVM(kernel="linear", nu=nu, tol=1e-6) # reference model model.fit(iris.data) @@ -1815,7 +1796,30 @@ def test_sgd_oneclass_vs_linear_oneclass(): assert dec_fn_corr > 0.99 assert preds_corr > 0.95 assert coef_corr > 0.99 - assert_allclose(1 - share_ones, nu) + assert_allclose(1 - share_ones, nu, atol=1e-2) + + +@pytest.mark.parametrize("nu", [0.1, 0.9]) +def test_sgd_oneclass_vs_linear_oneclass_offsets_match(nu): + """Test that the `offset_` of `SGDOneClassSVM` is close to the `offset_` + of `OneClassSVM` with `kernel="linear"`, given enough iterations and a + suitable value for the `eta0` parameter, while also ensuring that the + dataset is scaled. + """ + X = iris.data + X_scaled = StandardScaler().fit_transform(X) + model = SGDOneClassSVM( + nu=nu, + max_iter=40000, + tol=None, + learning_rate="optimal", + eta0=1e-6, + random_state=42, + ) + model_ref = OneClassSVM(kernel="linear", nu=nu, tol=5e-6) + model.fit(X_scaled) + model_ref.fit(X_scaled) + assert_allclose(model.offset_, model_ref.offset_, atol=1.3e-6) def test_l1_ratio(): @@ -2265,10 +2269,10 @@ def test_sgd_numerical_consistency(SGDEstimator): X_32 = X.astype(dtype=np.float32) Y_32 = np.array(Y, dtype=np.float32) - sgd_64 = SGDEstimator(max_iter=20) + sgd_64 = SGDEstimator(max_iter=22, shuffle=False) sgd_64.fit(X_64, Y_64) - sgd_32 = SGDEstimator(max_iter=20) + sgd_32 = SGDEstimator(max_iter=22, shuffle=False) sgd_32.fit(X_32, Y_32) assert_allclose(sgd_64.coef_, sgd_32.coef_) @@ -2281,3 +2285,52 @@ def test_sgd_one_class_svm_estimator_type(): """ sgd_ocsvm = SGDOneClassSVM() assert get_tags(sgd_ocsvm).estimator_type == "outlier_detector" + + +def test_sgd_one_class_svm_formulation_with_scipy_minimize(): + """Test that SGDOneClassSVM minimizes the correct objective function.""" + nu = 0.5 + hinge_threshold = 1.0 + n_samples, n_features = 300, 3 + random_seed = 42 + + def objective(w, X, y, alpha): + weights = w[:-1] + intercept = w[-1] + p = X @ weights + intercept + z = p * y + avg_loss = np.mean(np.maximum(hinge_threshold - z, 0.0)) + reg = 0.5 * alpha * weights @ weights + obj = avg_loss + reg + intercept * alpha + return obj + + X, _ = make_blobs( + n_samples=n_samples, + n_features=n_features, + random_state=random_seed, + ) + y = np.ones(n_samples, dtype=X.dtype) + w0 = np.zeros(n_features + 1) + scipy_output = minimize( + objective, + w0, + method="Nelder-Mead", + args=(X, y, nu), + options={"maxiter": 1000}, + ) + w_out = scipy_output.x + expected_coef = w_out[:-1] + expected_offset = 1 - w_out[-1] + + model = SGDOneClassSVM( + nu=nu, + learning_rate="constant", + max_iter=4000, + tol=None, + eta0=1e-4, + random_state=random_seed, + ) + model.fit(X, y) + + assert_allclose(model.coef_, expected_coef, rtol=5e-3) + assert_allclose(model.offset_, expected_offset, rtol=1e-2) From e53f0b85190a3014fb9a49edc05e6f871ff696bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Tue, 23 Dec 2025 21:11:43 +0100 Subject: [PATCH 073/462] DOC Add release highlights link in 1.8 changelog (#32933) --- doc/whats_new/v1.8.rst | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/doc/whats_new/v1.8.rst b/doc/whats_new/v1.8.rst index fa39c6f1fed43..db70bb46f408b 100644 --- a/doc/whats_new/v1.8.rst +++ b/doc/whats_new/v1.8.rst @@ -8,19 +8,8 @@ Version 1.8 =========== -.. - -- UNCOMMENT WHEN 1.8.0 IS RELEASED -- - For a short description of the main highlights of the release, please refer to - :ref:`sphx_glr_auto_examples_release_highlights_plot_release_highlights_1_7_0.py`. - - -.. - DELETE WHEN 1.8.0 IS RELEASED - Since October 2024, DO NOT add your changelog entry in this file. -.. - Instead, create a file named `..rst` in the relevant sub-folder in - `doc/whats_new/upcoming_changes/`. For full details, see: - https://github.com/scikit-learn/scikit-learn/blob/main/doc/whats_new/upcoming_changes/README.md +For a short description of the main highlights of the release, please refer to +:ref:`sphx_glr_auto_examples_release_highlights_plot_release_highlights_1_8_0.py`. .. include:: changelog_legend.inc From 43a7ffeef5f049021cf9081bb3f7860f62536c81 Mon Sep 17 00:00:00 2001 From: GAUTAM V DATLA <85986314+gautamvarmadatla@users.noreply.github.com> Date: Tue, 23 Dec 2025 23:52:28 -0500 Subject: [PATCH 074/462] CI Make test_predict_joint_proba more stable for different random seeds (#32939) --- sklearn/tests/test_naive_bayes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/tests/test_naive_bayes.py b/sklearn/tests/test_naive_bayes.py index f18cabbcf01d8..5a82c916db640 100644 --- a/sklearn/tests/test_naive_bayes.py +++ b/sklearn/tests/test_naive_bayes.py @@ -980,7 +980,7 @@ def test_predict_joint_proba(Estimator, global_random_seed): jll = est.predict_joint_log_proba(X2) log_prob_x = logsumexp(jll, axis=1) log_prob_x_y = jll - np.atleast_2d(log_prob_x).T - assert_allclose(est.predict_log_proba(X2), log_prob_x_y) + assert_allclose(est.predict_log_proba(X2), log_prob_x_y, atol=1e-12) @pytest.mark.parametrize("Estimator", ALL_NAIVE_BAYES_CLASSES) From 4a3f3571f51a87e388541b513c0addf41e66b396 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Thu, 25 Dec 2025 03:25:08 +1100 Subject: [PATCH 075/462] DOC Add glossary entry for one-vs-rest and one-vs-one (#32931) --- doc/glossary.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/glossary.rst b/doc/glossary.rst index ab6b54bf170e9..6dfffadd83656 100644 --- a/doc/glossary.rst +++ b/doc/glossary.rst @@ -592,6 +592,26 @@ General Concepts import numpy as np + ovo + One-vs-one + one-vs-one + Method of decomposing a :term:`multiclass` problem into + `n_classes * (n_classes - 1) / 2` :term:`binary` problems, one for each + pairwise combination of classes. A metric is computed or a classifier is + fitted for each pair combination. + :class:`~sklearn.multiclass.OneVsOneClassifier` implements this + method for binary classifiers. + + ovr + One-vs-Rest + one-vs-rest + Method for decomposing a :term:`multiclass` problem into `n_classes` + :term:`binary` problems. For each class a metric is computed or classifier + fitted, with that class being treated as the positive class while all other + classes are negative. + :class:`~sklearn.multiclass.OneVsRestClassifier` implements this + method for binary classifiers. + online learning Where a model is iteratively updated by receiving each batch of ground truth :term:`targets` soon after making predictions on corresponding From 4ac107924f6c017481c1a8c432c0512a9ec2dc0a Mon Sep 17 00:00:00 2001 From: CipherCat <75171347+CipherCat7134@users.noreply.github.com> Date: Fri, 26 Dec 2025 16:07:09 +0530 Subject: [PATCH 076/462] =?UTF-8?q?Fix=20subject=E2=80=93verb=20agreement?= =?UTF-8?q?=20in=20documentation=20(#32945)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/modules/density.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/modules/density.rst b/doc/modules/density.rst index b629857827c74..53bd317003048 100644 --- a/doc/modules/density.rst +++ b/doc/modules/density.rst @@ -42,7 +42,7 @@ the histogram. But what if, instead of stacking the blocks on a regular grid, we center each block on the point it represents, and sum the total height at each location? This idea leads to the lower-left visualization. It is perhaps not as clean as a histogram, but the fact that the data drive the block -locations mean that it is a much better representation of the underlying +locations means that it is a much better representation of the underlying data. This visualization is an example of a *kernel density estimation*, in this case From f397c5a328f51c17d28aacd14c8de35d4fcd91db Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 29 Dec 2025 12:39:03 +0100 Subject: [PATCH 077/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#32965) Co-authored-by: Lock file bot --- .../azure/pylatest_free_threaded_linux-64_conda.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index 89ce3107f6017..4429c158b51ad 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -28,7 +28,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e @@ -38,7 +38,7 @@ https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-he1279bd_0_cp314t. https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.2-py314hd8ed1ab_0.conda#d0ce45508dd9dffaec3795252897bd7a -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.3-py314h3f98dc2_0.conda#1ce59325e72dfa9a1bfc46cdde4420d5 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.3-py314h3f98dc2_1.conda#d328a09daecc1ad3d8fa272f836fb65f https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 @@ -53,10 +53,10 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d27 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py314hd4f4903_0.conda#f9c8cd3ab6c388232550c806379856d5 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py314hd4f4903_0.conda#d0c7122fcbd0bffc0d76d7c7d476e537 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.2-h92d6c8b_0.conda#f4db4d53331f31ec695670d5b3cedabb https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py314h529d2a9_2.conda#eda5b8c13cf149dc41ca6796d127fcab -https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.0-pyhd8ed1ab_0.conda#7d545e76cfc231cf246f99963bcd27b0 +https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.1-pyhd8ed1ab_0.conda#4e98ccdfa64d30826a7977c7a4fa17e8 From 2057f9cc3d96ec9e366b087890c141c659c26297 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 29 Dec 2025 12:41:09 +0100 Subject: [PATCH 078/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#32966) Co-authored-by: Lock file bot --- build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 1cd9d1e24f716..8d2d71fa8f849 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -27,7 +27,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16. https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a @@ -38,7 +38,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 # pip certifi @ https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl#sha256=97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b # pip charset-normalizer @ https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 -# pip coverage @ https://files.pythonhosted.org/packages/23/2d/3c7ff8b2e0e634c1f58d095f071f52ed3c23ff25be524b0ccae8b71f99f8/coverage-7.13.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=3188936845cd0cb114fa6a51842a304cdbac2958145d03be2377ec41eb285d19 +# pip coverage @ https://files.pythonhosted.org/packages/82/2b/783ded568f7cd6b677762f780ad338bf4b4750205860c17c25f7c708995e/coverage-7.13.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea From e47b3be9eb32a6cba7252cc59bde6a25a7d573e8 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 29 Dec 2025 13:23:49 +0100 Subject: [PATCH 079/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#32967) Co-authored-by: Lock file bot --- ...test_conda_forge_cuda_array-api_linux-64_conda.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 426250152c39c..e4b487bc0ed4e 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -95,7 +95,7 @@ https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff86 https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 @@ -142,7 +142,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#e https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.3-py313hc80a56d_0.conda#83f8ba04486916b1d161bc391b781bc7 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.3-py313hc80a56d_1.conda#5e6c9f05c2825daad3d8006d3e2474ac https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda#9bcbd351966dc56a24fc0c368da5ad99 https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.1-pyhd8ed1ab_0.conda#81a651287d3000eb12f0860ade0a1b41 @@ -170,7 +170,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e @@ -190,7 +190,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.7.13-h822ba82_2.conda#9cf2c3c13468f2209ee814be2c88655f https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.10.0-h113e628_0.conda#73f73f60854f325a55f1d31459f2ab73 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.8.0-h736e048_1.conda#13de36be8de3ae3f05ba127631599213 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.0-py313h3dea7bd_0.conda#dbf9a488eb9568f9f25c3af44cbbb03e +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.1-py313h3dea7bd_0.conda#82315acb438e857f809f556e2dcdb822 https://conda.anaconda.org/conda-forge/linux-64/cudnn-9.10.1.4-haad7af6_0.conda#8382d957333e0d3280dcbf5691516dc1 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee @@ -234,7 +234,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-19.0.1-hcb10f89_3 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-37_hdba1596_mkl.conda#4e76080972d13c913f178c90726b21ce https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-h45b15fe_0.conda#703a1ab01e36111d8bb40bc7517e900b https://conda.anaconda.org/conda-forge/linux-64/libparquet-19.0.1-h081d1f1_3_cpu.conda#1d04307cdb1d8aeb5f55b047d5d403ea -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py313hf6604e3_0.conda#15f43bcd12c90186e78801fafc53d89b +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py313hf6604e3_0.conda#07963f5dbb5351201035e1f8815ed8da https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-19.0.1-py313he5f92c8_0_cpu.conda#7d8649531c807b24295c8f9a0a396a78 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.2-py313ha3f37dd_1.conda#e2ec46ec4c607b97623e7b691ad31c54 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 From f82d5769927a6a764ee0eeefcf64cfb5904b0fa0 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Wed, 31 Dec 2025 07:39:16 +0100 Subject: [PATCH 080/462] ENH small improvement of hessian product in LinearModelLoss.gradient_hessian_product (#32972) --- sklearn/linear_model/_linear_loss.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/linear_model/_linear_loss.py b/sklearn/linear_model/_linear_loss.py index 200b391007951..85ab639700549 100644 --- a/sklearn/linear_model/_linear_loss.py +++ b/sklearn/linear_model/_linear_loss.py @@ -807,7 +807,7 @@ def hessp(s): else: s_intercept = 0 tmp = X @ s.T + s_intercept # X_{im} * s_k_m - tmp += (-proba * tmp).sum(axis=1)[:, np.newaxis] # - sum_l .. + tmp -= (proba * tmp).sum(axis=1)[:, np.newaxis] # - sum_l .. tmp *= proba # * p_i_k if sample_weight is not None: tmp *= sample_weight[:, np.newaxis] From 7f9afb87a0a3f9b624ac5d0861a8afa4335524a2 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Wed, 31 Dec 2025 12:47:22 +0100 Subject: [PATCH 081/462] Fix missing HTML escape in parameters repr (#32942) --- doc/whats_new/upcoming_changes/many-modules/32942.fix.rst | 4 ++++ sklearn/utils/_repr_html/params.py | 5 +++-- sklearn/utils/_repr_html/tests/test_params.py | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/many-modules/32942.fix.rst diff --git a/doc/whats_new/upcoming_changes/many-modules/32942.fix.rst b/doc/whats_new/upcoming_changes/many-modules/32942.fix.rst new file mode 100644 index 0000000000000..d37df9a5f277a --- /dev/null +++ b/doc/whats_new/upcoming_changes/many-modules/32942.fix.rst @@ -0,0 +1,4 @@ +- Some parameter descriptions in the HTML representation of estimators + were not properly escaped, which could lead to malformed HTML if the + description contains characters like `<` or `>`. + By :user:`Olivier Grisel `. diff --git a/sklearn/utils/_repr_html/params.py b/sklearn/utils/_repr_html/params.py index 2bc523f7d6e17..3bf858f5aef11 100644 --- a/sklearn/utils/_repr_html/params.py +++ b/sklearn/utils/_repr_html/params.py @@ -113,8 +113,9 @@ def _params_html_repr(params): link = _generate_link_to_param_doc(params.estimator_class, row, params.doc_link) if param_numpydoc := param_map.get(row, None): param_description = ( - f"{param_numpydoc.name}: {param_numpydoc.type}

" - f"{'
'.join(param_numpydoc.desc)}" + f"{html.escape(param_numpydoc.name)}: " + f"{html.escape(param_numpydoc.type)}

" + f"{'
'.join(html.escape(line) for line in param_numpydoc.desc)}" ) else: param_description = None diff --git a/sklearn/utils/_repr_html/tests/test_params.py b/sklearn/utils/_repr_html/tests/test_params.py index 4cbd1302ee2dd..ef41c4c725638 100644 --- a/sklearn/utils/_repr_html/tests/test_params.py +++ b/sklearn/utils/_repr_html/tests/test_params.py @@ -90,7 +90,8 @@ class MockEstimator: Parameters ---------- a : int - Description of a. + Description of a which can include ``_ that should not be confused with HTML tags. b : str """ @@ -115,7 +116,8 @@ class MockEstimator: r'\s*\s*a:' r"\sint

" - r"Description of a\.
" + r"Description of a which can include `<formatted text
" + r"https://example.com>`_ that should not be confused with HTML tags." r"\s*" r"\s*" ) From 46970effc67ee2b4e2bc08bb81b09520f2db86f3 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Wed, 31 Dec 2025 12:55:58 +0100 Subject: [PATCH 082/462] FIX monkeypatch.settattr raising AttributeError (#32954) --- .../tests/test_gradient_boosting.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py index e1d400ca07dd4..e32f6d868b4d5 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py @@ -11,7 +11,7 @@ from joblib.numpy_pickle import NumpyPickler from numpy.testing import assert_allclose, assert_array_equal -import sklearn +import sklearn.ensemble._hist_gradient_boosting.gradient_boosting as hgb_module from sklearn._loss.loss import ( AbsoluteError, HalfBinomialLoss, @@ -870,11 +870,7 @@ def mock_check_scoring(estimator, scoring): assert scoring == "neg_median_absolute_error" return mock_scorer - monkeypatch.setattr( - sklearn.ensemble._hist_gradient_boosting.gradient_boosting, - "check_scoring", - mock_check_scoring, - ) + monkeypatch.setattr(hgb_module, "check_scoring", mock_check_scoring) X, y = make_regression(random_state=0) sample_weight = np.ones_like(y) From 4be3e7dd5826babf25489318ab553475c5f3719d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= Date: Wed, 31 Dec 2025 13:10:03 +0100 Subject: [PATCH 083/462] FIX `remainder` parameter for column transformer visual block (#32713) Co-authored-by: Guillaume Lemaitre --- .../sklearn.compose/32713.fix.rst | 4 ++++ sklearn/compose/_column_transformer.py | 2 +- .../compose/tests/test_column_transformer.py | 2 +- sklearn/utils/_repr_html/estimator.py | 17 +++++++++++++---- 4 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.compose/32713.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.compose/32713.fix.rst b/doc/whats_new/upcoming_changes/sklearn.compose/32713.fix.rst new file mode 100644 index 0000000000000..6eb85870877b1 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.compose/32713.fix.rst @@ -0,0 +1,4 @@ +- The dotted line for :class:`compose.ColumnTransformer` in its HTML display + now includes only its elements. The behaviour when a remainder is used, + has also been corrected. + By :user:`Dea María Léon ` diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index 00986f7cf1c1f..4aa1f0c6739d2 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -1238,7 +1238,7 @@ def _sk_visual_block_(self): self.transformers, [("remainder", self.remainder, remainder_columns)] ) else: - transformers = chain(self.transformers, [("remainder", self.remainder, "")]) + transformers = chain(self.transformers, [("remainder", self.remainder, [])]) names, transformers, name_details = zip(*transformers) return _VisualBlock( diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index 7a6f243c14a92..f37ee10c2cc05 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -1555,7 +1555,7 @@ def test_sk_visual_block_remainder(remainder): ) visual_block = ct._sk_visual_block_() assert visual_block.names == ("ohe", "remainder") - assert visual_block.name_details == (["col1", "col2"], "") + assert visual_block.name_details == (["col1", "col2"], []) assert visual_block.estimators == (ohe, remainder) diff --git a/sklearn/utils/_repr_html/estimator.py b/sklearn/utils/_repr_html/estimator.py index cc62922713cf9..831f2485d9ebb 100644 --- a/sklearn/utils/_repr_html/estimator.py +++ b/sklearn/utils/_repr_html/estimator.py @@ -184,10 +184,11 @@ def _write_label_html( f'?{doc_label}' ) - + if name == "passthrough" or name_details == "[]": + name_caption = "" name_caption_div = ( "" - if name_caption is None + if name_caption is None or name_caption == "" else f'
{html.escape(name_caption)}
' ) name_caption_div = f"
{name}
{name_caption_div}
" @@ -196,10 +197,13 @@ def _write_label_html( if doc_link or is_fitted_icon else "" ) + label_arrow_class = ( + "" if name == "passthrough" else "sk-toggleable__label-arrow" + ) label_html = ( f'' + f'{label_arrow_class}">{name_caption_div}{links_div}' ) fmt_str = ( @@ -212,6 +216,8 @@ def _write_label_html( if params: fmt_str = "".join([fmt_str, f"{params}"]) elif name_details and ("Pipeline" not in name): + if name == "passthrough" or name_details == "[]": + name_details = "" fmt_str = "".join([fmt_str, f"
{name_details}
"]) out.write(fmt_str) @@ -382,7 +388,10 @@ def _write_estimator_html( out.write("") elif est_block.kind == "single": - if hasattr(estimator, "_get_params_html"): + if ( + hasattr(estimator, "_get_params_html") + and not est_block.names == "passthrough" + ): params = estimator._get_params_html(doc_link=doc_link)._repr_html_inner() else: params = "" From 03c1d566ee268b6029977b816e79d93403568e26 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Wed, 31 Dec 2025 15:44:07 +0100 Subject: [PATCH 084/462] ENH/FIX: make coordinate descent solver converge for ridge regression (#32845) --- .../32845.enhancement.rst | 7 + sklearn/linear_model/_cd_fast.pyx | 409 ++++++++++++------ sklearn/linear_model/_coordinate_descent.py | 9 +- .../tests/test_coordinate_descent.py | 115 +++-- .../tests/test_sparse_coordinate_descent.py | 14 +- 5 files changed, 376 insertions(+), 178 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/32845.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32845.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32845.enhancement.rst new file mode 100644 index 0000000000000..332a2b11ed160 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/32845.enhancement.rst @@ -0,0 +1,7 @@ +- :class:`linear_model.ElasticNet`, :class:`linear_model.ElasticNetCV` and + :func:`linear_model.enet_path` + now are able to fit Ridge regression, i.e. setting `l1_ratio=0`. + Before this PR, the stopping criterion was a formulation of the dual gap that breaks + down for `l1_ratio=0`. Now, an alternative dual gap formulation is used for this + setting. This reduces the noise of raised warnings. + By :user:`Christian Lorentzen `. diff --git a/sklearn/linear_model/_cd_fast.pyx b/sklearn/linear_model/_cd_fast.pyx index 5ca5160fcb127..4fabb7632b723 100644 --- a/sklearn/linear_model/_cd_fast.pyx +++ b/sklearn/linear_model/_cd_fast.pyx @@ -98,6 +98,30 @@ message_ridge = ( ) +cdef inline floating dual_gap_formulation_A( + floating alpha, # L1 penalty + floating beta, # L1 penalty + floating w_l1_norm, + floating w_l2_norm2, + floating R_norm2, # R @ R + floating Ry, # R @ y + floating dual_norm_XtA, +) noexcept nogil: + """Compute dual gap according to formulation A.""" + cdef floating gap, primal, dual + cdef floating scale # Scaling factor to achieve dual feasible point. + + primal = 0.5 * (R_norm2 + beta * w_l2_norm2) + alpha * w_l1_norm + + if (dual_norm_XtA > alpha): + scale = alpha / dual_norm_XtA + else: + scale = 1.0 + dual = -0.5 * (scale ** 2) * (R_norm2 + beta * w_l2_norm2) + scale * Ry + gap = primal - dual + return gap + + cdef (floating, floating) gap_enet( int n_samples, int n_features, @@ -110,14 +134,47 @@ cdef (floating, floating) gap_enet( floating[::1] XtA, # XtA = X.T @ R - beta * w is calculated inplace bint positive, ) noexcept nogil: - """Compute dual gap for use in enet_coordinate_descent.""" + """Compute dual gap for use in enet_coordinate_descent. + + alpha > 0: formulation A of the duality gap + alpha = 0 & beta > 0: formulation B of the duality gap + alpha = beta = 0: OLS first order condition (=gradient) + """ cdef floating gap = 0.0 cdef floating dual_norm_XtA cdef floating R_norm2 - cdef floating w_norm2 = 0.0 - cdef floating l1_norm - cdef floating A_norm2 - cdef floating const_ + cdef floating Ry + cdef floating w_l1_norm + cdef floating w_l2_norm2 = 0.0 + + # w_l2_norm2 = w @ w + if beta > 0: + w_l2_norm2 = _dot(n_features, &w[0], 1, &w[0], 1) + # R_norm2 = R @ R + R_norm2 = _dot(n_samples, &R[0], 1, &R[0], 1) + # Ry = R @ y + if not (alpha == 0 and beta == 0): + Ry = _dot(n_samples, &R[0], 1, &y[0], 1) + + if alpha == 0: + # XtA = X.T @ R + _gemv( + ColMajor, Trans, n_samples, n_features, 1.0, &X[0, 0], + n_samples, &R[0], 1, 0, &XtA[0], 1, + ) + # ||X'R||_2^2 + dual_norm_XtA = _dot(n_features, &XtA[0], 1, &XtA[0], 1) + if beta == 0: + # This is OLS, no dual gap available. Resort to first order condition + # X'R = 0 + # gap = ||X'R||_2^2 + # Compare with stopping criterion of LSQR. + gap = dual_norm_XtA + return gap, dual_norm_XtA + # This is Ridge regression, we use formulation B for the dual gap. + gap = R_norm2 + 0.5 * beta * w_l2_norm2 - Ry + gap += 1 / (2 * beta) * dual_norm_XtA + return gap, dual_norm_XtA # XtA = X.T @ R - beta * w _copy(n_features, &w[0], 1, &XtA[0], 1) @@ -125,32 +182,23 @@ cdef (floating, floating) gap_enet( n_samples, &R[0], 1, -beta, &XtA[0], 1) + # dual_norm_XtA if positive: dual_norm_XtA = max(n_features, &XtA[0]) else: dual_norm_XtA = abs_max(n_features, &XtA[0]) - # R_norm2 = R @ R - R_norm2 = _dot(n_samples, &R[0], 1, &R[0], 1) - - # w_norm2 = w @ w - if beta > 0: - w_norm2 = _dot(n_features, &w[0], 1, &w[0], 1) - - if (dual_norm_XtA > alpha): - const_ = alpha / dual_norm_XtA - A_norm2 = R_norm2 * (const_ ** 2) - gap = 0.5 * (R_norm2 + A_norm2) - else: - const_ = 1.0 - gap = R_norm2 - - l1_norm = _asum(n_features, &w[0], 1) - - gap += ( - alpha * l1_norm - - const_ * _dot(n_samples, &R[0], 1, &y[0], 1) # R @ y - + 0.5 * beta * (1 + const_ ** 2) * w_norm2 + # w_l1_norm = np.sum(np.abs(w)) + w_l1_norm = _asum(n_features, &w[0], 1) + + gap = dual_gap_formulation_A( + alpha=alpha, + beta=beta, + w_l1_norm=w_l1_norm, + w_l2_norm2=w_l2_norm2, + R_norm2=R_norm2, + Ry=Ry, + dual_norm_XtA=dual_norm_XtA, ) return gap, dual_norm_XtA @@ -178,7 +226,7 @@ def enet_coordinate_descent( The dual for beta = 0, see e.g. [Fercoq 2015] with v = alpha * theta, is - D(v) = -1/2 ||v||_2^2 + y v + D(v) = -1/2 ||v||_2^2 + y' v (formulation A) with dual feasible condition ||X^T v||_inf <= alpha. For beta > 0, one uses extended versions of X and y by adding n_features rows @@ -186,16 +234,22 @@ def enet_coordinate_descent( X -> ( X) y -> (y) (sqrt(beta) I) (0) - Note that the residual y - X w is an important ingredient for the estimation of a - dual feasible point v. + Note that the residual R = y - X w is an important ingredient for the estimation of + a dual feasible point v. At optimum of primal w* and dual v*, one has - v = y* - X w* + v* = y - X w* The duality gap is G(w, v) = P(w) - D(v) <= P(w) - P(w*) + Strong duality holds: G(w*, v*) = 0. + For testing convergence, one uses G(w, v) with current w and uses + + v = R if ||X^T R||_inf <= alpha + v = R * alpha / ||X^T R||_inf else + The final stopping criterion is based on the duality gap tol ||y||_2^2 <= G(w, v) @@ -203,6 +257,18 @@ def enet_coordinate_descent( The tolerance here is multiplied by ||y||_2^2 to have an inequality that scales the same on both sides and because one has G(0, 0) = 1/2 ||y||_2^2. + Note: + The above dual D(v) and duality gap G require alpha > 0 because of the dual + feasible condition. + There is, however, an alternative dual formulation, see [Dünner 2016] 5.2.3 and + https://github.com/scikit-learn/scikit-learn/issues/22836: + + D(v) = -1/2 ||v||_2^2 + y' v + -1/(2 beta) sum_j (|X_j' v| - alpha)_+^2 (formulation B) + + The dual feasible set is v element real numbers. It requires beta > 0, but + alpha = 0 is allowed. Strong duality holds and at optimum, v* = y - X w*. + Returns ------- w : ndarray of shape (n_features,) @@ -225,6 +291,11 @@ def enet_coordinate_descent( Olivier Fercoq, Alexandre Gramfort, Joseph Salmon. (2015) Mind the duality gap: safer rules for the Lasso https://arxiv.org/abs/1505.03410 + + .. [Dünner 2016] + Celestine Dünner, Simon Forte, Martin Takác, Martin Jaggi. (2016). + Primal-Dual Rates and Certificates. In ICML 2016. + https://arxiv.org/abs/1602.05205 """ if floating is float: @@ -266,9 +337,9 @@ def enet_coordinate_descent( cdef uint32_t rand_r_state_seed = rng.randint(0, RAND_R_MAX) cdef uint32_t* rand_r_state = &rand_r_state_seed - if alpha == 0 and beta == 0: - warnings.warn("Coordinate descent with no regularization may lead to " - "unexpected results and is discouraged.") + if alpha == 0: + # No screeing without L1-penalty. + do_screening = False if do_screening: active_set = np.empty(n_features, dtype=np.uint32) # map [:n_active] -> j @@ -387,7 +458,7 @@ def enet_coordinate_descent( with gil: message = ( message_conv + - f" Duality gap: {gap:.3e}, tolerance: {tol:.3e}" + f" Duality gap: {gap:.6e}, tolerance: {tol:.3e}" ) if alpha < np.finfo(np.float64).eps: message += "\n" + message_ridge @@ -448,16 +519,61 @@ cdef (floating, floating) gap_enet_sparse( floating[::1] XtA, # XtA = X.T @ R - beta * w is calculated inplace bint positive, ) noexcept nogil: - """Compute dual gap for use in sparse_enet_coordinate_descent.""" + """Compute dual gap for use in sparse_enet_coordinate_descent. + + alpha > 0: formulation A of the duality gap + alpha = 0 & beta > 0: formulation B of the duality gap + alpha = beta = 0: OLS first order condition (=gradient) + """ cdef floating gap = 0.0 cdef floating dual_norm_XtA cdef floating R_norm2 - cdef floating w_norm2 = 0.0 - cdef floating l1_norm - cdef floating A_norm2 - cdef floating const_ + cdef floating Ry + cdef floating w_l1_norm + cdef floating w_l2_norm2 = 0.0 cdef unsigned int i, j + # w_l2_norm2 = w @ w + if beta > 0: + w_l2_norm2 = _dot(n_features, &w[0], 1, &w[0], 1) + # R_norm2 = R @ R + if no_sample_weights: + R_norm2 = _dot(n_samples, &R[0], 1, &R[0], 1) + else: + R_norm2 = 0.0 + for i in range(n_samples): + # R is already multiplied by sample_weight + if sample_weight[i] != 0: + R_norm2 += (R[i] ** 2) / sample_weight[i] + # Ry = R @ y + if not (alpha == 0 and beta == 0): + # Note that with sample_weight, R equals R*sw and y is just y, such that + # Ry = (sw * R) @ y, as it should be. + Ry = _dot(n_samples, &R[0], 1, &y[0], 1) + + if alpha == 0: + # XtA = X.T @ R + for j in range(n_features): + XtA[j] = 0.0 + for i in range(X_indptr[j], X_indptr[j + 1]): + XtA[j] += X_data[i] * R[X_indices[i]] + + if center: + XtA[j] -= X_mean[j] * R_sum + # ||X'R||_2^2 + dual_norm_XtA = _dot(n_features, &XtA[0], 1, &XtA[0], 1) + if beta == 0: + # This is OLS, no dual gap available. Resort to first order condition + # X'R = 0 + # gap = ||X'R||_2^2 + # Compare with stopping criterion of LSQR. + gap = dual_norm_XtA + return gap, dual_norm_XtA + # This is Ridge regression, we use formulation B for the dual gap. + gap = R_norm2 + 0.5 * beta * w_l2_norm2 - Ry + gap += 1 / (2 * beta) * dual_norm_XtA + return gap, dual_norm_XtA + # XtA = X.T @ R - beta * w # sparse X.T @ dense R for j in range(n_features): @@ -469,39 +585,23 @@ cdef (floating, floating) gap_enet_sparse( XtA[j] -= X_mean[j] * R_sum XtA[j] -= beta * w[j] + # dual_norm_XtA if positive: dual_norm_XtA = max(n_features, &XtA[0]) else: dual_norm_XtA = abs_max(n_features, &XtA[0]) - # R_norm2 = R @ R - if no_sample_weights: - R_norm2 = _dot(n_samples, &R[0], 1, &R[0], 1) - else: - R_norm2 = 0.0 - for i in range(n_samples): - # R is already multiplied by sample_weight - if sample_weight[i] != 0: - R_norm2 += (R[i] ** 2) / sample_weight[i] - - # w_norm2 = w @ w - if beta > 0: - w_norm2 = _dot(n_features, &w[0], 1, &w[0], 1) - - if (dual_norm_XtA > alpha): - const_ = alpha / dual_norm_XtA - A_norm2 = R_norm2 * const_**2 - gap = 0.5 * (R_norm2 + A_norm2) - else: - const_ = 1.0 - gap = R_norm2 - - l1_norm = _asum(n_features, &w[0], 1) - - gap += ( - alpha * l1_norm - - const_ * _dot(n_samples, &R[0], 1, &y[0], 1) # R @ y - + 0.5 * beta * (1 + const_ ** 2) * w_norm2 + # w_l1_norm = np.sum(np.abs(w)) + w_l1_norm = _asum(n_features, &w[0], 1) + + gap = dual_gap_formulation_A( + alpha=alpha, + beta=beta, + w_l1_norm=w_l1_norm, + w_l2_norm2=w_l2_norm2, + R_norm2=R_norm2, + Ry=Ry, + dual_norm_XtA=dual_norm_XtA, ) return gap, dual_norm_XtA @@ -606,6 +706,10 @@ def sparse_enet_coordinate_descent( cdef bint center = False cdef bint no_sample_weights = sample_weight is None + if alpha == 0: + # No screeing without L1-penalty. + do_screening = False + if do_screening: active_set = np.empty(n_features, dtype=np.uint32) # map [:n_active] -> j excluded_set = np.empty(n_features, dtype=np.uint8) @@ -843,7 +947,7 @@ def sparse_enet_coordinate_descent( with gil: message = ( message_conv + - f" Duality gap: {gap:.3e}, tolerance: {tol:.3e}" + f" Duality gap: {gap:.6e}, tolerance: {tol:.3e}" ) if alpha < np.finfo(np.float64).eps: message += "\n" + message_ridge @@ -863,53 +967,75 @@ cdef (floating, floating) gap_enet_gram( floating[::1] XtA, # XtA = X.T @ R - beta * w is calculated inplace bint positive, ) noexcept nogil: - """Compute dual gap for use in enet_coordinate_descent.""" + """Compute dual gap for use in enet_coordinate_descent. + + alpha > 0: formulation A of the duality gap + alpha = 0 & beta > 0: formulation B of the duality gap + alpha = beta = 0: OLS first order condition (=gradient) + """ cdef floating gap = 0.0 cdef floating dual_norm_XtA cdef floating R_norm2 - cdef floating w_norm2 = 0.0 - cdef floating l1_norm - cdef floating A_norm2 - cdef floating const_ + cdef floating Ry + cdef floating w_l1_norm + cdef floating w_l2_norm2 = 0.0 cdef floating q_dot_w cdef floating wQw cdef unsigned int j + # w_l2_norm2 = w @ w + if beta > 0: + w_l2_norm2 = _dot(n_features, &w[0], 1, &w[0], 1) # q_dot_w = w @ q q_dot_w = _dot(n_features, &w[0], 1, &q[0], 1) + # wQw = w @ Q @ w + wQw = _dot(n_features, &w[0], 1, &Qw[0], 1) + # R_norm2 = R @ R, residual R = y - Xw + R_norm2 = y_norm2 + wQw - 2.0 * q_dot_w + # Ry = R @ y + if not (alpha == 0 and beta == 0): + # Note that R'y = (y - Xw)' y = ||y||_2^2 - w'X'y = y_norm2 - q_dot_w + Ry = y_norm2 - q_dot_w + + if alpha == 0: + # XtA = X'R + for j in range(n_features): + XtA[j] = q[j] - Qw[j] + # ||X'R||_2^2 + dual_norm_XtA = _dot(n_features, &XtA[0], 1, &XtA[0], 1) + if beta == 0: + # This is OLS, no dual gap available. Resort to first order condition + # X'R = 0 + # gap = ||X'R||_2^2 + # Compare with stopping criterion of LSQR. + gap = dual_norm_XtA + return gap, dual_norm_XtA + # This is Ridge regression, we use formulation B for the dual gap. + gap = R_norm2 + 0.5 * beta * w_l2_norm2 - Ry + gap += 1 / (2 * beta) * dual_norm_XtA + return gap, dual_norm_XtA # XtA = X.T @ R - beta * w = X.T @ y - X.T @ X @ w - beta * w for j in range(n_features): XtA[j] = q[j] - Qw[j] - beta * w[j] + # dual_norm_XtA if positive: dual_norm_XtA = max(n_features, &XtA[0]) else: dual_norm_XtA = abs_max(n_features, &XtA[0]) - # wQw = w @ Q @ w - wQw = _dot(n_features, &w[0], 1, &Qw[0], 1) - # R_norm2 = R @ R - R_norm2 = y_norm2 + wQw - 2.0 * q_dot_w - - # w_norm2 = w @ w - if beta > 0: - w_norm2 = _dot(n_features, &w[0], 1, &w[0], 1) - - if (dual_norm_XtA > alpha): - const_ = alpha / dual_norm_XtA - A_norm2 = R_norm2 * (const_ ** 2) - gap = 0.5 * (R_norm2 + A_norm2) - else: - const_ = 1.0 - gap = R_norm2 - - l1_norm = _asum(n_features, &w[0], 1) - - gap += ( - alpha * l1_norm - - const_ * (y_norm2 - q_dot_w) # -const_ * R @ y - + 0.5 * beta * (1 + const_ ** 2) * w_norm2 + # w_l1_norm = np.sum(np.abs(w)) + w_l1_norm = _asum(n_features, &w[0], 1) + + gap = dual_gap_formulation_A( + alpha=alpha, + beta=beta, + w_l1_norm=w_l1_norm, + w_l2_norm2=w_l2_norm2, + R_norm2=R_norm2, + Ry=Ry, + dual_norm_XtA=dual_norm_XtA, ) return gap, dual_norm_XtA @@ -987,11 +1113,8 @@ def enet_coordinate_descent_gram( cdef uint32_t* rand_r_state = &rand_r_state_seed if alpha == 0: - warnings.warn( - "Coordinate descent without L1 regularization may " - "lead to unexpected results and is discouraged. " - "Set l1_ratio > 0 to add L1 regularization." - ) + # No screeing without L1-penalty. + do_screening = False if do_screening: active_set = np.empty(n_features, dtype=np.uint32) # map [:n_active] -> j @@ -1108,8 +1231,10 @@ def enet_coordinate_descent_gram( with gil: message = ( message_conv + - f" Duality gap: {gap:.3e}, tolerance: {tol:.3e}" + f" Duality gap: {gap:.6e}, tolerance: {tol:.3e}" ) + if alpha < np.finfo(np.float64).eps: + message += "\n" + message_ridge warnings.warn(message, ConvergenceWarning) return np.asarray(w), gap, tol, n_iter + 1 @@ -1145,12 +1270,39 @@ cdef (floating, floating) gap_enet_multi_task( cdef floating gap = 0.0 cdef floating dual_norm_XtA cdef floating R_norm2 - cdef floating w_norm2 = 0.0 - cdef floating l21_norm - cdef floating A_norm2 - cdef floating const_ + cdef floating Ry + cdef floating w_l21_norm + cdef floating w_l2_norm2 = 0.0 cdef unsigned int t, j + # w_l2_norm2 = linalg.norm(W, ord="fro") ** 2 + if l2_reg > 0: + w_l2_norm2 = _dot(n_features * n_tasks, &W[0, 0], 1, &W[0, 0], 1) + # R_norm2 = linalg.norm(R, ord="fro") ** 2 + R_norm2 = _dot(n_samples * n_tasks, &R[0, 0], 1, &R[0, 0], 1) + # Ry = np.sum(R * Y) + if not (l1_reg == 0 and l2_reg == 0): + Ry = _dot(n_samples * n_tasks, &R[0, 0], 1, &Y[0, 0], 1) + + if l1_reg == 0: + # XtA = X.T @ R + for j in range(n_features): + for t in range(n_tasks): + XtA[j, t] = _dot(n_samples, &X[0, j], 1, &R[0, t], 1) + # ||X'R||_2^2 + dual_norm_XtA = _dot(n_features * n_tasks, &XtA[0, 0], 1, &XtA[0, 0], 1) + if l2_reg == 0: + # This is OLS, no dual gap available. Resort to first order condition + # X'R = 0 + # gap = ||X'R||_2^2 + # Compare with stopping criterion of LSQR. + gap = dual_norm_XtA + return gap, dual_norm_XtA + # This is Ridge regression, we use formulation B for the dual gap. + gap = R_norm2 + 0.5 * l2_reg * w_l2_norm2 - Ry + gap += 1 / (2 * l2_reg) * dual_norm_XtA + return gap, dual_norm_XtA + # XtA = X.T @ R - l2_reg * W.T for j in range(n_features): for t in range(n_tasks): @@ -1164,30 +1316,19 @@ cdef (floating, floating) gap_enet_multi_task( if XtA_row_norms[j] > dual_norm_XtA: dual_norm_XtA = XtA_row_norms[j] - # R_norm2 = linalg.norm(R, ord="fro") ** 2 - R_norm2 = _dot(n_samples * n_tasks, &R[0, 0], 1, &R[0, 0], 1) - - # w_norm2 = linalg.norm(W, ord="fro") ** 2 - if l2_reg > 0: - w_norm2 = _dot(n_features * n_tasks, &W[0, 0], 1, &W[0, 0], 1) - - if (dual_norm_XtA > l1_reg): - const_ = l1_reg / dual_norm_XtA - A_norm2 = R_norm2 * (const_ ** 2) - gap = 0.5 * (R_norm2 + A_norm2) - else: - const_ = 1.0 - gap = R_norm2 - - # l21_norm = np.sqrt(np.sum(W ** 2, axis=0)).sum() - l21_norm = 0.0 + # w_l21_norm = np.sqrt(np.sum(W ** 2, axis=0)).sum() + w_l21_norm = 0.0 for ii in range(n_features): - l21_norm += _nrm2(n_tasks, &W[0, ii], 1) - - gap += ( - l1_reg * l21_norm - - const_ * _dot(n_samples * n_tasks, &R[0, 0], 1, &Y[0, 0], 1) # np.sum(R * Y) - + 0.5 * l2_reg * (1 + const_ ** 2) * w_norm2 + w_l21_norm += _nrm2(n_tasks, &W[0, ii], 1) + + gap = dual_gap_formulation_A( + alpha=l1_reg, + beta=l2_reg, + w_l1_norm=w_l21_norm, + w_l2_norm2=w_l2_norm2, + R_norm2=R_norm2, + Ry=Ry, + dual_norm_XtA=dual_norm_XtA, ) return gap, dual_norm_XtA @@ -1274,10 +1415,8 @@ def enet_coordinate_descent_multi_task( cdef uint32_t* rand_r_state = &rand_r_state_seed if l1_reg == 0: - warnings.warn( - "Coordinate descent with l1_reg=0 may lead to unexpected" - " results and is discouraged." - ) + # No screeing without L1-penalty. + do_screening = False if do_screening: active_set = np.empty(n_features, dtype=np.uint32) # map [:n_active] -> j @@ -1429,8 +1568,10 @@ def enet_coordinate_descent_multi_task( with gil: message = ( message_conv + - f" Duality gap: {gap:.3e}, tolerance: {tol:.3e}" + f" Duality gap: {gap:.6e}, tolerance: {tol:.3e}" ) + if l1_reg < np.finfo(np.float64).eps: + message += "\n" + message_ridge warnings.warn(message, ConvergenceWarning) return np.asarray(W), gap, tol, n_iter + 1 diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index 5fc734c33a078..fb6e6acd851f4 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -124,9 +124,8 @@ def _alpha_grid( l1_ratio : float, default=1.0 The elastic net mixing parameter, with ``0 < l1_ratio <= 1``. - For ``l1_ratio = 0`` the penalty is an L2 penalty. (currently not - supported) ``For l1_ratio = 1`` it is an L1 penalty. For - ``0 < l1_ratio <1``, the penalty is a combination of L1 and L2. + For ``l1_ratio = 0``, there would be no L1 penalty which is not supported + for the generation of alphas. eps : float, default=1e-3 Length of the path. ``eps=1e-3`` means that @@ -439,7 +438,7 @@ def enet_path( For multi-output tasks it is:: - (1 / (2 * n_samples)) * ||Y - XW||_Fro^2 + 1 / (2 * n_samples) * ||Y - XW||_Fro^2 + alpha * l1_ratio * ||W||_21 + 0.5 * alpha * (1 - l1_ratio) * ||W||_Fro^2 @@ -447,7 +446,7 @@ def enet_path( ||W||_21 = \\sum_i \\sqrt{\\sum_j w_{ij}^2} - i.e. the sum of norm of each row. + i.e. the sum of L2-norm of each row (task) (i=feature, j=task) Read more in the :ref:`User Guide `. diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index 2cb9eb9e9f45b..30d054067e116 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -18,6 +18,7 @@ Lasso, LassoCV, LassoLarsCV, + LinearRegression, MultiTaskElasticNet, MultiTaskElasticNetCV, MultiTaskLasso, @@ -580,16 +581,14 @@ def test_uniform_targets(): for model in models_single_task: for y_values in (0, 5): y1.fill(y_values) - with ignore_warnings(category=ConvergenceWarning): - assert_array_equal(model.fit(X_train, y1).predict(X_test), y1) + assert_array_equal(model.fit(X_train, y1).predict(X_test), y1) assert_array_equal(model.alphas_, [np.finfo(float).resolution] * 3) for model in models_multi_task: for y_values in (0, 5): y2[:, 0].fill(y_values) y2[:, 1].fill(2 * y_values) - with ignore_warnings(category=ConvergenceWarning): - assert_array_equal(model.fit(X_train, y2).predict(X_test), y2) + assert_array_equal(model.fit(X_train, y2).predict(X_test), y2) assert_array_equal(model.alphas_, [np.finfo(float).resolution] * 3) @@ -969,15 +968,14 @@ def test_check_input_false(): X, y, _, _ = build_dataset(n_samples=20, n_features=10) X = check_array(X, order="F", dtype="float64") y = check_array(X, order="F", dtype="float64") - clf = ElasticNet(selection="cyclic", tol=1e-8) + clf = ElasticNet(selection="cyclic", tol=1e-7) # Check that no error is raised if data is provided in the right format clf.fit(X, y, check_input=False) # With check_input=False, an exhaustive check is not made on y but its # dtype is still cast in _preprocess_data to X's dtype. So the test should # pass anyway X = check_array(X, order="F", dtype="float32") - with ignore_warnings(category=ConvergenceWarning): - clf.fit(X, y, check_input=False) + clf.fit(X, y, check_input=False) # With no input checking, providing X in C order should result in false # computation X = check_array(X, order="C", dtype="float64") @@ -1093,7 +1091,6 @@ def test_enet_float_precision(): ) -@pytest.mark.filterwarnings("ignore::sklearn.exceptions.ConvergenceWarning") def test_enet_l1_ratio(): # Test that an error message is raised if an estimator that # uses _alpha_grid is called with l1_ratio=0 @@ -1111,14 +1108,10 @@ def test_enet_l1_ratio(): with pytest.raises(ValueError, match=msg): MultiTaskElasticNetCV(l1_ratio=0, random_state=42).fit(X, y[:, None]) - # Test that l1_ratio=0 with alpha>0 produces user warning - warning_message = ( - "Coordinate descent without L1 regularization may " - "lead to unexpected results and is discouraged. " - "Set l1_ratio > 0 to add L1 regularization." - ) + # But no error for ElasticNetCV with l1_ratio=0 and alpha>0. est = ElasticNetCV(l1_ratio=[0], alphas=[1]) - with pytest.warns(UserWarning, match=warning_message): + with warnings.catch_warnings(): + warnings.simplefilter("error") est.fit(X, y) # Test that l1_ratio=0 is allowed if we supply a grid manually @@ -1126,16 +1119,14 @@ def test_enet_l1_ratio(): estkwds = {"alphas": alphas, "random_state": 42} est_desired = ElasticNetCV(l1_ratio=0.00001, **estkwds) est = ElasticNetCV(l1_ratio=0, **estkwds) - with ignore_warnings(): - est_desired.fit(X, y) - est.fit(X, y) + est_desired.fit(X, y) + est.fit(X, y) assert_array_almost_equal(est.coef_, est_desired.coef_, decimal=5) est_desired = MultiTaskElasticNetCV(l1_ratio=0.00001, **estkwds) est = MultiTaskElasticNetCV(l1_ratio=0, **estkwds) - with ignore_warnings(): - est.fit(X, y[:, None]) - est_desired.fit(X, y[:, None]) + est.fit(X, y[:, None]) + est_desired.fit(X, y[:, None]) assert_array_almost_equal(est.coef_, est_desired.coef_, decimal=5) @@ -1553,39 +1544,85 @@ def test_enet_sample_weight_does_not_overwrite_sample_weight(check_input): assert_array_equal(sample_weight, sample_weight_1_25) -@pytest.mark.filterwarnings("ignore::sklearn.exceptions.ConvergenceWarning") -@pytest.mark.parametrize("ridge_alpha", [1e-1, 1.0, 1e6]) -def test_enet_ridge_consistency(ridge_alpha): +@pytest.mark.parametrize("ridge_alpha", [1e-6, 1e-1, 1.0, 1e6]) +@pytest.mark.parametrize( + ["precompute", "n_targets"], [(False, 1), (True, 1), (False, 3)] +) +def test_enet_ridge_consistency(ridge_alpha, precompute, n_targets): # Check that ElasticNet(l1_ratio=0) converges to the same solution as Ridge # provided that the value of alpha is adapted. - # - # XXX: this test does not pass for weaker regularization (lower values of - # ridge_alpha): it could be either a problem of ElasticNet or Ridge (less - # likely) and depends on the dataset statistics: lower values for - # effective_rank are more problematic in particular. rng = np.random.RandomState(42) n_samples = 300 X, y = make_regression( n_samples=n_samples, n_features=100, + n_targets=n_targets, effective_rank=10, n_informative=50, random_state=rng, ) sw = rng.uniform(low=0.01, high=10, size=X.shape[0]) - alpha = 1.0 - common_params = dict( - tol=1e-12, + + if n_targets == 1: + sw_arg = dict(sample_weight=sw) + else: + # MultiTaskElasticNet does not support sample weights (yet). + sw_arg = dict() + + ridge = Ridge(alpha=ridge_alpha, solver="svd").fit(X, y, **sw_arg) + + tol = 1e-11 if ridge_alpha >= 1e-2 else 1e-16 + if n_targets == 1: + alpha_enet = ridge_alpha / sw.sum() + enet = ElasticNet(alpha=alpha_enet, l1_ratio=0, precompute=precompute, tol=tol) + else: + alpha_enet = ridge_alpha / n_samples + enet = MultiTaskElasticNet(alpha=alpha_enet, l1_ratio=0, tol=tol) + enet.fit(X, y, **sw_arg) + + # The CD solver using the gram matrix (precompute = True) loses numerical precision + # by working with the squares of matrices like Q=X'X (=gram) and + # R^2 = y^2 + wQw - 2yQw (=square of residuals). + rtol = 1e-5 if precompute else 1e-7 + assert_allclose(enet.coef_, ridge.coef_, rtol=rtol) + assert_allclose(enet.intercept_, ridge.intercept_) + + +@pytest.mark.filterwarnings("ignore:With alpha=0, this algorithm:UserWarning") +@pytest.mark.parametrize("precompute", [False, True]) +@pytest.mark.parametrize("effective_rank", [None, 10]) +def test_enet_ols_consistency(precompute, effective_rank): + """Test that ElasticNet(alpha=0) converges to the same solution as OLS.""" + rng = np.random.RandomState(42) + n_samples = 300 + X, y = make_regression( + n_samples=n_samples, + n_features=100, + effective_rank=effective_rank, + n_informative=50, + random_state=rng, ) - ridge = Ridge(alpha=alpha, **common_params).fit(X, y, sample_weight=sw) + sw = rng.uniform(low=0.01, high=10, size=X.shape[0]) - alpha_enet = alpha / sw.sum() - enet = ElasticNet(alpha=alpha_enet, l1_ratio=0, **common_params).fit( + ols = LinearRegression().fit(X, y, sample_weight=sw) + enet = ElasticNet(alpha=0, precompute=precompute, tol=1e-15).fit( X, y, sample_weight=sw ) - assert_allclose(ridge.coef_, enet.coef_) - assert_allclose(ridge.intercept_, enet.intercept_) + + # Might be a singular problem, so check for same predictions + assert_allclose(enet.predict(X), ols.predict(X)) + # and for similar objective function (squared error) + se_ols = np.sum((y - ols.predict(X)) ** 2) + se_enet = np.sum((y - enet.predict(X)) ** 2) + if precompute: + assert se_ols <= 1e-20 + assert se_enet <= 1e-20 + else: + assert se_enet <= se_ols <= 1e-20 # Who would have thought that? + # We check equal coefficients, but "only" with absolute tolerance. + assert_allclose(enet.coef_, ols.coef_, atol=1e-11) + assert_allclose(enet.intercept_, ols.intercept_, atol=1e-12) @pytest.mark.parametrize( @@ -1769,7 +1806,9 @@ def test_linear_model_cv_alphas_n_alphas_unset(Estimator): # TODO(1.9): remove @pytest.mark.filterwarnings("ignore:'n_alphas' was deprecated in 1.7") -@pytest.mark.filterwarnings("ignore:.*with no regularization.*:UserWarning") +@pytest.mark.filterwarnings( + "ignore:With alpha=0, this algorithm does not converge well.*:UserWarning" +) @pytest.mark.parametrize( "Estimator", [ElasticNetCV, LassoCV, MultiTaskLassoCV, MultiTaskElasticNetCV] ) diff --git a/sklearn/linear_model/tests/test_sparse_coordinate_descent.py b/sklearn/linear_model/tests/test_sparse_coordinate_descent.py index d7d85763f8a86..6e928f2fedad2 100644 --- a/sklearn/linear_model/tests/test_sparse_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_sparse_coordinate_descent.py @@ -271,11 +271,18 @@ def test_path_parameters(csc_container): @pytest.mark.parametrize("Model", [Lasso, ElasticNet, LassoCV, ElasticNetCV]) @pytest.mark.parametrize("fit_intercept", [False, True]) +@pytest.mark.parametrize("l1_ratio", [0.5, 0]) @pytest.mark.parametrize("n_samples, n_features", [(24, 6), (6, 24)]) @pytest.mark.parametrize("with_sample_weight", [True, False]) @pytest.mark.parametrize("csc_container", CSC_CONTAINERS) def test_sparse_dense_equality( - Model, fit_intercept, n_samples, n_features, with_sample_weight, csc_container + Model, + fit_intercept, + l1_ratio, + n_samples, + n_features, + with_sample_weight, + csc_container, ): X, y = make_regression( n_samples=n_samples, @@ -292,6 +299,11 @@ def test_sparse_dense_equality( sw = None Xs = csc_container(X) params = {"fit_intercept": fit_intercept, "tol": 1e-6} + if Model != ElasticNet: + if l1_ratio == 0: + return + else: + params["l1_ratio"] = l1_ratio reg_dense = Model(**params).fit(X, y, sample_weight=sw) reg_sparse = Model(**params).fit(Xs, y, sample_weight=sw) if fit_intercept: From 04c9f3eee9dafa76b92bc589e55e700398ca6e10 Mon Sep 17 00:00:00 2001 From: Junteng Li Date: Wed, 31 Dec 2025 15:19:53 +0000 Subject: [PATCH 085/462] FIX coordinate descent alpha_max for positive=True (#32768) Co-authored-by: Christian Lorentzen --- .../sklearn.linear_model/32768.fix.rst | 5 ++++ sklearn/linear_model/_coordinate_descent.py | 20 +++++++++++--- .../tests/test_coordinate_descent.py | 27 ++++++++++++++----- 3 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/32768.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32768.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32768.fix.rst new file mode 100644 index 0000000000000..67f1bee7687d8 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/32768.fix.rst @@ -0,0 +1,5 @@ +- :class:`linear_model.LassoCV` and :class:`linear_model.ElasticNetCV` now + take the `positive` parameter into account to compute the maximum `alpha` parameter, + where all coefficients are zero. This impacts the search grid for the + internally tuned `alpha` hyper-parameter stored in the attribute `alphas_`. + By :user:`Junteng Li ` diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index fb6e6acd851f4..9ab0312be04ce 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -102,6 +102,8 @@ def _alpha_grid( eps=1e-3, n_alphas=100, sample_weight=None, + *, + positive: bool = False, ): """Compute the grid of alpha values for elastic net parameter search @@ -139,6 +141,9 @@ def _alpha_grid( sample_weight : ndarray of shape (n_samples,), default=None + positive : bool, default=False + If set to True, forces coefficients to be positive. + Returns ------- np.ndarray @@ -185,9 +190,15 @@ def _alpha_grid( n_samples = sample_weight.sum() else: n_samples = X.shape[0] - # Compute np.max(np.sqrt(np.sum(Xyw**2, axis=1))). We switch sqrt and max to avoid - # many computations of sqrt. This, however, needs an additional np.abs. - alpha_max = np.sqrt(np.max(np.abs(np.sum(Xyw**2, axis=1)))) / (n_samples * l1_ratio) + + if not positive: + # Compute np.max(np.sqrt(np.sum(Xyw**2, axis=1))). We switch sqrt and max to + # avoid many computations of sqrt. + alpha_max = np.sqrt(np.max(np.sum(Xyw**2, axis=1))) / (n_samples * l1_ratio) + else: + # We may safely assume Xyw.shape[1] == 1, MultiTask estimators do not support + # positive constraints. + alpha_max = max(0, np.max(Xyw)) / (n_samples * l1_ratio) if alpha_max <= np.finfo(np.float64).resolution: return np.full(n_alphas, np.finfo(np.float64).resolution) @@ -641,6 +652,7 @@ def enet_path( Xy=Xy, l1_ratio=l1_ratio, fit_intercept=False, + positive=positive, eps=eps, n_alphas=n_alphas, ) @@ -1801,6 +1813,8 @@ def fit(self, X, y, sample_weight=None, **params): y, l1_ratio=l1_ratio, fit_intercept=self.fit_intercept, + # Note: MultiTaskElasticNetCV has no attribute 'positive' + positive=getattr(self, "positive", False), eps=self.eps, n_alphas=self._alphas, sample_weight=sample_weight, diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index 30d054067e116..571da531f3008 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -1492,23 +1492,38 @@ def test_enet_cv_sample_weight_consistency( @pytest.mark.parametrize("X_is_sparse", [False, True]) @pytest.mark.parametrize("fit_intercept", [False, True]) -@pytest.mark.parametrize("sample_weight", [np.array([10, 1, 10, 1]), None]) -def test_enet_alpha_max(X_is_sparse, fit_intercept, sample_weight): - X = np.array([[3.0, 1.0], [2.0, 5.0], [5.0, 3.0], [1.0, 4.0]]) - beta = np.array([1, 1]) +@pytest.mark.parametrize("positive", [False, True]) +@pytest.mark.parametrize("sample_weight", [np.array([1, 10, 1, 10]), None]) +def test_enet_alpha_max(X_is_sparse, fit_intercept, positive, sample_weight): + X = np.array([[3.0, -1.0], [2.0, -5.0], [5.0, -3.0], [1.0, -4.0]]) + beta = np.array([1, -2]) y = X @ beta + params = dict(fit_intercept=fit_intercept, positive=positive) + if X_is_sparse: X = sparse.csc_matrix(X) # Test alpha_max makes coefs zero. - reg = ElasticNetCV(alphas=1, cv=2, eps=1, fit_intercept=fit_intercept) + reg = ElasticNetCV(alphas=1, cv=2, eps=1, **params) reg.fit(X, y, sample_weight=sample_weight) assert_allclose(reg.coef_, 0, atol=1e-5) alpha_max = reg.alpha_ # Test smaller alpha makes coefs nonzero. - reg = ElasticNet(alpha=0.99 * alpha_max, fit_intercept=fit_intercept, tol=1e-8) + reg = ElasticNet(alpha=0.99 * alpha_max, tol=1e-8, **params) reg.fit(X, y, sample_weight=sample_weight) assert_array_less(1e-3, np.max(np.abs(reg.coef_))) + if positive: + # Make sure that the positive constraint changes alpha_max, + # i.e. test the meaningfulness of the test data. + not_positive_alpha_max = ( + ElasticNetCV(alphas=1, cv=2, eps=1, **{**params, "positive": not positive}) + .fit(X, y, sample_weight=sample_weight) + .alpha_ + ) + assert not np.isclose(alpha_max, not_positive_alpha_max), ( + "Test data cannot distinguish alpha_max between positive=True and False." + ) + @pytest.mark.parametrize("estimator", [ElasticNetCV, LassoCV]) def test_linear_models_cv_fit_with_loky(estimator): From e0c77885d7ac83c5cc9204fbe51044fc759fbcd5 Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Fri, 2 Jan 2026 14:01:57 +0100 Subject: [PATCH 086/462] FIX Error handling in ranking metrics supporting multiclass: `average_precision_score`, `roc_auc_score` and `top_k_accuracy_score` (#32912) --- sklearn/metrics/_ranking.py | 23 +++++++++++++++++++++-- sklearn/metrics/tests/test_ranking.py | 18 ++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index 8226e49bff6d0..782f5c0fc7dbe 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -142,7 +142,8 @@ def average_precision_score( Parameters ---------- y_true : array-like of shape (n_samples,) or (n_samples, n_classes) - True binary labels or :term:`multilabel indicator matrix`. + True binary labels, :term:`multi-label` indicators (as a + :term:`multilabel indicator matrix`) or :term:`multi-class` labels. y_score : array-like of shape (n_samples,) or (n_samples, n_classes) Target scores, can either be probability estimates of the positive @@ -261,6 +262,12 @@ def _binary_uninterpolated_average_precision( "Do not set pos_label or set pos_label to 1." ) y_true = label_binarize(y_true, classes=present_labels) + if not y_score.shape == y_true.shape: + raise ValueError( + "`y_score` needs to be of shape `(n_samples, n_classes)`, since " + "`y_true` contains multiple classes. Got " + f"`y_score.shape={y_score.shape}`." + ) average_precision = partial( _binary_uninterpolated_average_precision, pos_label=pos_label @@ -764,7 +771,12 @@ def _multiclass_roc_auc_score( Sample weights. """ - # validation of the input y_score + if not y_score.ndim == 2: + raise ValueError( + "`y_score` needs to be of shape `(n_samples, n_classes)`, since " + "`y_true` contains multiple classes. Got " + f"`y_score.shape={y_score.shape}`." + ) if not np.allclose(1, y_score.sum(axis=1)): raise ValueError( "Target scores need to be probabilities for multiclass " @@ -2111,6 +2123,13 @@ def top_k_accuracy_score( " labels, `labels` must be provided." ) y_score = column_or_1d(y_score) + else: + if not y_score.ndim == 2: + raise ValueError( + "`y_score` needs to be of shape `(n_samples, n_classes)`, since " + "`y_true` contains multiple classes. Got " + f"`y_score.shape={y_score.shape}`." + ) check_consistent_length(y_true, y_score, sample_weight) y_score_n_classes = y_score.shape[1] if y_score.ndim == 2 else 2 diff --git a/sklearn/metrics/tests/test_ranking.py b/sklearn/metrics/tests/test_ranking.py index 821537571ea1a..fb607d319482f 100644 --- a/sklearn/metrics/tests/test_ranking.py +++ b/sklearn/metrics/tests/test_ranking.py @@ -1212,7 +1212,7 @@ def test_average_precision_score_multilabel_pos_label_errors(): def test_average_precision_score_multiclass_pos_label_errors(): # Raise an error for multiclass y_true with pos_label other than 1 y_true = np.array([0, 1, 2, 0, 1, 2]) - y_pred = np.array( + y_score = np.array( [ [0.5, 0.2, 0.1], [0.4, 0.5, 0.3], @@ -1227,7 +1227,21 @@ def test_average_precision_score_multiclass_pos_label_errors(): "Do not set pos_label or set pos_label to 1." ) with pytest.raises(ValueError, match=err_msg): - average_precision_score(y_true, y_pred, pos_label=3) + average_precision_score(y_true, y_score, pos_label=3) + + +def test_multiclass_ranking_metrics_raise_for_incorrect_shape_of_y_score(): + """Test ranking metrics, with multiclass support, raise if shape `y_score` is 1D.""" + y_true = np.array([0, 1, 2, 0, 1, 2]) + y_score = np.array([0.5, 0.4, 0.8, 0.9, 0.8, 0.7]) + + msg = re.escape("`y_score` needs to be of shape `(n_samples, n_classes)`") + with pytest.raises(ValueError, match=msg): + average_precision_score(y_true, y_score) + with pytest.raises(ValueError, match=msg): + roc_auc_score(y_true, y_score, multi_class="ovr") + with pytest.raises(ValueError, match=msg): + top_k_accuracy_score(y_true, y_score) def test_score_scale_invariance(): From 6dce55ebff962076625db46ab70b6b1c939f423b Mon Sep 17 00:00:00 2001 From: Omar Salman Date: Sat, 3 Jan 2026 00:34:41 +0500 Subject: [PATCH 087/462] FIX remove the special check in `test_enet_ols_consistency` (#32988) --- .../tests/test_coordinate_descent.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index 571da531f3008..788e097db0003 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -1607,9 +1607,9 @@ def test_enet_ridge_consistency(ridge_alpha, precompute, n_targets): @pytest.mark.filterwarnings("ignore:With alpha=0, this algorithm:UserWarning") @pytest.mark.parametrize("precompute", [False, True]) @pytest.mark.parametrize("effective_rank", [None, 10]) -def test_enet_ols_consistency(precompute, effective_rank): +def test_enet_ols_consistency(precompute, effective_rank, global_random_seed): """Test that ElasticNet(alpha=0) converges to the same solution as OLS.""" - rng = np.random.RandomState(42) + rng = np.random.RandomState(global_random_seed) n_samples = 300 X, y = make_regression( n_samples=n_samples, @@ -1628,16 +1628,13 @@ def test_enet_ols_consistency(precompute, effective_rank): # Might be a singular problem, so check for same predictions assert_allclose(enet.predict(X), ols.predict(X)) # and for similar objective function (squared error) - se_ols = np.sum((y - ols.predict(X)) ** 2) - se_enet = np.sum((y - enet.predict(X)) ** 2) - if precompute: - assert se_ols <= 1e-20 - assert se_enet <= 1e-20 - else: - assert se_enet <= se_ols <= 1e-20 # Who would have thought that? + se_ols = np.sum(sw * (y - ols.predict(X)) ** 2) + se_enet = np.sum(sw * (y - enet.predict(X)) ** 2) + assert se_ols <= 1e-19 + assert se_enet <= 1e-19 # We check equal coefficients, but "only" with absolute tolerance. assert_allclose(enet.coef_, ols.coef_, atol=1e-11) - assert_allclose(enet.intercept_, ols.intercept_, atol=1e-12) + assert_allclose(enet.intercept_, ols.intercept_, atol=1e-11) @pytest.mark.parametrize( From 1b0138758b026e968b15cab68c931c69e5249f17 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 5 Jan 2026 09:38:12 +0100 Subject: [PATCH 088/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#32997) Co-authored-by: Lock file bot --- .../azure/pylatest_free_threaded_linux-64_conda.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index 4429c158b51ad..da6285265539f 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -4,8 +4,8 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#3251796e09870c978e0f69fa05e38fb6 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-h8577fbf_0.conda#338201218b54cadff2e774ac27733990 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 @@ -38,7 +38,7 @@ https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-he1279bd_0_cp314t. https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.2-py314hd8ed1ab_0.conda#d0ce45508dd9dffaec3795252897bd7a -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.3-py314h3f98dc2_1.conda#d328a09daecc1ad3d8fa272f836fb65f +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.conda#cc2fcbfdf0628b5ad05b319866187bbc https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 From d155ee985f1c328eedb39b01c6b8fbed26db1f4a Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 5 Jan 2026 09:41:28 +0100 Subject: [PATCH 089/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#32998) Co-authored-by: Lock file bot --- .../azure/pylatest_pip_scipy_dev_linux-64_conda.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 8d2d71fa8f849..8076c0d955bcc 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -4,8 +4,8 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-h8577fbf_0.conda#338201218b54cadff2e774ac27733990 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 @@ -36,7 +36,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#e https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 -# pip certifi @ https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl#sha256=97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b +# pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c # pip charset-normalizer @ https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 # pip coverage @ https://files.pythonhosted.org/packages/82/2b/783ded568f7cd6b677762f780ad338bf4b4750205860c17c25f7c708995e/coverage-7.13.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de @@ -72,5 +72,5 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip pooch @ https://files.pythonhosted.org/packages/a8/87/77cc11c7a9ea9fd05503def69e3d18605852cd0d4b0d3b8f15bbeb3ef1d1/pooch-1.8.2-py3-none-any.whl#sha256=3529a57096f7198778a5ceefd5ac3ef0e4d06a6ddaf9fc2d609b806f25302c47 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 -# pip sphinx @ https://files.pythonhosted.org/packages/c6/3f/4bbd76424c393caead2e1eb89777f575dee5c8653e2d4b6afd7a564f5974/sphinx-9.0.4-py3-none-any.whl#sha256=5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb +# pip sphinx @ https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl#sha256=c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978 # pip numpydoc @ https://files.pythonhosted.org/packages/6c/45/56d99ba9366476cd8548527667f01869279cedb9e66b28eb4dfb27701679/numpydoc-1.8.0-py3-none-any.whl#sha256=72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541 From dba7037676c2d433fe3dd449092fc88feca9bf95 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 5 Jan 2026 09:42:03 +0100 Subject: [PATCH 090/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#32999) Co-authored-by: Lock file bot --- ...test_conda_forge_cuda_array-api_linux-64_conda.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index e4b487bc0ed4e..4f3b72530b5bd 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -12,8 +12,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.1 https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2024.2.2-ha770c72_17.conda#c18fd07c02239a7eb744ea728db39630 https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-h8577fbf_0.conda#338201218b54cadff2e774ac27733990 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 @@ -142,10 +142,10 @@ https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#e https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.3-py313hc80a56d_1.conda#5e6c9f05c2825daad3d8006d3e2474ac +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda#9bcbd351966dc56a24fc0c368da5ad99 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.1-pyhd8ed1ab_0.conda#81a651287d3000eb12f0860ade0a1b41 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.2-pyhd8ed1ab_0.conda#7e7cf4d6c2be6991e6ae2b3f4331701c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.12.0-pyhd8ed1ab_0.conda#a3b9510e2491c20c7fc0f5e730227fbb https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 @@ -165,7 +165,7 @@ https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#3 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h80991f8_2.conda#37ca27d2f726f29a068230d8f6917ce4 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py313h80991f8_0.conda#183fe6b9e99e5c2b464c1573ec78eac8 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 From 60fb6bd45047c72a4096c89a721b833d02aa032a Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Mon, 5 Jan 2026 09:47:40 +0100 Subject: [PATCH 091/462] MNT Update year to 2026 in COPYING (#32992) --- COPYING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/COPYING b/COPYING index e1cd01d584578..3d7ee432c15b6 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2007-2024 The scikit-learn developers. +Copyright (c) 2007-2026 The scikit-learn developers. All rights reserved. Redistribution and use in source and binary forms, with or without From abcfa076153a841af6efcac7860338605b83a3d7 Mon Sep 17 00:00:00 2001 From: clijo <52968726+clijo@users.noreply.github.com> Date: Mon, 5 Jan 2026 10:11:40 +0100 Subject: [PATCH 092/462] DOC Fix truncated summaries caused by 'a.k.a.' (#32995) --- sklearn/linear_model/_least_angle.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/linear_model/_least_angle.py b/sklearn/linear_model/_least_angle.py index 7c29f350fd200..c50b552313925 100644 --- a/sklearn/linear_model/_least_angle.py +++ b/sklearn/linear_model/_least_angle.py @@ -918,7 +918,7 @@ def _lars_path_solver( class Lars(MultiOutputMixin, RegressorMixin, LinearModel): - """Least Angle Regression model a.k.a. LAR. + """Least Angle Regression model aka LAR. Read more in the :ref:`User Guide `. @@ -1208,7 +1208,7 @@ def fit(self, X, y, Xy=None): class LassoLars(Lars): - """Lasso model fit with Least Angle Regression a.k.a. Lars. + """Lasso model fit with Least Angle Regression aka Lars. It is a Linear Model trained with an L1 prior as regularizer. From 3db0cd3caa3bf114917589865cd789f208e80322 Mon Sep 17 00:00:00 2001 From: "Christine P. Chai" Date: Mon, 5 Jan 2026 01:13:08 -0800 Subject: [PATCH 093/462] DOC: Correct many a/an usage mistakes (#32996) --- doc/api_reference.py | 2 +- doc/developers/cython.rst | 4 ++-- doc/make.bat | 2 +- doc/modules/feature_selection.rst | 2 +- doc/modules/model_evaluation.rst | 2 +- examples/covariance/plot_covariance_estimation.py | 2 +- examples/covariance/plot_lw_vs_oas.py | 2 +- examples/ensemble/plot_hgbt_regression.py | 2 +- examples/linear_model/plot_lasso_and_elasticnet.py | 2 +- sklearn/datasets/tests/test_openml.py | 2 +- sklearn/decomposition/tests/test_kernel_pca.py | 2 +- sklearn/feature_selection/tests/test_rfe.py | 2 +- sklearn/kernel_approximation.py | 8 ++++---- sklearn/linear_model/_logistic.py | 8 ++++---- sklearn/metrics/tests/test_pairwise.py | 2 +- sklearn/multiclass.py | 2 +- sklearn/svm/tests/test_bounds.py | 2 +- sklearn/utils/_bunch.py | 2 +- sklearn/utils/_repr_html/estimator.py | 2 +- sklearn/utils/_repr_html/tests/test_js.py | 2 +- sklearn/utils/estimator_checks.py | 2 +- sklearn/utils/tests/test_arpack.py | 2 +- 22 files changed, 29 insertions(+), 29 deletions(-) diff --git a/doc/api_reference.py b/doc/api_reference.py index d003b0bafd558..340f75ce941b7 100644 --- a/doc/api_reference.py +++ b/doc/api_reference.py @@ -603,7 +603,7 @@ def _get_submodule(module_name, submodule_name): "title": "Regressors with variable selection", "description": ( "The following estimators have built-in variable selection fitting " - "procedures, but any estimator using a L1 or elastic-net penalty " + "procedures, but any estimator using an L1 or elastic-net penalty " "also performs variable selection: typically " ":class:`~linear_model.SGDRegressor` or " ":class:`~sklearn.linear_model.SGDClassifier` with an appropriate " diff --git a/doc/developers/cython.rst b/doc/developers/cython.rst index c1f371dd8a8da..1732525a495f2 100644 --- a/doc/developers/cython.rst +++ b/doc/developers/cython.rst @@ -66,7 +66,7 @@ Tips to ease development # This generates `source.c` as if you had recompiled scikit-learn entirely. cythonX --annotate source.pyx -* Using the ``--annotate`` option with this flag allows generating a HTML report of code annotation. +* Using the ``--annotate`` option with this flag allows generating an HTML report of code annotation. This report indicates interactions with the CPython interpreter on a line-by-line basis. Interactions with the CPython interpreter must be avoided as much as possible in the computationally intensive sections of the algorithms. @@ -74,7 +74,7 @@ Tips to ease development .. code-block:: - # This generates a HTML report (`source.html`) for `source.c`. + # This generates an HTML report (`source.html`) for `source.c`. cythonX --annotate source.pyx Tips for performance diff --git a/doc/make.bat b/doc/make.bat index 2a32bcb678f62..7d4b48ad1ed88 100644 --- a/doc/make.bat +++ b/doc/make.bat @@ -18,7 +18,7 @@ if "%1" == "help" ( echo. dirhtml to make HTML files named index.html in directories echo. pickle to make pickle files echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project + echo. htmlhelp to make HTML files and an HTML help project echo. qthelp to make HTML files and a qthelp project echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. changes to make an overview over all changed/added/deprecated items diff --git a/doc/modules/feature_selection.rst b/doc/modules/feature_selection.rst index ffee801f34ccc..a245c2bf4339d 100644 --- a/doc/modules/feature_selection.rst +++ b/doc/modules/feature_selection.rst @@ -70,7 +70,7 @@ as objects that implement the ``transform`` method: selection with a configurable strategy. This allows to select the best univariate selection strategy with hyper-parameter search estimator. -For instance, we can use a F-test to retrieve the two +For instance, we can use an F-test to retrieve the two best features for a dataset as follows: >>> from sklearn.datasets import load_iris diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index a5e32336da38c..922eb3a752c79 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -1134,7 +1134,7 @@ Note the following behaviors when averaging: * If all labels are included, "micro"-averaging in a multiclass setting will produce precision, recall and :math:`F` that are all identical to accuracy. -* "weighted" averaging may produce a F-score that is not between precision and recall. +* "weighted" averaging may produce an F-score that is not between precision and recall. * "macro" averaging for F-measures is calculated as the arithmetic mean over per-label/class F-measures, not the harmonic mean over the arithmetic precision and recall means. Both calculations can be seen in the literature but are not equivalent, diff --git a/examples/covariance/plot_covariance_estimation.py b/examples/covariance/plot_covariance_estimation.py index f8bee76ea7ae7..18c7737f31b34 100644 --- a/examples/covariance/plot_covariance_estimation.py +++ b/examples/covariance/plot_covariance_estimation.py @@ -71,7 +71,7 @@ # according to a grid of potential shrinkage parameters. # # * A close formula proposed by Ledoit and Wolf to compute -# the asymptotically optimal regularization parameter (minimizing a MSE +# the asymptotically optimal regularization parameter (minimizing an MSE # criterion), yielding the :class:`~sklearn.covariance.LedoitWolf` # covariance estimate. # diff --git a/examples/covariance/plot_lw_vs_oas.py b/examples/covariance/plot_lw_vs_oas.py index 6ec995c5c3b01..1611404a64ce0 100644 --- a/examples/covariance/plot_lw_vs_oas.py +++ b/examples/covariance/plot_lw_vs_oas.py @@ -5,7 +5,7 @@ The usual covariance maximum likelihood estimate can be regularized using shrinkage. Ledoit and Wolf proposed a close formula to compute -the asymptotically optimal shrinkage parameter (minimizing a MSE +the asymptotically optimal shrinkage parameter (minimizing an MSE criterion), yielding the Ledoit-Wolf covariance estimate. Chen et al. [1]_ proposed an improvement of the Ledoit-Wolf shrinkage diff --git a/examples/ensemble/plot_hgbt_regression.py b/examples/ensemble/plot_hgbt_regression.py index dce97a6e0b700..777f6a2fa897e 100644 --- a/examples/ensemble/plot_hgbt_regression.py +++ b/examples/ensemble/plot_hgbt_regression.py @@ -326,7 +326,7 @@ def generate_missing_values(X, missing_fraction): # # Given specific domain knowledge that requires the relationship between a # feature and the target to be monotonically increasing or decreasing, one can -# enforce such behaviour in the predictions of a HGBT model using monotonic +# enforce such behaviour in the predictions of an HGBT model using monotonic # constraints. This makes the model more interpretable and can reduce its # variance (and potentially mitigate overfitting) at the risk of increasing # bias. Monotonic constraints can also be used to enforce specific regulatory diff --git a/examples/linear_model/plot_lasso_and_elasticnet.py b/examples/linear_model/plot_lasso_and_elasticnet.py index 235a65fe731ea..cdfded2c2ae1a 100644 --- a/examples/linear_model/plot_lasso_and_elasticnet.py +++ b/examples/linear_model/plot_lasso_and_elasticnet.py @@ -153,7 +153,7 @@ # # :class:`~sklearn.linear_model.ElasticNet` is a middle ground between # :class:`~sklearn.linear_model.Lasso` and :class:`~sklearn.linear_model.Ridge`, -# as it combines a L1 and a L2-penalty. The amount of regularization is +# as it combines an L1 and an L2-penalty. The amount of regularization is # controlled by the two hyperparameters `l1_ratio` and `alpha`. For `l1_ratio = # 0` the penalty is pure L2 and the model is equivalent to a # :class:`~sklearn.linear_model.Ridge`. Similarly, `l1_ratio = 1` is a pure L1 diff --git a/sklearn/datasets/tests/test_openml.py b/sklearn/datasets/tests/test_openml.py index 3c29a526a008b..eb551814bc6e1 100644 --- a/sklearn/datasets/tests/test_openml.py +++ b/sklearn/datasets/tests/test_openml.py @@ -163,7 +163,7 @@ def _mock_urlopen_data_list(url, has_gzip_header): data_file_name = _file_name(url, ".json") data_file_path = resources.files(data_module) / data_file_name - # load the file itself, to simulate a http error + # load the file itself, to simulate an http error with data_file_path.open("rb") as f: decompressed_f = read_fn(f, "rb") decoded_s = decompressed_f.read().decode("utf-8") diff --git a/sklearn/decomposition/tests/test_kernel_pca.py b/sklearn/decomposition/tests/test_kernel_pca.py index 6d77a6379a2b7..47c6890df776e 100644 --- a/sklearn/decomposition/tests/test_kernel_pca.py +++ b/sklearn/decomposition/tests/test_kernel_pca.py @@ -355,7 +355,7 @@ def test_nested_circles(): train_score = Perceptron(max_iter=5).fit(X, y).score(X, y) assert train_score < 0.8 - # Project the circles data into the first 2 components of a RBF Kernel + # Project the circles data into the first 2 components of an RBF Kernel # PCA model. # Note that the gamma value is data dependent. If this test breaks # and the gamma value has to be updated, the Kernel PCA example will diff --git a/sklearn/feature_selection/tests/test_rfe.py b/sklearn/feature_selection/tests/test_rfe.py index 1f5672545874c..b7d5457202ed3 100644 --- a/sklearn/feature_selection/tests/test_rfe.py +++ b/sklearn/feature_selection/tests/test_rfe.py @@ -665,7 +665,7 @@ def test_rfe_estimator_attribute_error(): ) def test_rfe_n_features_to_select_warning(ClsRFE, param): """Check if the correct warning is raised when trying to initialize a RFE - object with a n_features_to_select attribute larger than the number of + object with an n_features_to_select attribute larger than the number of features present in the X variable that is passed to the fit method """ X, y = make_classification(n_features=20, random_state=0) diff --git a/sklearn/kernel_approximation.py b/sklearn/kernel_approximation.py index bd60f8494bf61..564295339fc77 100644 --- a/sklearn/kernel_approximation.py +++ b/sklearn/kernel_approximation.py @@ -99,7 +99,7 @@ class PolynomialCountSketch( -------- AdditiveChi2Sampler : Approximate feature map for additive chi2 kernel. Nystroem : Approximate a kernel map using a subset of the training data. - RBFSampler : Approximate a RBF kernel feature map using random Fourier + RBFSampler : Approximate an RBF kernel feature map using random Fourier features. SkewedChi2Sampler : Approximate feature map for "skewed chi-squared" kernel. sklearn.metrics.pairwise.kernel_metrics : List of built-in kernels. @@ -246,7 +246,7 @@ def __sklearn_tags__(self): class RBFSampler(ClassNamePrefixFeaturesOutMixin, TransformerMixin, BaseEstimator): - """Approximate a RBF kernel feature map using random Fourier features. + """Approximate an RBF kernel feature map using random Fourier features. It implements a variant of Random Kitchen Sinks.[1] @@ -465,7 +465,7 @@ class SkewedChi2Sampler( -------- AdditiveChi2Sampler : Approximate feature map for additive chi2 kernel. Nystroem : Approximate a kernel map using a subset of the training data. - RBFSampler : Approximate a RBF kernel feature map using random Fourier + RBFSampler : Approximate an RBF kernel feature map using random Fourier features. SkewedChi2Sampler : Approximate feature map for "skewed chi-squared" kernel. sklearn.metrics.pairwise.chi2_kernel : The exact chi squared kernel. @@ -923,7 +923,7 @@ class Nystroem(ClassNamePrefixFeaturesOutMixin, TransformerMixin, BaseEstimator) -------- AdditiveChi2Sampler : Approximate feature map for additive chi2 kernel. PolynomialCountSketch : Polynomial kernel approximation via Tensor Sketch. - RBFSampler : Approximate a RBF kernel feature map using random Fourier + RBFSampler : Approximate an RBF kernel feature map using random Fourier features. SkewedChi2Sampler : Approximate feature map for "skewed chi-squared" kernel. sklearn.metrics.pairwise.kernel_metrics : List of built-in kernels. diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index e3ce9dd12efa0..0a566961dd497 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -761,8 +761,8 @@ class LogisticRegression(LinearClassifierMixin, SparseCoefMixin, BaseEstimator): Specify the norm of the penalty: - `None`: no penalty is added; - - `'l2'`: add a L2 penalty term and it is the default choice; - - `'l1'`: add a L1 penalty term; + - `'l2'`: add an L2 penalty term and it is the default choice; + - `'l1'`: add an L1 penalty term; - `'elasticnet'`: both L1 and L2 penalty terms are added. .. warning:: @@ -1432,8 +1432,8 @@ class LogisticRegressionCV(LogisticRegression, LinearClassifierMixin, BaseEstima penalty : {'l1', 'l2', 'elasticnet'}, default='l2' Specify the norm of the penalty: - - `'l2'`: add a L2 penalty term (used by default); - - `'l1'`: add a L1 penalty term; + - `'l2'`: add an L2 penalty term (used by default); + - `'l1'`: add an L1 penalty term; - `'elasticnet'`: both L1 and L2 penalty terms are added. .. warning:: diff --git a/sklearn/metrics/tests/test_pairwise.py b/sklearn/metrics/tests/test_pairwise.py index 0efa3647f5122..b6e96e76c2465 100644 --- a/sklearn/metrics/tests/test_pairwise.py +++ b/sklearn/metrics/tests/test_pairwise.py @@ -1465,7 +1465,7 @@ def test_rbf_kernel(): rng = np.random.RandomState(0) X = rng.random_sample((5, 4)) K = rbf_kernel(X, X) - # the diagonal elements of a rbf kernel are 1 + # the diagonal elements of an rbf kernel are 1 assert_allclose(K.flat[::6], np.ones(5)) diff --git a/sklearn/multiclass.py b/sklearn/multiclass.py index c01aad10dab3e..92d8c8a960dd7 100644 --- a/sklearn/multiclass.py +++ b/sklearn/multiclass.py @@ -1252,7 +1252,7 @@ def predict(self, X): """ check_is_fitted(self) # ArgKmin only accepts C-contiguous array. The aggregated predictions need to be - # transposed. We therefore create a F-contiguous array to avoid a copy and have + # transposed. We therefore create an F-contiguous array to avoid a copy and have # a C-contiguous array after the transpose operation. Y = np.array( [_predict_binary(e, X) for e in self.estimators_], diff --git a/sklearn/svm/tests/test_bounds.py b/sklearn/svm/tests/test_bounds.py index d226a2ae36aeb..dce08b0866bce 100644 --- a/sklearn/svm/tests/test_bounds.py +++ b/sklearn/svm/tests/test_bounds.py @@ -105,7 +105,7 @@ def test_newrand_bounded_rand_int(range_, n_pts): sample = [bounded_rand_int_wrap(range_) for _ in range(n_pts)] res = stats.kstest(sample, uniform_dist.cdf) ks_pvals.append(res.pvalue) - # Null hypothesis = samples come from an uniform distribution. + # Null hypothesis = samples come from a uniform distribution. # Under the null hypothesis, p-values should be uniformly distributed # and not concentrated on low values # (this may seem counter-intuitive but is backed by multiple refs) diff --git a/sklearn/utils/_bunch.py b/sklearn/utils/_bunch.py index a11e80e366135..ed030f05033af 100644 --- a/sklearn/utils/_bunch.py +++ b/sklearn/utils/_bunch.py @@ -59,7 +59,7 @@ def __getattr__(self, key): raise AttributeError(key) def __setstate__(self, state): - # Bunch pickles generated with scikit-learn 0.16.* have an non + # Bunch pickles generated with scikit-learn 0.16.* have a non # empty __dict__. This causes a surprising behaviour when # loading these pickles scikit-learn 0.17: reading bunch.key # uses __dict__ but assigning to bunch.key use __setattr__ and diff --git a/sklearn/utils/_repr_html/estimator.py b/sklearn/utils/_repr_html/estimator.py index 831f2485d9ebb..d3d86e69def13 100644 --- a/sklearn/utils/_repr_html/estimator.py +++ b/sklearn/utils/_repr_html/estimator.py @@ -414,7 +414,7 @@ def _write_estimator_html( def estimator_html_repr(estimator): - """Build a HTML representation of an estimator. + """Build an HTML representation of an estimator. Read more in the :ref:`User Guide `. diff --git a/sklearn/utils/_repr_html/tests/test_js.py b/sklearn/utils/_repr_html/tests/test_js.py index 69101b95eb0e0..35cdf8057d8e1 100644 --- a/sklearn/utils/_repr_html/tests/test_js.py +++ b/sklearn/utils/_repr_html/tests/test_js.py @@ -60,7 +60,7 @@ def log_message(self, format, *args): def _make_page(body): - """Helper to create a HTML page that includes `estimator.js` and the given body.""" + """Helper to create an HTML page that includes `estimator.js` and the given body.""" js_path = Path(__file__).parent.parent / "estimator.js" with open(js_path, "r", encoding="utf-8") as f: diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index 84edd1ae838c5..7fd36041f608a 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -4090,7 +4090,7 @@ def check_transformer_n_iter(name, estimator_orig): set_random_state(estimator, 0) estimator.fit(X, y_) - # These return a n_iter per component. + # These return an n_iter per component. if name in CROSS_DECOMPOSITION: for iter_ in estimator.n_iter_: assert iter_ >= 1 diff --git a/sklearn/utils/tests/test_arpack.py b/sklearn/utils/tests/test_arpack.py index ab1d622d51a08..33a2a75980de0 100644 --- a/sklearn/utils/tests/test_arpack.py +++ b/sklearn/utils/tests/test_arpack.py @@ -7,7 +7,7 @@ @pytest.mark.parametrize("seed", range(100)) def test_init_arpack_v0(seed): - # check that the initialization a sampling from an uniform distribution + # check that the initialization a sampling from a uniform distribution # where we can fix the random state size = 1000 v0 = _init_arpack_v0(size, seed) From 932c8bf22d018cd054904a3f498a4eac0d6d40f0 Mon Sep 17 00:00:00 2001 From: Lucas Colley Date: Mon, 5 Jan 2026 09:30:56 +0000 Subject: [PATCH 094/462] MNT: externals: bump array-api-compat to v1.13 (#32962) Co-authored-by: Olivier Grisel --- maint_tools/vendor_array_api_compat.sh | 2 +- .../externals/array_api_compat/__init__.py | 2 +- .../externals/array_api_compat/_internal.py | 24 +- .../array_api_compat/common/_aliases.py | 39 +-- .../array_api_compat/common/_helpers.py | 247 ++++++++++-------- .../array_api_compat/common/_linalg.py | 8 +- .../array_api_compat/common/_typing.py | 15 +- .../array_api_compat/cupy/__init__.py | 13 +- .../array_api_compat/cupy/_aliases.py | 58 ++-- .../array_api_compat/cupy/_typing.py | 1 - .../externals/array_api_compat/cupy/fft.py | 16 +- .../externals/array_api_compat/cupy/linalg.py | 8 +- .../array_api_compat/dask/array/__init__.py | 18 +- .../array_api_compat/dask/array/_aliases.py | 9 +- .../array_api_compat/dask/array/_info.py | 47 ++-- .../array_api_compat/dask/array/fft.py | 19 +- .../array_api_compat/dask/array/linalg.py | 40 ++- .../array_api_compat/numpy/__init__.py | 24 +- .../array_api_compat/numpy/_aliases.py | 65 ++--- .../externals/array_api_compat/numpy/_info.py | 3 +- .../array_api_compat/numpy/_typing.py | 1 - .../externals/array_api_compat/numpy/fft.py | 15 +- .../array_api_compat/numpy/linalg.py | 33 +-- .../array_api_compat/torch/__init__.py | 29 +- .../array_api_compat/torch/_aliases.py | 236 +++++++++-------- .../externals/array_api_compat/torch/fft.py | 37 ++- .../array_api_compat/torch/linalg.py | 29 +- 27 files changed, 528 insertions(+), 510 deletions(-) diff --git a/maint_tools/vendor_array_api_compat.sh b/maint_tools/vendor_array_api_compat.sh index 51056ce477cbb..96282b52733a8 100755 --- a/maint_tools/vendor_array_api_compat.sh +++ b/maint_tools/vendor_array_api_compat.sh @@ -6,7 +6,7 @@ set -o nounset set -o errexit URL="https://github.com/data-apis/array-api-compat.git" -VERSION="1.12" +VERSION="1.13" ROOT_DIR=sklearn/externals/array_api_compat diff --git a/sklearn/externals/array_api_compat/__init__.py b/sklearn/externals/array_api_compat/__init__.py index 653cb40a37607..4abca400a24f7 100644 --- a/sklearn/externals/array_api_compat/__init__.py +++ b/sklearn/externals/array_api_compat/__init__.py @@ -17,6 +17,6 @@ this implementation for the default when working with NumPy arrays. """ -__version__ = '1.12.0' +__version__ = '1.13.0' from .common import * # noqa: F401, F403 diff --git a/sklearn/externals/array_api_compat/_internal.py b/sklearn/externals/array_api_compat/_internal.py index cd8d939f36de2..baa39ded8decf 100644 --- a/sklearn/externals/array_api_compat/_internal.py +++ b/sklearn/externals/array_api_compat/_internal.py @@ -2,6 +2,7 @@ Internal helpers """ +import importlib from collections.abc import Callable from functools import wraps from inspect import signature @@ -46,14 +47,31 @@ def wrapped_f(*args: object, **kwargs: object) -> object: specification for more details. """ - wrapped_f.__signature__ = new_sig # pyright: ignore[reportAttributeAccessIssue] - return wrapped_f # pyright: ignore[reportReturnType] + wrapped_f.__signature__ = new_sig # type: ignore[attr-defined] # pyright: ignore[reportAttributeAccessIssue] + return wrapped_f # type: ignore[return-value] # pyright: ignore[reportReturnType] return inner -__all__ = ["get_xp"] +def clone_module(mod_name: str, globals_: dict[str, object]) -> list[str]: + """Import everything from module, updating globals(). + Returns __all__. + """ + mod = importlib.import_module(mod_name) + # Neither of these two methods is sufficient by itself, + # depending on various idiosyncrasies of the libraries we're wrapping. + objs = {} + exec(f"from {mod.__name__} import *", objs) + + for n in dir(mod): + if not n.startswith("_") and hasattr(mod, n): + objs[n] = getattr(mod, n) + + globals_.update(objs) + return list(objs) + +__all__ = ["get_xp", "clone_module"] def __dir__() -> list[str]: return __all__ diff --git a/sklearn/externals/array_api_compat/common/_aliases.py b/sklearn/externals/array_api_compat/common/_aliases.py index 8ea9162a9edc8..3587ef16fa18b 100644 --- a/sklearn/externals/array_api_compat/common/_aliases.py +++ b/sklearn/externals/array_api_compat/common/_aliases.py @@ -5,11 +5,12 @@ from __future__ import annotations import inspect -from typing import TYPE_CHECKING, Any, NamedTuple, Optional, Sequence, cast +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, NamedTuple, cast from ._helpers import _check_device, array_namespace from ._helpers import device as _get_device -from ._helpers import is_cupy_namespace as _is_cupy_namespace +from ._helpers import is_cupy_namespace from ._typing import Array, Device, DType, Namespace if TYPE_CHECKING: @@ -381,8 +382,8 @@ def clip( # TODO: np.clip has other ufunc kwargs out: Array | None = None, ) -> Array: - def _isscalar(a: object) -> TypeIs[int | float | None]: - return isinstance(a, (int, float, type(None))) + def _isscalar(a: object) -> TypeIs[float | None]: + return isinstance(a, int | float) or a is None min_shape = () if _isscalar(min) else min.shape max_shape = () if _isscalar(max) else max.shape @@ -450,7 +451,7 @@ def reshape( shape: tuple[int, ...], xp: Namespace, *, - copy: Optional[bool] = None, + copy: bool | None = None, **kwargs: object, ) -> Array: if copy is True: @@ -524,27 +525,6 @@ def nonzero(x: Array, /, xp: Namespace, **kwargs: object) -> tuple[Array, ...]: return xp.nonzero(x, **kwargs) -# ceil, floor, and trunc return integers for integer inputs - - -def ceil(x: Array, /, xp: Namespace, **kwargs: object) -> Array: - if xp.issubdtype(x.dtype, xp.integer): - return x - return xp.ceil(x, **kwargs) - - -def floor(x: Array, /, xp: Namespace, **kwargs: object) -> Array: - if xp.issubdtype(x.dtype, xp.integer): - return x - return xp.floor(x, **kwargs) - - -def trunc(x: Array, /, xp: Namespace, **kwargs: object) -> Array: - if xp.issubdtype(x.dtype, xp.integer): - return x - return xp.trunc(x, **kwargs) - - # linear algebra functions @@ -657,7 +637,7 @@ def sign(x: Array, /, xp: Namespace, **kwargs: object) -> Array: out = xp.sign(x, **kwargs) # CuPy sign() does not propagate nans. See # https://github.com/data-apis/array-api-compat/issues/136 - if _is_cupy_namespace(xp) and isdtype(x.dtype, "real floating", xp=xp): + if is_cupy_namespace(xp) and isdtype(x.dtype, "real floating", xp=xp): out[xp.isnan(x)] = xp.nan return out[()] @@ -707,9 +687,6 @@ def iinfo(type_: DType | Array, /, xp: Namespace) -> Any: "argsort", "sort", "nonzero", - "ceil", - "floor", - "trunc", "matmul", "matrix_transpose", "tensordot", @@ -720,8 +697,6 @@ def iinfo(type_: DType | Array, /, xp: Namespace) -> Any: "finfo", "iinfo", ] -_all_ignore = ["inspect", "array_namespace", "NamedTuple"] - def __dir__() -> list[str]: return __all__ diff --git a/sklearn/externals/array_api_compat/common/_helpers.py b/sklearn/externals/array_api_compat/common/_helpers.py index 77175d0d1e974..8194a083db92f 100644 --- a/sklearn/externals/array_api_compat/common/_helpers.py +++ b/sklearn/externals/array_api_compat/common/_helpers.py @@ -8,6 +8,7 @@ from __future__ import annotations +import enum import inspect import math import sys @@ -22,7 +23,6 @@ SupportsIndex, TypeAlias, TypeGuard, - TypeVar, cast, overload, ) @@ -30,32 +30,29 @@ from ._typing import Array, Device, HasShape, Namespace, SupportsArrayNamespace if TYPE_CHECKING: - + import cupy as cp import dask.array as da import jax import ndonnx as ndx import numpy as np import numpy.typing as npt - import sparse # pyright: ignore[reportMissingTypeStubs] + import sparse import torch # TODO: import from typing (requires Python >=3.13) - from typing_extensions import TypeIs, TypeVar - - _SizeT = TypeVar("_SizeT", bound = int | None) + from typing_extensions import TypeIs _ZeroGradientArray: TypeAlias = npt.NDArray[np.void] - _CupyArray: TypeAlias = Any # cupy has no py.typed _ArrayApiObj: TypeAlias = ( npt.NDArray[Any] + | cp.ndarray | da.Array | jax.Array | ndx.Array | sparse.SparseArray | torch.Tensor | SupportsArrayNamespace[Any] - | _CupyArray ) _API_VERSIONS_OLD: Final = frozenset({"2021.12", "2022.12", "2023.12"}) @@ -95,7 +92,7 @@ def _is_jax_zero_gradient_array(x: object) -> TypeGuard[_ZeroGradientArray]: return dtype == jax.float0 -def is_numpy_array(x: object) -> TypeGuard[npt.NDArray[Any]]: +def is_numpy_array(x: object) -> TypeIs[npt.NDArray[Any]]: """ Return True if `x` is a NumPy array. @@ -238,7 +235,17 @@ def is_jax_array(x: object) -> TypeIs[jax.Array]: is_pydata_sparse_array """ cls = cast(Hashable, type(x)) - return _issubclass_fast(cls, "jax", "Array") or _is_jax_zero_gradient_array(x) + # We test for jax.core.Tracer here to identify jax arrays during jit tracing. From jax 0.8.2 on, + # tracers are not a subclass of jax.Array anymore. Note that tracers can also represent + # non-array values and a fully correct implementation would need to use isinstance checks. Since + # we use hash-based caching with type names as keys, we cannot use instance checks without + # losing performance here. For more information, see + # https://github.com/data-apis/array-api-compat/pull/369 and the corresponding issue. + return ( + _issubclass_fast(cls, "jax", "Array") + or _issubclass_fast(cls, "jax.core", "Tracer") + or _is_jax_zero_gradient_array(x) + ) def is_pydata_sparse_array(x: object) -> TypeIs[sparse.SparseArray]: @@ -266,7 +273,7 @@ def is_pydata_sparse_array(x: object) -> TypeIs[sparse.SparseArray]: return _issubclass_fast(cls, "sparse", "SparseArray") -def is_array_api_obj(x: object) -> TypeIs[_ArrayApiObj]: # pyright: ignore[reportUnknownParameterType] +def is_array_api_obj(x: object) -> TypeGuard[_ArrayApiObj]: """ Return True if `x` is an array API compatible array object. @@ -299,6 +306,7 @@ def _is_array_api_cls(cls: type) -> bool: or _issubclass_fast(cls, "sparse", "SparseArray") # TODO: drop support for jax<0.4.32 which didn't have __array_namespace__ or _issubclass_fast(cls, "jax", "Array") + or _issubclass_fast(cls, "jax.core", "Tracer") # see is_jax_array for limitations ) @@ -485,6 +493,86 @@ def _check_api_version(api_version: str | None) -> None: ) +class _ClsToXPInfo(enum.Enum): + SCALAR = 0 + MAYBE_JAX_ZERO_GRADIENT = 1 + + +@lru_cache(100) +def _cls_to_namespace( + cls: type, + api_version: str | None, + use_compat: bool | None, +) -> tuple[Namespace | None, _ClsToXPInfo | None]: + if use_compat not in (None, True, False): + raise ValueError("use_compat must be None, True, or False") + _use_compat = use_compat in (None, True) + cls_ = cast(Hashable, cls) # Make mypy happy + + if ( + _issubclass_fast(cls_, "numpy", "ndarray") + or _issubclass_fast(cls_, "numpy", "generic") + ): + if use_compat is True: + _check_api_version(api_version) + from .. import numpy as xp + elif use_compat is False: + import numpy as xp # type: ignore[no-redef] + else: + # NumPy 2.0+ have __array_namespace__; however they are not + # yet fully array API compatible. + from .. import numpy as xp # type: ignore[no-redef] + return xp, _ClsToXPInfo.MAYBE_JAX_ZERO_GRADIENT + + # Note: this must happen _after_ the test for np.generic, + # because np.float64 and np.complex128 are subclasses of float and complex. + if issubclass(cls, int | float | complex | type(None)): + return None, _ClsToXPInfo.SCALAR + + if _issubclass_fast(cls_, "cupy", "ndarray"): + if _use_compat: + _check_api_version(api_version) + from .. import cupy as xp # type: ignore[no-redef] + else: + import cupy as xp # type: ignore[no-redef] + return xp, None + + if _issubclass_fast(cls_, "torch", "Tensor"): + if _use_compat: + _check_api_version(api_version) + from .. import torch as xp # type: ignore[no-redef] + else: + import torch as xp # type: ignore[no-redef] + return xp, None + + if _issubclass_fast(cls_, "dask.array", "Array"): + if _use_compat: + _check_api_version(api_version) + from ..dask import array as xp # type: ignore[no-redef] + else: + import dask.array as xp # type: ignore[no-redef] + return xp, None + + # Backwards compatibility for jax<0.4.32 + if _issubclass_fast(cls_, "jax", "Array"): + return _jax_namespace(api_version, use_compat), None + + return None, None + + +def _jax_namespace(api_version: str | None, use_compat: bool | None) -> Namespace: + if use_compat: + raise ValueError("JAX does not have an array-api-compat wrapper") + import jax.numpy as jnp + if not hasattr(jnp, "__array_namespace_info__"): + # JAX v0.4.32 and newer implements the array API directly in jax.numpy. + # For older JAX versions, it is available via jax.experimental.array_api. + # jnp.Array objects gain the __array_namespace__ method. + import jax.experimental.array_api # noqa: F401 + # Test api_version + return jnp.empty(0).__array_namespace__(api_version=api_version) + + def array_namespace( *xs: Array | complex | None, api_version: str | None = None, @@ -553,105 +641,40 @@ def your_function(x, y): is_pydata_sparse_array """ - if use_compat not in [None, True, False]: - raise ValueError("use_compat must be None, True, or False") - - _use_compat = use_compat in [None, True] - namespaces: set[Namespace] = set() for x in xs: - if is_numpy_array(x): - import numpy as np - - from .. import numpy as numpy_namespace - - if use_compat is True: - _check_api_version(api_version) - namespaces.add(numpy_namespace) - elif use_compat is False: - namespaces.add(np) - else: - # numpy 2.0+ have __array_namespace__, however, they are not yet fully array API - # compatible. - namespaces.add(numpy_namespace) - elif is_cupy_array(x): - if _use_compat: - _check_api_version(api_version) - from .. import cupy as cupy_namespace - - namespaces.add(cupy_namespace) - else: - import cupy as cp # pyright: ignore[reportMissingTypeStubs] - - namespaces.add(cp) - elif is_torch_array(x): - if _use_compat: - _check_api_version(api_version) - from .. import torch as torch_namespace - - namespaces.add(torch_namespace) - else: - import torch - - namespaces.add(torch) - elif is_dask_array(x): - if _use_compat: - _check_api_version(api_version) - from ..dask import array as dask_namespace - - namespaces.add(dask_namespace) - else: - import dask.array as da - - namespaces.add(da) - elif is_jax_array(x): - if use_compat is True: - _check_api_version(api_version) - raise ValueError("JAX does not have an array-api-compat wrapper") - elif use_compat is False: - import jax.numpy as jnp - else: - # JAX v0.4.32 and newer implements the array API directly in jax.numpy. - # For older JAX versions, it is available via jax.experimental.array_api. - import jax.numpy - - if hasattr(jax.numpy, "__array_api_version__"): - jnp = jax.numpy - else: - import jax.experimental.array_api as jnp # pyright: ignore[reportMissingImports] - namespaces.add(jnp) - elif is_pydata_sparse_array(x): - if use_compat is True: - _check_api_version(api_version) - raise ValueError("`sparse` does not have an array-api-compat wrapper") - else: - import sparse # pyright: ignore[reportMissingTypeStubs] - # `sparse` is already an array namespace. We do not have a wrapper - # submodule for it. - namespaces.add(sparse) - elif hasattr(x, "__array_namespace__"): - if use_compat is True: + xp, info = _cls_to_namespace(cast(Hashable, type(x)), api_version, use_compat) + if info is _ClsToXPInfo.SCALAR: + continue + + if ( + info is _ClsToXPInfo.MAYBE_JAX_ZERO_GRADIENT + and _is_jax_zero_gradient_array(x) + ): + xp = _jax_namespace(api_version, use_compat) + + if xp is None: + get_ns = getattr(x, "__array_namespace__", None) + if get_ns is None: + raise TypeError(f"{type(x).__name__} is not a supported array type") + if use_compat: raise ValueError( "The given array does not have an array-api-compat wrapper" ) - x = cast("SupportsArrayNamespace[Any]", x) - namespaces.add(x.__array_namespace__(api_version=api_version)) - elif isinstance(x, (bool, int, float, complex, type(None))): - continue - else: - # TODO: Support Python scalars? - raise TypeError(f"{type(x).__name__} is not a supported array type") + xp = get_ns(api_version=api_version) - if not namespaces: - raise TypeError("Unrecognized array input") + namespaces.add(xp) - if len(namespaces) != 1: + try: + (xp,) = namespaces + return xp + except ValueError: + if not namespaces: + raise TypeError( + "array_namespace requires at least one non-scalar array input" + ) raise TypeError(f"Multiple namespaces for array inputs: {namespaces}") - (xp,) = namespaces - - return xp - # backwards compatibility alias get_namespace = array_namespace @@ -732,7 +755,7 @@ def device(x: _ArrayApiObj, /) -> Device: return "cpu" elif is_dask_array(x): # Peek at the metadata of the Dask array to determine type - if is_numpy_array(x._meta): # pyright: ignore + if is_numpy_array(x._meta): # Must be on CPU since backed by numpy return "cpu" return _DASK_DEVICE @@ -761,7 +784,7 @@ def device(x: _ArrayApiObj, /) -> Device: return "cpu" # Return the device of the constituent array return device(inner) # pyright: ignore - return x.device # pyright: ignore + return x.device # type: ignore # pyright: ignore # Prevent shadowing, used below @@ -770,11 +793,11 @@ def device(x: _ArrayApiObj, /) -> Device: # Based on cupy.array_api.Array.to_device def _cupy_to_device( - x: _CupyArray, + x: cp.ndarray, device: Device, /, stream: int | Any | None = None, -) -> _CupyArray: +) -> cp.ndarray: import cupy as cp if device == "cpu": @@ -803,7 +826,7 @@ def _torch_to_device( x: torch.Tensor, device: torch.device | str | int, /, - stream: None = None, + stream: int | Any | None = None, ) -> torch.Tensor: if stream is not None: raise NotImplementedError @@ -869,7 +892,7 @@ def to_device(x: Array, device: Device, /, *, stream: int | Any | None = None) - # cupy does not yet have to_device return _cupy_to_device(x, device, stream=stream) elif is_torch_array(x): - return _torch_to_device(x, device, stream=stream) # pyright: ignore[reportArgumentType] + return _torch_to_device(x, device, stream=stream) elif is_dask_array(x): if stream is not None: raise ValueError("The stream argument to to_device() is not supported") @@ -896,8 +919,6 @@ def to_device(x: Array, device: Device, /, *, stream: int | Any | None = None) - @overload def size(x: HasShape[Collection[SupportsIndex]]) -> int: ... @overload -def size(x: HasShape[Collection[None]]) -> None: ... -@overload def size(x: HasShape[Collection[SupportsIndex | None]]) -> int | None: ... def size(x: HasShape[Collection[SupportsIndex | None]]) -> int | None: """ @@ -924,6 +945,7 @@ def _is_writeable_cls(cls: type) -> bool | None: if ( _issubclass_fast(cls, "numpy", "generic") or _issubclass_fast(cls, "jax", "Array") + or _issubclass_fast(cls, "jax.core", "Tracer") # see is_jax_array for limitations or _issubclass_fast(cls, "sparse", "SparseArray") ): return False @@ -932,7 +954,7 @@ def _is_writeable_cls(cls: type) -> bool | None: return None -def is_writeable_array(x: object) -> bool: +def is_writeable_array(x: object) -> TypeGuard[_ArrayApiObj]: """ Return False if ``x.__setitem__`` is expected to raise; True otherwise. Return False if `x` is not an array API compatible object. @@ -963,6 +985,7 @@ def _is_lazy_cls(cls: type) -> bool | None: return False if ( _issubclass_fast(cls, "jax", "Array") + or _issubclass_fast(cls, "jax.core", "Tracer") # see is_jax_array for limitations or _issubclass_fast(cls, "dask.array", "Array") or _issubclass_fast(cls, "ndonnx", "Array") ): @@ -970,7 +993,7 @@ def _is_lazy_cls(cls: type) -> bool | None: return None -def is_lazy_array(x: object) -> bool: +def is_lazy_array(x: object) -> TypeGuard[_ArrayApiObj]: """Return True if x is potentially a future or it may be otherwise impossible or expensive to eagerly read its contents, regardless of their size, e.g. by calling ``bool(x)`` or ``float(x)``. @@ -1052,7 +1075,5 @@ def is_lazy_array(x: object) -> bool: "to_device", ] -_all_ignore = ['lru_cache', 'sys', 'math', 'inspect', 'warnings'] - def __dir__() -> list[str]: return __all__ diff --git a/sklearn/externals/array_api_compat/common/_linalg.py b/sklearn/externals/array_api_compat/common/_linalg.py index 7ad87a1be9105..69672af768d06 100644 --- a/sklearn/externals/array_api_compat/common/_linalg.py +++ b/sklearn/externals/array_api_compat/common/_linalg.py @@ -8,7 +8,7 @@ if np.__version__[0] == "2": from numpy.lib.array_utils import normalize_axis_tuple else: - from numpy.core.numeric import normalize_axis_tuple + from numpy.core.numeric import normalize_axis_tuple # type: ignore[no-redef] from .._internal import get_xp from ._aliases import isdtype, matmul, matrix_transpose, tensordot, vecdot @@ -187,14 +187,14 @@ def vector_norm( # We can't reuse xp.linalg.norm(keepdims) because of the reshape hacks # above to avoid matrix norm logic. shape = list(x.shape) - _axis = cast( + axes = cast( "tuple[int, ...]", normalize_axis_tuple( # pyright: ignore[reportCallIssue] range(x.ndim) if axis is None else axis, x.ndim, ), ) - for i in _axis: + for i in axes: shape[i] = 1 res = xp.reshape(res, tuple(shape)) @@ -225,8 +225,6 @@ def trace( 'matrix_transpose', 'svdvals', 'vecdot', 'vector_norm', 'diagonal', 'trace'] -_all_ignore = ['math', 'normalize_axis_tuple', 'get_xp', 'np', 'isdtype'] - def __dir__() -> list[str]: return __all__ diff --git a/sklearn/externals/array_api_compat/common/_typing.py b/sklearn/externals/array_api_compat/common/_typing.py index cd26feeba4dff..11b00bd10395f 100644 --- a/sklearn/externals/array_api_compat/common/_typing.py +++ b/sklearn/externals/array_api_compat/common/_typing.py @@ -34,32 +34,29 @@ # - docs: https://github.com/jorenham/optype/blob/master/README.md#just # - code: https://github.com/jorenham/optype/blob/master/optype/_core/_just.py @final -class JustInt(Protocol): - @property +class JustInt(Protocol): # type: ignore[misc] + @property # type: ignore[override] def __class__(self, /) -> type[int]: ... @__class__.setter def __class__(self, value: type[int], /) -> None: ... # pyright: ignore[reportIncompatibleMethodOverride] @final -class JustFloat(Protocol): - @property +class JustFloat(Protocol): # type: ignore[misc] + @property # type: ignore[override] def __class__(self, /) -> type[float]: ... @__class__.setter def __class__(self, value: type[float], /) -> None: ... # pyright: ignore[reportIncompatibleMethodOverride] @final -class JustComplex(Protocol): - @property +class JustComplex(Protocol): # type: ignore[misc] + @property # type: ignore[override] def __class__(self, /) -> type[complex]: ... @__class__.setter def __class__(self, value: type[complex], /) -> None: ... # pyright: ignore[reportIncompatibleMethodOverride] -# - - class NestedSequence(Protocol[_T_co]): def __getitem__(self, key: int, /) -> _T_co | NestedSequence[_T_co]: ... def __len__(self, /) -> int: ... diff --git a/sklearn/externals/array_api_compat/cupy/__init__.py b/sklearn/externals/array_api_compat/cupy/__init__.py index 9a30f95ddf12c..af003c5adaa52 100644 --- a/sklearn/externals/array_api_compat/cupy/__init__.py +++ b/sklearn/externals/array_api_compat/cupy/__init__.py @@ -1,3 +1,4 @@ +from typing import Final from cupy import * # noqa: F403 # from cupy import * doesn't overwrite these builtin names @@ -5,9 +6,19 @@ # These imports may overwrite names from the import * above. from ._aliases import * # noqa: F403 +from ._info import __array_namespace_info__ # noqa: F401 # See the comment in the numpy __init__.py __import__(__package__ + '.linalg') __import__(__package__ + '.fft') -__array_api_version__ = '2024.12' +__array_api_version__: Final = '2024.12' + +__all__ = sorted( + {name for name in globals() if not name.startswith("__")} + - {"Final", "_aliases", "_info", "_typing"} + | {"__array_api_version__", "__array_namespace_info__", "linalg", "fft"} +) + +def __dir__() -> list[str]: + return __all__ diff --git a/sklearn/externals/array_api_compat/cupy/_aliases.py b/sklearn/externals/array_api_compat/cupy/_aliases.py index 90b48f059bafa..2e512fc896399 100644 --- a/sklearn/externals/array_api_compat/cupy/_aliases.py +++ b/sklearn/externals/array_api_compat/cupy/_aliases.py @@ -1,13 +1,12 @@ from __future__ import annotations -from typing import Optional +from builtins import bool as py_bool import cupy as cp from ..common import _aliases, _helpers from ..common._typing import NestedSequence, SupportsBufferProtocol from .._internal import get_xp -from ._info import __array_namespace_info__ from ._typing import Array, Device, DType bool = cp.bool_ @@ -54,9 +53,6 @@ argsort = get_xp(cp)(_aliases.argsort) sort = get_xp(cp)(_aliases.sort) nonzero = get_xp(cp)(_aliases.nonzero) -ceil = get_xp(cp)(_aliases.ceil) -floor = get_xp(cp)(_aliases.floor) -trunc = get_xp(cp)(_aliases.trunc) matmul = get_xp(cp)(_aliases.matmul) matrix_transpose = get_xp(cp)(_aliases.matrix_transpose) tensordot = get_xp(cp)(_aliases.tensordot) @@ -67,18 +63,13 @@ # asarray also adds the copy keyword, which is not present in numpy 1.0. def asarray( - obj: ( - Array - | bool | int | float | complex - | NestedSequence[bool | int | float | complex] - | SupportsBufferProtocol - ), + obj: Array | complex | NestedSequence[complex] | SupportsBufferProtocol, /, *, - dtype: Optional[DType] = None, - device: Optional[Device] = None, - copy: Optional[bool] = None, - **kwargs, + dtype: DType | None = None, + device: Device | None = None, + copy: py_bool | None = None, + **kwargs: object, ) -> Array: """ Array API compatibility wrapper for asarray(). @@ -101,8 +92,8 @@ def astype( dtype: DType, /, *, - copy: bool = True, - device: Optional[Device] = None, + copy: py_bool = True, + device: Device | None = None, ) -> Array: if device is None: return x.astype(dtype=dtype, copy=copy) @@ -113,8 +104,8 @@ def astype( # cupy.count_nonzero does not have keepdims def count_nonzero( x: Array, - axis=None, - keepdims=False + axis: int | tuple[int, ...] | None = None, + keepdims: py_bool = False, ) -> Array: result = cp.count_nonzero(x, axis) if keepdims: @@ -123,9 +114,28 @@ def count_nonzero( return cp.expand_dims(result, axis) return result +# ceil, floor, and trunc return integers for integer inputs + +def ceil(x: Array, /) -> Array: + if cp.issubdtype(x.dtype, cp.integer): + return x.copy() + return cp.ceil(x) + + +def floor(x: Array, /) -> Array: + if cp.issubdtype(x.dtype, cp.integer): + return x.copy() + return cp.floor(x) + + +def trunc(x: Array, /) -> Array: + if cp.issubdtype(x.dtype, cp.integer): + return x.copy() + return cp.trunc(x) + # take_along_axis: axis defaults to -1 but in cupy (and numpy) axis is a required arg -def take_along_axis(x: Array, indices: Array, /, *, axis: int = -1): +def take_along_axis(x: Array, indices: Array, /, *, axis: int = -1) -> Array: return cp.take_along_axis(x, indices, axis=axis) @@ -146,11 +156,13 @@ def take_along_axis(x: Array, indices: Array, /, *, axis: int = -1): else: unstack = get_xp(cp)(_aliases.unstack) -__all__ = _aliases.__all__ + ['__array_namespace_info__', 'asarray', 'astype', +__all__ = _aliases.__all__ + ['asarray', 'astype', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'bitwise_left_shift', 'bitwise_invert', 'bitwise_right_shift', 'bool', 'concat', 'count_nonzero', 'pow', 'sign', - 'take_along_axis'] + 'ceil', 'floor', 'trunc', 'take_along_axis'] + -_all_ignore = ['cp', 'get_xp'] +def __dir__() -> list[str]: + return __all__ diff --git a/sklearn/externals/array_api_compat/cupy/_typing.py b/sklearn/externals/array_api_compat/cupy/_typing.py index d8e49ca773dc5..e5c202dc53e09 100644 --- a/sklearn/externals/array_api_compat/cupy/_typing.py +++ b/sklearn/externals/array_api_compat/cupy/_typing.py @@ -1,7 +1,6 @@ from __future__ import annotations __all__ = ["Array", "DType", "Device"] -_all_ignore = ["cp"] from typing import TYPE_CHECKING diff --git a/sklearn/externals/array_api_compat/cupy/fft.py b/sklearn/externals/array_api_compat/cupy/fft.py index 307e0f7277710..53a9a45438651 100644 --- a/sklearn/externals/array_api_compat/cupy/fft.py +++ b/sklearn/externals/array_api_compat/cupy/fft.py @@ -1,10 +1,11 @@ -from cupy.fft import * # noqa: F403 +from cupy.fft import * # noqa: F403 + # cupy.fft doesn't have __all__. If it is added, replace this with # # from cupy.fft import __all__ as linalg_all -_n = {} -exec('from cupy.fft import *', _n) -del _n['__builtins__'] +_n: dict[str, object] = {} +exec("from cupy.fft import *", _n) +del _n["__builtins__"] fft_all = list(_n) del _n @@ -30,7 +31,6 @@ __all__ = fft_all + _fft.__all__ -del get_xp -del cp -del fft_all -del _fft +def __dir__() -> list[str]: + return __all__ + diff --git a/sklearn/externals/array_api_compat/cupy/linalg.py b/sklearn/externals/array_api_compat/cupy/linalg.py index 7fcdd498e0073..da301574728a7 100644 --- a/sklearn/externals/array_api_compat/cupy/linalg.py +++ b/sklearn/externals/array_api_compat/cupy/linalg.py @@ -2,7 +2,7 @@ # cupy.linalg doesn't have __all__. If it is added, replace this with # # from cupy.linalg import __all__ as linalg_all -_n = {} +_n: dict[str, object] = {} exec('from cupy.linalg import *', _n) del _n['__builtins__'] linalg_all = list(_n) @@ -43,7 +43,5 @@ __all__ = linalg_all + _linalg.__all__ -del get_xp -del cp -del linalg_all -del _linalg +def __dir__() -> list[str]: + return __all__ diff --git a/sklearn/externals/array_api_compat/dask/array/__init__.py b/sklearn/externals/array_api_compat/dask/array/__init__.py index 1e47b9606b774..f78aa8b378444 100644 --- a/sklearn/externals/array_api_compat/dask/array/__init__.py +++ b/sklearn/externals/array_api_compat/dask/array/__init__.py @@ -1,12 +1,26 @@ from typing import Final -from dask.array import * # noqa: F403 +from ..._internal import clone_module + +__all__ = clone_module("dask.array", globals()) # These imports may overwrite names from the import * above. -from ._aliases import * # noqa: F403 +from . import _aliases +from ._aliases import * # type: ignore[assignment] # noqa: F403 +from ._info import __array_namespace_info__ # noqa: F401 __array_api_version__: Final = "2024.12" +del Final # See the comment in the numpy __init__.py __import__(__package__ + '.linalg') __import__(__package__ + '.fft') + +__all__ = sorted( + set(__all__) + | set(_aliases.__all__) + | {"__array_api_version__", "__array_namespace_info__", "linalg", "fft"} +) + +def __dir__() -> list[str]: + return __all__ diff --git a/sklearn/externals/array_api_compat/dask/array/_aliases.py b/sklearn/externals/array_api_compat/dask/array/_aliases.py index d43881ab18f1c..54d323b2a5b6f 100644 --- a/sklearn/externals/array_api_compat/dask/array/_aliases.py +++ b/sklearn/externals/array_api_compat/dask/array/_aliases.py @@ -41,7 +41,6 @@ NestedSequence, SupportsBufferProtocol, ) -from ._info import __array_namespace_info__ isdtype = get_xp(np)(_aliases.isdtype) unstack = get_xp(da)(_aliases.unstack) @@ -134,9 +133,6 @@ def arange( matrix_transpose = get_xp(da)(_aliases.matrix_transpose) vecdot = get_xp(da)(_aliases.vecdot) nonzero = get_xp(da)(_aliases.nonzero) -ceil = get_xp(np)(_aliases.ceil) -floor = get_xp(np)(_aliases.floor) -trunc = get_xp(np)(_aliases.trunc) matmul = get_xp(np)(_aliases.matmul) tensordot = get_xp(np)(_aliases.tensordot) sign = get_xp(np)(_aliases.sign) @@ -146,7 +142,7 @@ def arange( # asarray also adds the copy keyword, which is not present in numpy 1.0. def asarray( - obj: complex | NestedSequence[complex] | Array | SupportsBufferProtocol, + obj: Array | complex | NestedSequence[complex] | SupportsBufferProtocol, /, *, dtype: DType | None = None, @@ -355,7 +351,6 @@ def count_nonzero( __all__ = [ - "__array_namespace_info__", "count_nonzero", "bool", "int8", "int16", "int32", "int64", @@ -369,8 +364,6 @@ def count_nonzero( "bitwise_left_shift", "bitwise_right_shift", "bitwise_invert", ] # fmt: skip __all__ += _aliases.__all__ -_all_ignore = ["array_namespace", "get_xp", "da", "np"] - def __dir__() -> list[str]: return __all__ diff --git a/sklearn/externals/array_api_compat/dask/array/_info.py b/sklearn/externals/array_api_compat/dask/array/_info.py index 9e4d736f99657..2f39fc4b17ef7 100644 --- a/sklearn/externals/array_api_compat/dask/array/_info.py +++ b/sklearn/externals/array_api_compat/dask/array/_info.py @@ -12,9 +12,9 @@ from __future__ import annotations -from typing import Literal as L -from typing import TypeAlias, overload +from typing import Literal, TypeAlias, overload +import dask.array as da from numpy import bool_ as bool from numpy import ( complex64, @@ -33,7 +33,7 @@ uint64, ) -from ...common._helpers import _DASK_DEVICE, _dask_device +from ...common._helpers import _DASK_DEVICE, _check_device, _dask_device from ...common._typing import ( Capabilities, DefaultDTypes, @@ -49,8 +49,7 @@ DTypesSigned, DTypesUnsigned, ) - -_Device: TypeAlias = L["cpu"] | _dask_device +Device: TypeAlias = Literal["cpu"] | _dask_device class __array_namespace_info__: @@ -142,7 +141,7 @@ def capabilities(self) -> Capabilities: "max dimensions": 64, } - def default_device(self) -> L["cpu"]: + def default_device(self) -> Device: """ The default device used for new Dask arrays. @@ -169,7 +168,7 @@ def default_device(self) -> L["cpu"]: """ return "cpu" - def default_dtypes(self, /, *, device: _Device | None = None) -> DefaultDTypes: + def default_dtypes(self, /, *, device: Device | None = None) -> DefaultDTypes: """ The default data types used for new Dask arrays. @@ -208,11 +207,7 @@ def default_dtypes(self, /, *, device: _Device | None = None) -> DefaultDTypes: 'indexing': dask.int64} """ - if device not in ["cpu", _DASK_DEVICE, None]: - raise ValueError( - f'Device not understood. Only "cpu" or _DASK_DEVICE is allowed, ' - f"but received: {device!r}" - ) + _check_device(da, device) return { "real floating": dtype(float64), "complex floating": dtype(complex128), @@ -222,38 +217,38 @@ def default_dtypes(self, /, *, device: _Device | None = None) -> DefaultDTypes: @overload def dtypes( - self, /, *, device: _Device | None = None, kind: None = None + self, /, *, device: Device | None = None, kind: None = None ) -> DTypesAll: ... @overload def dtypes( - self, /, *, device: _Device | None = None, kind: L["bool"] + self, /, *, device: Device | None = None, kind: Literal["bool"] ) -> DTypesBool: ... @overload def dtypes( - self, /, *, device: _Device | None = None, kind: L["signed integer"] + self, /, *, device: Device | None = None, kind: Literal["signed integer"] ) -> DTypesSigned: ... @overload def dtypes( - self, /, *, device: _Device | None = None, kind: L["unsigned integer"] + self, /, *, device: Device | None = None, kind: Literal["unsigned integer"] ) -> DTypesUnsigned: ... @overload def dtypes( - self, /, *, device: _Device | None = None, kind: L["integral"] + self, /, *, device: Device | None = None, kind: Literal["integral"] ) -> DTypesIntegral: ... @overload def dtypes( - self, /, *, device: _Device | None = None, kind: L["real floating"] + self, /, *, device: Device | None = None, kind: Literal["real floating"] ) -> DTypesReal: ... @overload def dtypes( - self, /, *, device: _Device | None = None, kind: L["complex floating"] + self, /, *, device: Device | None = None, kind: Literal["complex floating"] ) -> DTypesComplex: ... @overload def dtypes( - self, /, *, device: _Device | None = None, kind: L["numeric"] + self, /, *, device: Device | None = None, kind: Literal["numeric"] ) -> DTypesNumeric: ... def dtypes( - self, /, *, device: _Device | None = None, kind: DTypeKind | None = None + self, /, *, device: Device | None = None, kind: DTypeKind | None = None ) -> DTypesAny: """ The array API data types supported by Dask. @@ -308,11 +303,7 @@ def dtypes( 'int64': dask.int64} """ - if device not in ["cpu", _DASK_DEVICE, None]: - raise ValueError( - 'Device not understood. Only "cpu" or _DASK_DEVICE is allowed, but received:' - f" {device}" - ) + _check_device(da, device) if kind is None: return { "bool": dtype(bool), @@ -381,14 +372,14 @@ def dtypes( "complex64": dtype(complex64), "complex128": dtype(complex128), } - if isinstance(kind, tuple): # type: ignore[reportUnnecessaryIsinstanceCall] + if isinstance(kind, tuple): res: dict[str, DType] = {} for k in kind: res.update(self.dtypes(kind=k)) return res raise ValueError(f"unsupported kind: {kind!r}") - def devices(self) -> list[_Device]: + def devices(self) -> list[Device]: """ The devices supported by Dask. diff --git a/sklearn/externals/array_api_compat/dask/array/fft.py b/sklearn/externals/array_api_compat/dask/array/fft.py index 3f40dffe7abd5..44b68e733984f 100644 --- a/sklearn/externals/array_api_compat/dask/array/fft.py +++ b/sklearn/externals/array_api_compat/dask/array/fft.py @@ -1,13 +1,6 @@ -from dask.array.fft import * # noqa: F403 -# dask.array.fft doesn't have __all__. If it is added, replace this with -# -# from dask.array.fft import __all__ as linalg_all -_n = {} -exec('from dask.array.fft import *', _n) -for k in ("__builtins__", "Sequence", "annotations", "warnings"): - _n.pop(k, None) -fft_all = list(_n) -del _n, k +from ..._internal import clone_module + +__all__ = clone_module("dask.array.fft", globals()) from ...common import _fft from ..._internal import get_xp @@ -17,5 +10,7 @@ fftfreq = get_xp(da)(_fft.fftfreq) rfftfreq = get_xp(da)(_fft.rfftfreq) -__all__ = fft_all + ["fftfreq", "rfftfreq"] -_all_ignore = ["da", "fft_all", "get_xp", "warnings"] +__all__ += ["fftfreq", "rfftfreq"] + +def __dir__() -> list[str]: + return __all__ diff --git a/sklearn/externals/array_api_compat/dask/array/linalg.py b/sklearn/externals/array_api_compat/dask/array/linalg.py index 0825386ed5dc3..6b3c10117b10b 100644 --- a/sklearn/externals/array_api_compat/dask/array/linalg.py +++ b/sklearn/externals/array_api_compat/dask/array/linalg.py @@ -8,22 +8,13 @@ from dask.array import matmul, outer, tensordot # Exports -from dask.array.linalg import * # noqa: F403 - -from ..._internal import get_xp +from ..._internal import clone_module, get_xp from ...common import _linalg -from ...common._typing import Array as _Array -from ._aliases import matrix_transpose, vecdot +from ...common._typing import Array -# dask.array.linalg doesn't have __all__. If it is added, replace this with -# -# from dask.array.linalg import __all__ as linalg_all -_n = {} -exec('from dask.array.linalg import *', _n) -for k in ('__builtins__', 'annotations', 'operator', 'warnings', 'Array'): - _n.pop(k, None) -linalg_all = list(_n) -del _n, k +__all__ = clone_module("dask.array.linalg", globals()) + +from ._aliases import matrix_transpose, vecdot EighResult = _linalg.EighResult QRResult = _linalg.QRResult @@ -33,8 +24,8 @@ # supports the mode keyword on QR # https://github.com/dask/dask/issues/10388 #qr = get_xp(da)(_linalg.qr) -def qr( - x: _Array, +def qr( # type: ignore[no-redef] + x: Array, mode: Literal["reduced", "complete"] = "reduced", **kwargs: object, ) -> QRResult: @@ -50,12 +41,12 @@ def qr( # Wrap the svd functions to not pass full_matrices to dask # when full_matrices=False (as that is the default behavior for dask), # and dask doesn't have the full_matrices keyword -def svd(x: _Array, full_matrices: bool = True, **kwargs) -> SVDResult: +def svd(x: Array, full_matrices: bool = True, **kwargs: object) -> SVDResult: # type: ignore[no-redef] if full_matrices: raise ValueError("full_matrics=True is not supported by dask.") return da.linalg.svd(x, coerce_signs=False, **kwargs) -def svdvals(x: _Array) -> _Array: +def svdvals(x: Array) -> Array: # TODO: can't avoid computing U or V for dask _, s, _ = svd(x) return s @@ -63,10 +54,11 @@ def svdvals(x: _Array) -> _Array: vector_norm = get_xp(da)(_linalg.vector_norm) diagonal = get_xp(da)(_linalg.diagonal) -__all__ = linalg_all + ["trace", "outer", "matmul", "tensordot", - "matrix_transpose", "vecdot", "EighResult", - "QRResult", "SlogdetResult", "SVDResult", "qr", - "cholesky", "matrix_rank", "matrix_norm", "svdvals", - "vector_norm", "diagonal"] +__all__ += ["trace", "outer", "matmul", "tensordot", + "matrix_transpose", "vecdot", "EighResult", + "QRResult", "SlogdetResult", "SVDResult", "qr", + "cholesky", "matrix_rank", "matrix_norm", "svdvals", + "vector_norm", "diagonal"] -_all_ignore = ['get_xp', 'da', 'linalg_all', 'warnings'] +def __dir__() -> list[str]: + return __all__ diff --git a/sklearn/externals/array_api_compat/numpy/__init__.py b/sklearn/externals/array_api_compat/numpy/__init__.py index 3e138f53db006..23379e44db6e7 100644 --- a/sklearn/externals/array_api_compat/numpy/__init__.py +++ b/sklearn/externals/array_api_compat/numpy/__init__.py @@ -1,16 +1,17 @@ # ruff: noqa: PLC0414 from typing import Final -from numpy import * # noqa: F403 # pyright: ignore[reportWildcardImportFromLibrary] +from .._internal import clone_module -# from numpy import * doesn't overwrite these builtin names -from numpy import abs as abs -from numpy import max as max -from numpy import min as min -from numpy import round as round +# This needs to be loaded explicitly before cloning +import numpy.typing # noqa: F401 + +__all__ = clone_module("numpy", globals()) # These imports may overwrite names from the import * above. -from ._aliases import * # noqa: F403 +from . import _aliases +from ._aliases import * # type: ignore[assignment,no-redef] # noqa: F403 +from ._info import __array_namespace_info__ # noqa: F401 # Don't know why, but we have to do an absolute import to import linalg. If we # instead do @@ -26,3 +27,12 @@ from .linalg import matrix_transpose, vecdot # type: ignore[no-redef] # noqa: F401 __array_api_version__: Final = "2024.12" + +__all__ = sorted( + set(__all__) + | set(_aliases.__all__) + | {"__array_api_version__", "__array_namespace_info__", "linalg", "fft"} +) + +def __dir__() -> list[str]: + return __all__ diff --git a/sklearn/externals/array_api_compat/numpy/_aliases.py b/sklearn/externals/array_api_compat/numpy/_aliases.py index a1aee5c0df796..87b3c2f398af0 100644 --- a/sklearn/externals/array_api_compat/numpy/_aliases.py +++ b/sklearn/externals/array_api_compat/numpy/_aliases.py @@ -2,23 +2,15 @@ from __future__ import annotations from builtins import bool as py_bool -from typing import TYPE_CHECKING, Any, Literal, TypeAlias, cast +from typing import Any, cast import numpy as np from .._internal import get_xp from ..common import _aliases, _helpers from ..common._typing import NestedSequence, SupportsBufferProtocol -from ._info import __array_namespace_info__ from ._typing import Array, Device, DType -if TYPE_CHECKING: - from typing_extensions import Buffer, TypeIs - -# The values of the `_CopyMode` enum can be either `False`, `True`, or `2`: -# https://github.com/numpy/numpy/blob/5a8a6a79d9c2fff8f07dcab5d41e14f8508d673f/numpy/_globals.pyi#L7-L10 -_Copy: TypeAlias = py_bool | Literal[2] | np._CopyMode - bool = np.bool_ # Basic renames @@ -63,9 +55,6 @@ argsort = get_xp(np)(_aliases.argsort) sort = get_xp(np)(_aliases.sort) nonzero = get_xp(np)(_aliases.nonzero) -ceil = get_xp(np)(_aliases.ceil) -floor = get_xp(np)(_aliases.floor) -trunc = get_xp(np)(_aliases.trunc) matmul = get_xp(np)(_aliases.matmul) matrix_transpose = get_xp(np)(_aliases.matrix_transpose) tensordot = get_xp(np)(_aliases.tensordot) @@ -74,14 +63,6 @@ iinfo = get_xp(np)(_aliases.iinfo) -def _supports_buffer_protocol(obj: object) -> TypeIs[Buffer]: # pyright: ignore[reportUnusedFunction] - try: - memoryview(obj) # pyright: ignore[reportArgumentType] - except TypeError: - return False - return True - - # asarray also adds the copy keyword, which is not present in numpy 1.0. # asarray() is different enough between numpy, cupy, and dask, the logic # complicated enough that it's easier to define it separately for each module @@ -92,7 +73,7 @@ def asarray( *, dtype: DType | None = None, device: Device | None = None, - copy: _Copy | None = None, + copy: py_bool | None = None, **kwargs: Any, ) -> Array: """ @@ -103,14 +84,14 @@ def asarray( """ _helpers._check_device(np, device) + # None is unsupported in NumPy 1.0, but we can use an internal enum + # False in NumPy 1.0 means None in NumPy 2.0 and in the Array API if copy is None: - copy = np._CopyMode.IF_NEEDED + copy = np._CopyMode.IF_NEEDED # type: ignore[assignment,attr-defined] elif copy is False: - copy = np._CopyMode.NEVER - elif copy is True: - copy = np._CopyMode.ALWAYS + copy = np._CopyMode.NEVER # type: ignore[assignment,attr-defined] - return np.array(obj, copy=copy, dtype=dtype, **kwargs) # pyright: ignore + return np.array(obj, copy=copy, dtype=dtype, **kwargs) def astype( @@ -141,16 +122,36 @@ def count_nonzero( # take_along_axis: axis defaults to -1 but in numpy axis is a required arg -def take_along_axis(x: Array, indices: Array, /, *, axis: int = -1): +def take_along_axis(x: Array, indices: Array, /, *, axis: int = -1) -> Array: return np.take_along_axis(x, indices, axis=axis) +# ceil, floor, and trunc return integers for integer inputs in NumPy < 2 + +def ceil(x: Array, /) -> Array: + if np.__version__ < '2' and np.issubdtype(x.dtype, np.integer): + return x.copy() + return np.ceil(x) + + +def floor(x: Array, /) -> Array: + if np.__version__ < '2' and np.issubdtype(x.dtype, np.integer): + return x.copy() + return np.floor(x) + + +def trunc(x: Array, /) -> Array: + if np.__version__ < '2' and np.issubdtype(x.dtype, np.integer): + return x.copy() + return np.trunc(x) + + # These functions are completely new here. If the library already has them # (i.e., numpy 2.0), use the library version instead of our wrapper. if hasattr(np, "vecdot"): vecdot = np.vecdot else: - vecdot = get_xp(np)(_aliases.vecdot) + vecdot = get_xp(np)(_aliases.vecdot) # type: ignore[assignment] if hasattr(np, "isdtype"): isdtype = np.isdtype @@ -162,8 +163,7 @@ def take_along_axis(x: Array, indices: Array, /, *, axis: int = -1): else: unstack = get_xp(np)(_aliases.unstack) -__all__ = [ - "__array_namespace_info__", +__all__ = _aliases.__all__ + [ "asarray", "astype", "acos", @@ -173,6 +173,9 @@ def take_along_axis(x: Array, indices: Array, /, *, axis: int = -1): "atan", "atan2", "atanh", + "ceil", + "floor", + "trunc", "bitwise_left_shift", "bitwise_invert", "bitwise_right_shift", @@ -182,8 +185,6 @@ def take_along_axis(x: Array, indices: Array, /, *, axis: int = -1): "pow", "take_along_axis" ] -__all__ += _aliases.__all__ -_all_ignore = ["np", "get_xp"] def __dir__() -> list[str]: diff --git a/sklearn/externals/array_api_compat/numpy/_info.py b/sklearn/externals/array_api_compat/numpy/_info.py index f307f62c5d5d5..c625c13e36942 100644 --- a/sklearn/externals/array_api_compat/numpy/_info.py +++ b/sklearn/externals/array_api_compat/numpy/_info.py @@ -27,6 +27,7 @@ uint64, ) +from ..common._typing import DefaultDTypes from ._typing import Device, DType @@ -139,7 +140,7 @@ def default_dtypes( self, *, device: Device | None = None, - ) -> dict[str, dtype[intp | float64 | complex128]]: + ) -> DefaultDTypes: """ The default data types used for new NumPy arrays. diff --git a/sklearn/externals/array_api_compat/numpy/_typing.py b/sklearn/externals/array_api_compat/numpy/_typing.py index e771c788bbcab..b5fa188c52b69 100644 --- a/sklearn/externals/array_api_compat/numpy/_typing.py +++ b/sklearn/externals/array_api_compat/numpy/_typing.py @@ -23,7 +23,6 @@ Array: TypeAlias = np.ndarray __all__ = ["Array", "DType", "Device"] -_all_ignore = ["np"] def __dir__() -> list[str]: diff --git a/sklearn/externals/array_api_compat/numpy/fft.py b/sklearn/externals/array_api_compat/numpy/fft.py index 06875f00b4312..a492feb8cf690 100644 --- a/sklearn/externals/array_api_compat/numpy/fft.py +++ b/sklearn/externals/array_api_compat/numpy/fft.py @@ -1,6 +1,8 @@ import numpy as np -from numpy.fft import __all__ as fft_all -from numpy.fft import fft2, ifft2, irfft2, rfft2 + +from .._internal import clone_module + +__all__ = clone_module("numpy.fft", globals()) from .._internal import get_xp from ..common import _fft @@ -21,15 +23,8 @@ ifftshift = get_xp(np)(_fft.ifftshift) -__all__ = ["rfft2", "irfft2", "fft2", "ifft2"] -__all__ += _fft.__all__ - +__all__ = sorted(set(__all__) | set(_fft.__all__)) def __dir__() -> list[str]: return __all__ - -del get_xp -del np -del fft_all -del _fft diff --git a/sklearn/externals/array_api_compat/numpy/linalg.py b/sklearn/externals/array_api_compat/numpy/linalg.py index 2d3e731da3fc0..7168441c7517e 100644 --- a/sklearn/externals/array_api_compat/numpy/linalg.py +++ b/sklearn/externals/array_api_compat/numpy/linalg.py @@ -7,26 +7,11 @@ import numpy as np -# intersection of `np.linalg.__all__` on numpy 1.22 and 2.2, minus `_linalg.__all__` -from numpy.linalg import ( - LinAlgError, - cond, - det, - eig, - eigvals, - eigvalsh, - inv, - lstsq, - matrix_power, - multi_dot, - norm, - tensorinv, - tensorsolve, -) - -from .._internal import get_xp +from .._internal import clone_module, get_xp from ..common import _linalg +__all__ = clone_module("numpy.linalg", globals()) + # These functions are in both the main and linalg namespaces from ._aliases import matmul, matrix_transpose, tensordot, vecdot # noqa: F401 from ._typing import Array @@ -65,7 +50,7 @@ # https://github.com/cupy/cupy/blob/main/cupy/cublas.py#L43). def solve(x1: Array, x2: Array, /) -> Array: try: - from numpy.linalg._linalg import ( + from numpy.linalg._linalg import ( # type: ignore[attr-defined] _assert_stacked_2d, _assert_stacked_square, _commonType, @@ -74,7 +59,7 @@ def solve(x1: Array, x2: Array, /) -> Array: isComplexType, ) except ImportError: - from numpy.linalg.linalg import ( + from numpy.linalg.linalg import ( # type: ignore[attr-defined] _assert_stacked_2d, _assert_stacked_square, _commonType, @@ -120,7 +105,7 @@ def solve(x1: Array, x2: Array, /) -> Array: vector_norm = get_xp(np)(_linalg.vector_norm) -__all__ = [ +_all = [ "LinAlgError", "cond", "det", @@ -132,12 +117,12 @@ def solve(x1: Array, x2: Array, /) -> Array: "matrix_power", "multi_dot", "norm", + "solve", "tensorinv", "tensorsolve", + "vector_norm", ] -__all__ += _linalg.__all__ -__all__ += ["solve", "vector_norm"] - +__all__ = sorted(set(__all__) | set(_linalg.__all__) | set(_all)) def __dir__() -> list[str]: return __all__ diff --git a/sklearn/externals/array_api_compat/torch/__init__.py b/sklearn/externals/array_api_compat/torch/__init__.py index 69fd19ce83a56..6cbb6ec264869 100644 --- a/sklearn/externals/array_api_compat/torch/__init__.py +++ b/sklearn/externals/array_api_compat/torch/__init__.py @@ -1,22 +1,25 @@ -from torch import * # noqa: F403 +from typing import Final -# Several names are not included in the above import * -import torch -for n in dir(torch): - if (n.startswith('_') - or n.endswith('_') - or 'cuda' in n - or 'cpu' in n - or 'backward' in n): - continue - exec(f"{n} = torch.{n}") -del n +from .._internal import clone_module + +__all__ = clone_module("torch", globals()) # These imports may overwrite names from the import * above. +from . import _aliases from ._aliases import * # noqa: F403 +from ._info import __array_namespace_info__ # noqa: F401 # See the comment in the numpy __init__.py __import__(__package__ + '.linalg') __import__(__package__ + '.fft') -__array_api_version__ = '2024.12' +__array_api_version__: Final = '2024.12' + +__all__ = sorted( + set(__all__) + | set(_aliases.__all__) + | {"__array_api_version__", "__array_namespace_info__", "linalg", "fft"} +) + +def __dir__() -> list[str]: + return __all__ diff --git a/sklearn/externals/array_api_compat/torch/_aliases.py b/sklearn/externals/array_api_compat/torch/_aliases.py index de5d1a5d40eb5..4e8533f95e839 100644 --- a/sklearn/externals/array_api_compat/torch/_aliases.py +++ b/sklearn/externals/array_api_compat/torch/_aliases.py @@ -1,15 +1,15 @@ from __future__ import annotations +from collections.abc import Sequence from functools import reduce as _reduce, wraps as _wraps from builtins import all as _builtin_all, any as _builtin_any -from typing import Any, List, Optional, Sequence, Tuple, Union, Literal +from typing import Any, Literal import torch from .._internal import get_xp from ..common import _aliases from ..common._typing import NestedSequence, SupportsBufferProtocol -from ._info import __array_namespace_info__ from ._typing import Array, Device, DType _int_dtypes = { @@ -96,9 +96,7 @@ def _fix_promotion(x1, x2, only_scalar=True): _py_scalars = (bool, int, float, complex) -def result_type( - *arrays_and_dtypes: Array | DType | bool | int | float | complex -) -> DType: +def result_type(*arrays_and_dtypes: Array | DType | complex) -> DType: num = len(arrays_and_dtypes) if num == 0: @@ -129,10 +127,7 @@ def result_type( return _reduce(_result_type, others + scalars) -def _result_type( - x: Array | DType | bool | int | float | complex, - y: Array | DType | bool | int | float | complex, -) -> DType: +def _result_type(x: Array | DType | complex, y: Array | DType | complex) -> DType: if not (isinstance(x, _py_scalars) or isinstance(y, _py_scalars)): xdt = x if isinstance(x, torch.dtype) else x.dtype ydt = y if isinstance(y, torch.dtype) else y.dtype @@ -150,7 +145,7 @@ def _result_type( return torch.result_type(x, y) -def can_cast(from_: Union[DType, Array], to: DType, /) -> bool: +def can_cast(from_: DType | Array, to: DType, /) -> bool: if not isinstance(from_, torch.dtype): from_ = from_.dtype return torch.can_cast(from_, to) @@ -194,12 +189,7 @@ def can_cast(from_: Union[DType, Array], to: DType, /) -> bool: def asarray( - obj: ( - Array - | bool | int | float | complex - | NestedSequence[bool | int | float | complex] - | SupportsBufferProtocol - ), + obj: Array | complex | NestedSequence[complex] | SupportsBufferProtocol, /, *, dtype: DType | None = None, @@ -218,13 +208,13 @@ def asarray( # of 'axis'. # torch.min and torch.max return a tuple and don't support multiple axes https://github.com/pytorch/pytorch/issues/58745 -def max(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: +def max(x: Array, /, *, axis: int | tuple[int, ...] | None = None, keepdims: bool = False) -> Array: # https://github.com/pytorch/pytorch/issues/29137 if axis == (): return torch.clone(x) return torch.amax(x, axis, keepdims=keepdims) -def min(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keepdims: bool = False) -> Array: +def min(x: Array, /, *, axis: int | tuple[int, ...] |None = None, keepdims: bool = False) -> Array: # https://github.com/pytorch/pytorch/issues/29137 if axis == (): return torch.clone(x) @@ -240,9 +230,31 @@ def min(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, keep # torch.sort also returns a tuple # https://github.com/pytorch/pytorch/issues/70921 -def sort(x: Array, /, *, axis: int = -1, descending: bool = False, stable: bool = True, **kwargs) -> Array: +def sort( + x: Array, + /, + *, + axis: int = -1, + descending: bool = False, + stable: bool = True, + **kwargs: object, +) -> Array: return torch.sort(x, dim=axis, descending=descending, stable=stable, **kwargs).values + +# Wrap torch.argsort to set stable=True by default +def argsort( + x: Array, + /, + *, + axis: int = -1, + descending: bool = False, + stable: bool = True, + **kwargs: object, +) -> Array: + return torch.argsort(x, dim=axis, descending=descending, stable=stable, **kwargs) + + def _normalize_axes(axis, ndim): axes = [] if ndim == 0 and axis: @@ -307,10 +319,10 @@ def _sum_prod_no_axis(x: Array, dtype: DType | None) -> Array: def prod(x: Array, /, *, - axis: Optional[Union[int, Tuple[int, ...]]] = None, - dtype: Optional[DType] = None, + axis: int | tuple[int, ...] | None = None, + dtype: DType | None = None, keepdims: bool = False, - **kwargs) -> Array: + **kwargs: object) -> Array: if axis == (): return _sum_prod_no_axis(x, dtype) @@ -331,10 +343,10 @@ def prod(x: Array, def sum(x: Array, /, *, - axis: Optional[Union[int, Tuple[int, ...]]] = None, - dtype: Optional[DType] = None, + axis: int | tuple[int, ...] | None = None, + dtype: DType | None = None, keepdims: bool = False, - **kwargs) -> Array: + **kwargs: object) -> Array: if axis == (): return _sum_prod_no_axis(x, dtype) @@ -350,9 +362,9 @@ def sum(x: Array, def any(x: Array, /, *, - axis: Optional[Union[int, Tuple[int, ...]]] = None, + axis: int | tuple[int, ...] | None = None, keepdims: bool = False, - **kwargs) -> Array: + **kwargs: object) -> Array: if axis == (): return x.to(torch.bool) @@ -374,9 +386,9 @@ def any(x: Array, def all(x: Array, /, *, - axis: Optional[Union[int, Tuple[int, ...]]] = None, + axis: int | tuple[int, ...] | None = None, keepdims: bool = False, - **kwargs) -> Array: + **kwargs: object) -> Array: if axis == (): return x.to(torch.bool) @@ -398,9 +410,9 @@ def all(x: Array, def mean(x: Array, /, *, - axis: Optional[Union[int, Tuple[int, ...]]] = None, + axis: int | tuple[int, ...] | None = None, keepdims: bool = False, - **kwargs) -> Array: + **kwargs: object) -> Array: # https://github.com/pytorch/pytorch/issues/29137 if axis == (): return torch.clone(x) @@ -415,10 +427,10 @@ def mean(x: Array, def std(x: Array, /, *, - axis: Optional[Union[int, Tuple[int, ...]]] = None, - correction: Union[int, float] = 0.0, + axis: int | tuple[int, ...] | None = None, + correction: float = 0.0, keepdims: bool = False, - **kwargs) -> Array: + **kwargs: object) -> Array: # Note, float correction is not supported # https://github.com/pytorch/pytorch/issues/61492. We don't try to # implement it here for now. @@ -446,10 +458,10 @@ def std(x: Array, def var(x: Array, /, *, - axis: Optional[Union[int, Tuple[int, ...]]] = None, - correction: Union[int, float] = 0.0, + axis: int | tuple[int, ...] | None = None, + correction: float = 0.0, keepdims: bool = False, - **kwargs) -> Array: + **kwargs: object) -> Array: # Note, float correction is not supported # https://github.com/pytorch/pytorch/issues/61492. We don't try to # implement it here for now. @@ -472,11 +484,11 @@ def var(x: Array, # torch.concat doesn't support dim=None # https://github.com/pytorch/pytorch/issues/70925 -def concat(arrays: Union[Tuple[Array, ...], List[Array]], +def concat(arrays: tuple[Array, ...] | list[Array], /, *, - axis: Optional[int] = 0, - **kwargs) -> Array: + axis: int | None = 0, + **kwargs: object) -> Array: if axis is None: arrays = tuple(ar.flatten() for ar in arrays) axis = 0 @@ -485,7 +497,7 @@ def concat(arrays: Union[Tuple[Array, ...], List[Array]], # torch.squeeze only accepts int dim and doesn't require it # https://github.com/pytorch/pytorch/issues/70924. Support for tuple dim was # added at https://github.com/pytorch/pytorch/pull/89017. -def squeeze(x: Array, /, axis: Union[int, Tuple[int, ...]]) -> Array: +def squeeze(x: Array, /, axis: int | tuple[int, ...]) -> Array: if isinstance(axis, int): axis = (axis,) for a in axis: @@ -499,27 +511,27 @@ def squeeze(x: Array, /, axis: Union[int, Tuple[int, ...]]) -> Array: return x # torch.broadcast_to uses size instead of shape -def broadcast_to(x: Array, /, shape: Tuple[int, ...], **kwargs) -> Array: +def broadcast_to(x: Array, /, shape: tuple[int, ...], **kwargs: object) -> Array: return torch.broadcast_to(x, shape, **kwargs) # torch.permute uses dims instead of axes -def permute_dims(x: Array, /, axes: Tuple[int, ...]) -> Array: +def permute_dims(x: Array, /, axes: tuple[int, ...]) -> Array: return torch.permute(x, axes) # The axis parameter doesn't work for flip() and roll() # https://github.com/pytorch/pytorch/issues/71210. Also torch.flip() doesn't # accept axis=None -def flip(x: Array, /, *, axis: Optional[Union[int, Tuple[int, ...]]] = None, **kwargs) -> Array: +def flip(x: Array, /, *, axis: int | tuple[int, ...] | None = None, **kwargs: object) -> Array: if axis is None: axis = tuple(range(x.ndim)) # torch.flip doesn't accept dim as an int but the method does # https://github.com/pytorch/pytorch/issues/18095 return x.flip(axis, **kwargs) -def roll(x: Array, /, shift: Union[int, Tuple[int, ...]], *, axis: Optional[Union[int, Tuple[int, ...]]] = None, **kwargs) -> Array: +def roll(x: Array, /, shift: int | tuple[int, ...], *, axis: int | tuple[int, ...] | None = None, **kwargs: object) -> Array: return torch.roll(x, shift, axis, **kwargs) -def nonzero(x: Array, /, **kwargs) -> Tuple[Array, ...]: +def nonzero(x: Array, /, **kwargs: object) -> tuple[Array, ...]: if x.ndim == 0: raise ValueError("nonzero() does not support zero-dimensional arrays") return torch.nonzero(x, as_tuple=True, **kwargs) @@ -532,8 +544,8 @@ def diff( *, axis: int = -1, n: int = 1, - prepend: Optional[Array] = None, - append: Optional[Array] = None, + prepend: Array | None = None, + append: Array | None = None, ) -> Array: return torch.diff(x, dim=axis, n=n, prepend=prepend, append=append) @@ -543,7 +555,7 @@ def count_nonzero( x: Array, /, *, - axis: Optional[Union[int, Tuple[int, ...]]] = None, + axis: int | tuple[int, ...] | None = None, keepdims: bool = False, ) -> Array: result = torch.count_nonzero(x, dim=axis) @@ -564,12 +576,7 @@ def repeat(x: Array, repeats: int | Array, /, *, axis: int | None = None) -> Arr return torch.repeat_interleave(x, repeats, axis) -def where( - condition: Array, - x1: Array | bool | int | float | complex, - x2: Array | bool | int | float | complex, - /, -) -> Array: +def where(condition: Array, x1: Array | complex, x2: Array | complex, /) -> Array: x1, x2 = _fix_promotion(x1, x2) return torch.where(condition, x1, x2) @@ -577,10 +584,10 @@ def where( # torch.reshape doesn't have the copy keyword def reshape(x: Array, /, - shape: Tuple[int, ...], + shape: tuple[int, ...], *, - copy: Optional[bool] = None, - **kwargs) -> Array: + copy: bool | None = None, + **kwargs: object) -> Array: if copy is not None: raise NotImplementedError("torch.reshape doesn't yet support the copy keyword") return torch.reshape(x, shape, **kwargs) @@ -589,14 +596,14 @@ def reshape(x: Array, # (https://github.com/pytorch/pytorch/issues/70915), and doesn't support some # keyword argument combinations # (https://github.com/pytorch/pytorch/issues/70914) -def arange(start: Union[int, float], +def arange(start: float, /, - stop: Optional[Union[int, float]] = None, - step: Union[int, float] = 1, + stop: float | None = None, + step: float = 1, *, - dtype: Optional[DType] = None, - device: Optional[Device] = None, - **kwargs) -> Array: + dtype: DType | None = None, + device: Device | None = None, + **kwargs: object) -> Array: if stop is None: start, stop = 0, start if step > 0 and stop <= start or step < 0 and stop >= start: @@ -611,13 +618,13 @@ def arange(start: Union[int, float], # torch.eye does not accept None as a default for the second argument and # doesn't support off-diagonals (https://github.com/pytorch/pytorch/issues/70910) def eye(n_rows: int, - n_cols: Optional[int] = None, + n_cols: int | None = None, /, *, k: int = 0, - dtype: Optional[DType] = None, - device: Optional[Device] = None, - **kwargs) -> Array: + dtype: DType | None = None, + device: Device | None = None, + **kwargs: object) -> Array: if n_cols is None: n_cols = n_rows z = torch.zeros(n_rows, n_cols, dtype=dtype, device=device, **kwargs) @@ -626,52 +633,52 @@ def eye(n_rows: int, return z # torch.linspace doesn't have the endpoint parameter -def linspace(start: Union[int, float], - stop: Union[int, float], +def linspace(start: float, + stop: float, /, num: int, *, - dtype: Optional[DType] = None, - device: Optional[Device] = None, + dtype: DType | None = None, + device: Device | None = None, endpoint: bool = True, - **kwargs) -> Array: + **kwargs: object) -> Array: if not endpoint: return torch.linspace(start, stop, num+1, dtype=dtype, device=device, **kwargs)[:-1] return torch.linspace(start, stop, num, dtype=dtype, device=device, **kwargs) # torch.full does not accept an int size # https://github.com/pytorch/pytorch/issues/70906 -def full(shape: Union[int, Tuple[int, ...]], - fill_value: bool | int | float | complex, +def full(shape: int | tuple[int, ...], + fill_value: complex, *, - dtype: Optional[DType] = None, - device: Optional[Device] = None, - **kwargs) -> Array: + dtype: DType | None = None, + device: Device | None = None, + **kwargs: object) -> Array: if isinstance(shape, int): shape = (shape,) return torch.full(shape, fill_value, dtype=dtype, device=device, **kwargs) # ones, zeros, and empty do not accept shape as a keyword argument -def ones(shape: Union[int, Tuple[int, ...]], +def ones(shape: int | tuple[int, ...], *, - dtype: Optional[DType] = None, - device: Optional[Device] = None, - **kwargs) -> Array: + dtype: DType | None = None, + device: Device | None = None, + **kwargs: object) -> Array: return torch.ones(shape, dtype=dtype, device=device, **kwargs) -def zeros(shape: Union[int, Tuple[int, ...]], +def zeros(shape: int | tuple[int, ...], *, - dtype: Optional[DType] = None, - device: Optional[Device] = None, - **kwargs) -> Array: + dtype: DType | None = None, + device: Device | None = None, + **kwargs: object) -> Array: return torch.zeros(shape, dtype=dtype, device=device, **kwargs) -def empty(shape: Union[int, Tuple[int, ...]], +def empty(shape: int | tuple[int, ...], *, - dtype: Optional[DType] = None, - device: Optional[Device] = None, - **kwargs) -> Array: + dtype: DType | None = None, + device: Device | None = None, + **kwargs: object) -> Array: return torch.empty(shape, dtype=dtype, device=device, **kwargs) # tril and triu do not call the keyword argument k @@ -693,14 +700,14 @@ def astype( /, *, copy: bool = True, - device: Optional[Device] = None, + device: Device | None = None, ) -> Array: if device is not None: return x.to(device, dtype=dtype, copy=copy) return x.to(dtype=dtype, copy=copy) -def broadcast_arrays(*arrays: Array) -> List[Array]: +def broadcast_arrays(*arrays: Array) -> list[Array]: shape = torch.broadcast_shapes(*[a.shape for a in arrays]) return [torch.broadcast_to(a, shape) for a in arrays] @@ -738,7 +745,7 @@ def unique_inverse(x: Array) -> UniqueInverseResult: def unique_values(x: Array) -> Array: return torch.unique(x) -def matmul(x1: Array, x2: Array, /, **kwargs) -> Array: +def matmul(x1: Array, x2: Array, /, **kwargs: object) -> Array: # torch.matmul doesn't type promote (but differently from _fix_promotion) x1, x2 = _fix_promotion(x1, x2, only_scalar=False) return torch.matmul(x1, x2, **kwargs) @@ -756,8 +763,8 @@ def tensordot( x2: Array, /, *, - axes: Union[int, Tuple[Sequence[int], Sequence[int]]] = 2, - **kwargs, + axes: int | tuple[Sequence[int], Sequence[int]] = 2, + **kwargs: object, ) -> Array: # Note: torch.tensordot fails with integer dtypes when there is only 1 # element in the axis (https://github.com/pytorch/pytorch/issues/84530). @@ -766,8 +773,10 @@ def tensordot( def isdtype( - dtype: DType, kind: Union[DType, str, Tuple[Union[DType, str], ...]], - *, _tuple=True, # Disallow nested tuples + dtype: DType, + kind: DType | str | tuple[DType | str, ...], + *, + _tuple: bool = True, # Disallow nested tuples ) -> bool: """ Returns a boolean indicating whether a provided dtype is of a specified data type ``kind``. @@ -801,16 +810,29 @@ def isdtype( else: return dtype == kind -def take(x: Array, indices: Array, /, *, axis: Optional[int] = None, **kwargs) -> Array: +def take(x: Array, indices: Array, /, *, axis: int | None = None, **kwargs: object) -> Array: if axis is None: if x.ndim != 1: raise ValueError("axis must be specified when ndim > 1") axis = 0 - return torch.index_select(x, axis, indices, **kwargs) + # torch does not support negative indices, + # see https://github.com/pytorch/pytorch/issues/146211 + return torch.index_select( + x, + axis, + torch.where(indices < 0, indices + x.shape[axis], indices), + **kwargs + ) def take_along_axis(x: Array, indices: Array, /, *, axis: int = -1) -> Array: - return torch.take_along_dim(x, indices, dim=axis) + # torch does not support negative indices, + # see https://github.com/pytorch/pytorch/issues/146211 + return torch.take_along_dim( + x, + torch.where(indices < 0, indices + x.shape[axis], indices), + dim=axis + ) def sign(x: Array, /) -> Array: @@ -828,13 +850,13 @@ def sign(x: Array, /) -> Array: return out -def meshgrid(*arrays: Array, indexing: Literal['xy', 'ij'] = 'xy') -> List[Array]: +def meshgrid(*arrays: Array, indexing: Literal['xy', 'ij'] = 'xy') -> list[Array]: # enforce the default of 'xy' # TODO: is the return type a list or a tuple - return list(torch.meshgrid(*arrays, indexing='xy')) + return list(torch.meshgrid(*arrays, indexing=indexing)) -__all__ = ['__array_namespace_info__', 'asarray', 'result_type', 'can_cast', +__all__ = ['asarray', 'result_type', 'can_cast', 'permute_dims', 'bitwise_invert', 'newaxis', 'conj', 'add', 'atan2', 'bitwise_and', 'bitwise_left_shift', 'bitwise_or', 'bitwise_right_shift', 'bitwise_xor', 'copysign', 'count_nonzero', @@ -842,14 +864,12 @@ def meshgrid(*arrays: Array, indexing: Literal['xy', 'ij'] = 'xy') -> List[Array 'equal', 'floor_divide', 'greater', 'greater_equal', 'hypot', 'less', 'less_equal', 'logaddexp', 'maximum', 'minimum', 'multiply', 'not_equal', 'pow', 'remainder', 'subtract', 'max', - 'min', 'clip', 'unstack', 'cumulative_sum', 'cumulative_prod', 'sort', 'prod', 'sum', - 'any', 'all', 'mean', 'std', 'var', 'concat', 'squeeze', - 'broadcast_to', 'flip', 'roll', 'nonzero', 'where', 'reshape', + 'min', 'clip', 'unstack', 'cumulative_sum', 'cumulative_prod', 'sort', + 'argsort', 'prod', 'sum', 'any', 'all', 'mean', 'std', 'var', 'concat', + 'squeeze', 'broadcast_to', 'flip', 'roll', 'nonzero', 'where', 'reshape', 'arange', 'eye', 'linspace', 'full', 'ones', 'zeros', 'empty', 'tril', 'triu', 'expand_dims', 'astype', 'broadcast_arrays', 'UniqueAllResult', 'UniqueCountsResult', 'UniqueInverseResult', 'unique_all', 'unique_counts', 'unique_inverse', 'unique_values', 'matmul', 'matrix_transpose', 'vecdot', 'tensordot', 'isdtype', 'take', 'take_along_axis', 'sign', 'finfo', 'iinfo', 'repeat', 'meshgrid'] - -_all_ignore = ['torch', 'get_xp'] diff --git a/sklearn/externals/array_api_compat/torch/fft.py b/sklearn/externals/array_api_compat/torch/fft.py index 50e6a0d0a3968..f11b3eb597563 100644 --- a/sklearn/externals/array_api_compat/torch/fft.py +++ b/sklearn/externals/array_api_compat/torch/fft.py @@ -1,12 +1,15 @@ from __future__ import annotations -from typing import Union, Sequence, Literal +from collections.abc import Sequence +from typing import Literal -import torch +import torch # noqa: F401 import torch.fft -from torch.fft import * # noqa: F403 from ._typing import Array +from .._internal import clone_module + +__all__ = clone_module("torch.fft", globals()) # Several torch fft functions do not map axes to dim @@ -17,7 +20,7 @@ def fftn( s: Sequence[int] = None, axes: Sequence[int] = None, norm: Literal["backward", "ortho", "forward"] = "backward", - **kwargs, + **kwargs: object, ) -> Array: return torch.fft.fftn(x, s=s, dim=axes, norm=norm, **kwargs) @@ -28,7 +31,7 @@ def ifftn( s: Sequence[int] = None, axes: Sequence[int] = None, norm: Literal["backward", "ortho", "forward"] = "backward", - **kwargs, + **kwargs: object, ) -> Array: return torch.fft.ifftn(x, s=s, dim=axes, norm=norm, **kwargs) @@ -39,7 +42,7 @@ def rfftn( s: Sequence[int] = None, axes: Sequence[int] = None, norm: Literal["backward", "ortho", "forward"] = "backward", - **kwargs, + **kwargs: object, ) -> Array: return torch.fft.rfftn(x, s=s, dim=axes, norm=norm, **kwargs) @@ -50,7 +53,7 @@ def irfftn( s: Sequence[int] = None, axes: Sequence[int] = None, norm: Literal["backward", "ortho", "forward"] = "backward", - **kwargs, + **kwargs: object, ) -> Array: return torch.fft.irfftn(x, s=s, dim=axes, norm=norm, **kwargs) @@ -58,8 +61,8 @@ def fftshift( x: Array, /, *, - axes: Union[int, Sequence[int]] = None, - **kwargs, + axes: int | Sequence[int] = None, + **kwargs: object, ) -> Array: return torch.fft.fftshift(x, dim=axes, **kwargs) @@ -67,19 +70,13 @@ def ifftshift( x: Array, /, *, - axes: Union[int, Sequence[int]] = None, - **kwargs, + axes: int | Sequence[int] = None, + **kwargs: object, ) -> Array: return torch.fft.ifftshift(x, dim=axes, **kwargs) -__all__ = torch.fft.__all__ + [ - "fftn", - "ifftn", - "rfftn", - "irfftn", - "fftshift", - "ifftshift", -] +__all__ += ["fftn", "ifftn", "rfftn", "irfftn", "fftshift", "ifftshift"] -_all_ignore = ['torch'] +def __dir__() -> list[str]: + return __all__ diff --git a/sklearn/externals/array_api_compat/torch/linalg.py b/sklearn/externals/array_api_compat/torch/linalg.py index 70d7240500ce4..08271d226734b 100644 --- a/sklearn/externals/array_api_compat/torch/linalg.py +++ b/sklearn/externals/array_api_compat/torch/linalg.py @@ -1,14 +1,11 @@ from __future__ import annotations import torch -from typing import Optional, Union, Tuple +import torch.linalg -from torch.linalg import * # noqa: F403 +from .._internal import clone_module -# torch.linalg doesn't define __all__ -# from torch.linalg import __all__ as linalg_all -from torch import linalg as torch_linalg -linalg_all = [i for i in dir(torch_linalg) if not i.startswith('_')] +__all__ = clone_module("torch.linalg", globals()) # outer is implemented in torch but aren't in the linalg namespace from torch import outer @@ -30,9 +27,9 @@ def cross(x1: Array, x2: Array, /, *, axis: int = -1) -> Array: if not (x1.shape[axis] == x2.shape[axis] == 3): raise ValueError(f"cross product axis must have size 3, got {x1.shape[axis]} and {x2.shape[axis]}") x1, x2 = torch.broadcast_tensors(x1, x2) - return torch_linalg.cross(x1, x2, dim=axis) + return torch.linalg.cross(x1, x2, dim=axis) -def vecdot(x1: Array, x2: Array, /, *, axis: int = -1, **kwargs) -> Array: +def vecdot(x1: Array, x2: Array, /, *, axis: int = -1, **kwargs: object) -> Array: from ._aliases import isdtype x1, x2 = _fix_promotion(x1, x2, only_scalar=False) @@ -54,7 +51,7 @@ def vecdot(x1: Array, x2: Array, /, *, axis: int = -1, **kwargs) -> Array: return res[..., 0, 0] return torch.linalg.vecdot(x1, x2, dim=axis, **kwargs) -def solve(x1: Array, x2: Array, /, **kwargs) -> Array: +def solve(x1: Array, x2: Array, /, **kwargs: object) -> Array: x1, x2 = _fix_promotion(x1, x2, only_scalar=False) # Torch tries to emulate NumPy 1 solve behavior by using batched 1-D solve # whenever @@ -75,7 +72,7 @@ def solve(x1: Array, x2: Array, /, **kwargs) -> Array: return torch.linalg.solve(x1, x2, **kwargs) # torch.trace doesn't support the offset argument and doesn't support stacking -def trace(x: Array, /, *, offset: int = 0, dtype: Optional[DType] = None) -> Array: +def trace(x: Array, /, *, offset: int = 0, dtype: DType | None = None) -> Array: # Use our wrapped sum to make sure it does upcasting correctly return sum(torch.diagonal(x, offset=offset, dim1=-2, dim2=-1), axis=-1, dtype=dtype) @@ -83,11 +80,11 @@ def vector_norm( x: Array, /, *, - axis: Optional[Union[int, Tuple[int, ...]]] = None, + axis: int | tuple[int, ...] | None = None, keepdims: bool = False, # JustFloat stands for inf | -inf, which are not valid for Literal ord: JustInt | JustFloat = 2, - **kwargs, + **kwargs: object, ) -> Array: # torch.vector_norm incorrectly treats axis=() the same as axis=None if axis == (): @@ -110,12 +107,8 @@ def vector_norm( return out return torch.linalg.vector_norm(x, ord=ord, axis=axis, keepdim=keepdims, **kwargs) -__all__ = linalg_all + ['outer', 'matmul', 'matrix_transpose', 'tensordot', - 'cross', 'vecdot', 'solve', 'trace', 'vector_norm'] - -_all_ignore = ['torch_linalg', 'sum'] - -del linalg_all +__all__ += ['outer', 'matmul', 'matrix_transpose', 'tensordot', + 'cross', 'vecdot', 'solve', 'trace', 'vector_norm'] def __dir__() -> list[str]: return __all__ From b345ff7cadeb9f80035041e9bdf931cc695413d5 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Mon, 5 Jan 2026 14:38:22 +0100 Subject: [PATCH 095/462] TST cleanup of tests for LogisticRegression (#32759) --- sklearn/linear_model/tests/test_logistic.py | 399 ++++++-------------- 1 file changed, 121 insertions(+), 278 deletions(-) diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index da5df658f8099..81891951a3fa0 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -68,7 +68,7 @@ def check_predictions(clf, X, y): probabilities = clf.predict_proba(X) assert probabilities.shape == (n_samples, n_classes) - assert_array_almost_equal(probabilities.sum(axis=1), np.ones(n_samples)) + assert_allclose(probabilities.sum(axis=1), np.ones(n_samples)) assert_array_equal(probabilities.argmax(axis=1), y) @@ -86,97 +86,12 @@ def test_predict_2_classes(csr_container): check_predictions(LogisticRegression(fit_intercept=False), csr_container(X), Y1) -def test_logistic_cv_mock_scorer(): - """Test that LogisticRegressionCV calls the scorer.""" - - class MockScorer: - def __init__(self): - self.calls = 0 - self.scores = [0.1, 0.4, 0.8, 0.5] - - def __call__(self, model, X, y, sample_weight=None): - score = self.scores[self.calls % len(self.scores)] - self.calls += 1 - return score - - mock_scorer = MockScorer() - Cs = [1, 2, 3, 4] - cv = 2 - - lr = LogisticRegressionCV( - Cs=Cs, - l1_ratios=(0,), # TODO(1.10): remove with new default of l1_ratios - scoring=mock_scorer, - cv=cv, - use_legacy_attributes=False, - ) - X, y = make_classification(random_state=0) - lr.fit(X, y) - - # Cs[2] has the highest score (0.8) from MockScorer - assert lr.C_ == Cs[2] - - # scorer called 8 times (cv*len(Cs)) - assert mock_scorer.calls == cv * len(Cs) - - # reset mock_scorer - mock_scorer.calls = 0 - custom_score = lr.score(X, lr.predict(X)) - - assert custom_score == mock_scorer.scores[0] - assert mock_scorer.calls == 1 - - @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) def test_predict_3_classes(csr_container): check_predictions(LogisticRegression(C=10), X, Y2) check_predictions(LogisticRegression(C=10), csr_container(X), Y2) -@pytest.mark.parametrize( - "clf", - [ - LogisticRegression(C=len(iris.data), solver="lbfgs", max_iter=200), - LogisticRegression(C=len(iris.data), solver="newton-cg"), - LogisticRegression( - C=len(iris.data), - solver="sag", - tol=1e-2, - ), - LogisticRegression( - C=len(iris.data), - solver="saga", - tol=1e-2, - ), - LogisticRegression(C=len(iris.data), solver="newton-cholesky"), - OneVsRestClassifier(LogisticRegression(C=len(iris.data), solver="liblinear")), - ], -) -def test_predict_iris(clf, global_random_seed): - """Test logistic regression with the iris dataset. - - Test that different solvers handle multiclass data correctly and - give good accuracy score (>0.95) for the training data. - """ - clf = clone(clf) # Avoid side effects from shared instances - n_samples, _ = iris.data.shape - target = iris.target_names[iris.target] - - if getattr(clf, "solver", None) in ("sag", "saga", "liblinear"): - clf.set_params(random_state=global_random_seed) - clf.fit(iris.data, target) - assert_array_equal(np.unique(target), clf.classes_) - - pred = clf.predict(iris.data) - assert np.mean(pred == target) > 0.95 - - probabilities = clf.predict_proba(iris.data) - assert_allclose(probabilities.sum(axis=1), np.ones(n_samples)) - - pred = iris.target_names[probabilities.argmax(axis=1)] - assert np.mean(pred == target) > 0.95 - - @pytest.mark.filterwarnings("error::sklearn.exceptions.ConvergenceWarning") @pytest.mark.parametrize("solver", ["lbfgs", "newton-cholesky"]) def test_logistic_glmnet(solver): @@ -348,11 +263,13 @@ def test_inconsistent_input(): # Wrong dimensions for training data y_wrong = y_[:-1] - with pytest.raises(ValueError): + with pytest.raises( + ValueError, match="Found input variables with inconsistent number" + ): clf.fit(X, y_wrong) # Wrong dimensions for test data - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="X has 12 features, but"): clf.fit(X_, y_).predict(rng.random_sample((3, 12))) @@ -370,10 +287,10 @@ def test_nan(): # Regression test for Issue #252: fit used to go into an infinite loop. Xnan = np.array(X, dtype=np.float64) Xnan[0, 1] = np.nan - logistic = LogisticRegression() + clf = LogisticRegression() - with pytest.raises(ValueError): - logistic.fit(Xnan, Y1) + with pytest.raises(ValueError, match="Input X contains NaN."): + clf.fit(Xnan, Y1) def test_consistency_path(global_random_seed): @@ -543,6 +460,47 @@ def test_logistic_cv(global_random_seed, use_legacy_attributes): assert lr_cv.scores_.shape == (n_cv, n_l1_ratios, n_Cs) +def test_logistic_cv_mock_scorer(): + """Test that LogisticRegressionCV calls the scorer.""" + + class MockScorer: + def __init__(self): + self.calls = 0 + self.scores = [0.1, 0.4, 0.8, 0.5] + + def __call__(self, model, X, y, sample_weight=None): + score = self.scores[self.calls % len(self.scores)] + self.calls += 1 + return score + + mock_scorer = MockScorer() + Cs = [1, 2, 3, 4] + cv = 2 + + lr = LogisticRegressionCV( + Cs=Cs, + l1_ratios=(0,), # TODO(1.10): remove with new default of l1_ratios + scoring=mock_scorer, + cv=cv, + use_legacy_attributes=False, + ) + X, y = make_classification(random_state=0) + lr.fit(X, y) + + # Cs[2] has the highest score (0.8) from MockScorer + assert lr.C_ == Cs[2] + + # scorer called 8 times (cv*len(Cs)) + assert mock_scorer.calls == cv * len(Cs) + + # reset mock_scorer + mock_scorer.calls = 0 + custom_score = lr.score(X, lr.predict(X)) + + assert custom_score == mock_scorer.scores[0] + assert mock_scorer.calls == 1 + + @pytest.mark.parametrize( "scoring, multiclass_agg_list", [ @@ -652,23 +610,6 @@ def test_multinomial_logistic_regression_string_inputs(): assert sorted(np.unique(lr_cv_str.predict(X_ref))) == ["bar", "baz"] -@pytest.mark.parametrize("csr_container", CSR_CONTAINERS) -def test_logistic_cv_sparse(global_random_seed, csr_container): - X, y = make_classification( - n_samples=100, n_features=5, random_state=global_random_seed - ) - X[X < 1.0] = 0.0 - csr = csr_container(X) - - clf = LogisticRegressionCV(use_legacy_attributes=False) - clf.fit(X, y) - clfs = LogisticRegressionCV(use_legacy_attributes=False) - clfs.fit(csr, y) - assert_array_almost_equal(clfs.coef_, clf.coef_) - assert_array_almost_equal(clfs.intercept_, clf.intercept_) - assert clfs.C_ == clf.C_ - - # TODO(1.12): remove deprecated use_legacy_attributes @pytest.mark.parametrize("use_legacy_attributes", [True, False]) def test_multinomial_cv_iris(use_legacy_attributes): @@ -835,11 +776,12 @@ def test_logistic_regression_solvers(global_random_seed): @pytest.mark.parametrize("fit_intercept", [False, True]) def test_logistic_regression_solvers_multiclass(fit_intercept): """Test solvers converge to the same result for multiclass problems.""" + n_samples, n_features, n_classes = 20, 20, 3 X, y = make_classification( - n_samples=20, - n_features=20, + n_samples=n_samples, + n_features=n_features, n_informative=10, - n_classes=3, + n_classes=n_classes, random_state=0, ) tol = 1e-8 @@ -847,7 +789,7 @@ def test_logistic_regression_solvers_multiclass(fit_intercept): # Override max iteration count for specific solvers to allow for # proper convergence. - solver_max_iter = {"lbfgs": 200, "sag": 10_000, "saga": 10_000} + solver_max_iter = {"lbfgs": 200, "sag": 20_000, "saga": 20_000} classifiers = { solver: LogisticRegression( @@ -855,6 +797,10 @@ def test_logistic_regression_solvers_multiclass(fit_intercept): ).fit(X, y) for solver in set(SOLVERS) - set(["liblinear"]) } + for solver, clf in classifiers.items(): + assert clf.coef_.shape == (n_classes, n_features), ( + f"Solver {solver} generates coef_ with wrong shape." + ) for solver_1, solver_2 in itertools.combinations(classifiers, r=2): assert_allclose( @@ -871,6 +817,30 @@ def test_logistic_regression_solvers_multiclass(fit_intercept): err_msg=f"{solver_1} vs {solver_2}", ) + # Test that LogisticRegressionCV gives almost the same results for the same C. + # However, since in this case we take the average of the coefs after fitting across + # all the folds, it need not be exactly the same. + classifiers_cv = { + solver: LogisticRegressionCV( + Cs=[1.0], + solver=solver, + max_iter=solver_max_iter.get(solver, 100), + use_legacy_attributes=False, + **params, + ).fit(X, y) + for solver in set(SOLVERS) - set(["liblinear"]) + } + for solver in classifiers_cv: + assert_allclose( + classifiers_cv[solver].coef_, classifiers[solver].coef_, rtol=1e-2 + ) + if fit_intercept: + assert_allclose( + classifiers_cv[solver].intercept_, + classifiers[solver].intercept_, + rtol=1e-2, + ) + @pytest.mark.parametrize("fit_intercept", [False, True]) def test_logistic_regression_solvers_multiclass_unpenalized( @@ -942,6 +912,27 @@ def test_logistic_regression_solvers_multiclass_unpenalized( ) +@pytest.mark.parametrize("solver", SOLVERS) +@pytest.mark.parametrize("csr_container", CSR_CONTAINERS) +def test_logistic_cv_sparse(global_random_seed, solver, csr_container): + """Test that sparse and dense X gives same result for each solver.""" + X, y = make_classification( + n_samples=100, n_features=5, random_state=global_random_seed + ) + X[X < 0.0] = 0.0 # make it a bit sparse + params = dict(Cs=[1e-1, 1, 1e1], max_iter=10_000, tol=1e-6, random_state=42) + + clf = LogisticRegressionCV(solver=solver, use_legacy_attributes=False, **params) + clf.fit(X, y) + clfs = LogisticRegressionCV(solver=solver, use_legacy_attributes=False, **params) + clfs.fit(csr_container(X), y) + + rtol = 5e-2 if solver in ("sag", "saga") else 1e-5 + assert_allclose(clfs.coef_, clf.coef_, rtol=rtol) + assert_allclose(clfs.intercept_, clf.intercept_, rtol=rtol) + assert clfs.C_ == clf.C_ + + @pytest.mark.parametrize("weight", [{0: 0.1, 1: 0.2}, {0: 0.1, 1: 0.2, 2: 0.5}]) @pytest.mark.parametrize("class_weight", ["weight", "balanced"]) def test_logistic_regressioncv_class_weights(weight, class_weight, global_random_seed): @@ -994,9 +985,7 @@ def test_logistic_regressioncv_class_weights(weight, class_weight, global_random # TODO(1.10): remove filterwarnings with deprecation period of use_legacy_attributes @pytest.mark.filterwarnings("ignore:.*use_legacy_attributes.*:FutureWarning") @pytest.mark.parametrize("problem", ("single", "cv")) -@pytest.mark.parametrize( - "solver", ("lbfgs", "liblinear", "newton-cg", "newton-cholesky", "sag", "saga") -) +@pytest.mark.parametrize("solver", SOLVERS) def test_logistic_regression_sample_weights(problem, solver, global_random_seed): n_samples_per_cv_group = 200 n_cv_groups = 3 @@ -1036,13 +1025,13 @@ def test_logistic_regression_sample_weights(problem, solver, global_random_seed) ] ) splits_weighted = list(LeaveOneGroupOut().split(X, groups=groups_weighted)) - kw_weighted.update({"Cs": 100, "cv": splits_weighted}) + kw_weighted.update({"Cs": 10, "cv": splits_weighted}) groups_repeated = np.repeat(groups_weighted, sw.astype(int), axis=0) splits_repeated = list( LeaveOneGroupOut().split(X_repeated, groups=groups_repeated) ) - kw_repeated.update({"Cs": 100, "cv": splits_repeated}) + kw_repeated.update({"Cs": 10, "cv": splits_repeated}) clf_sw_weighted = LR(solver=solver, **kw_weighted) clf_sw_repeated = LR(solver=solver, **kw_repeated) @@ -1064,9 +1053,7 @@ def test_logistic_regression_sample_weights(problem, solver, global_random_seed) assert_allclose(clf_sw_weighted.coef_, clf_sw_repeated.coef_, atol=1e-5) -@pytest.mark.parametrize( - "solver", ("lbfgs", "newton-cg", "newton-cholesky", "sag", "saga") -) +@pytest.mark.parametrize("solver", SOLVERS) def test_logistic_regression_solver_class_weights(solver, global_random_seed): # Test that passing class_weight as [1, 2] is the same as # passing class weight = [1,1] but adjusting sample weights @@ -1204,69 +1191,6 @@ def test_logistic_regression_class_weights(global_random_seed, csr_container): assert_array_almost_equal(clf1.coef_, clf2.coef_, decimal=6) -def test_logistic_regression_multinomial(global_random_seed): - # Tests for the multinomial option in logistic regression - - # Some basic attributes of Logistic Regression - n_samples, n_features, n_classes = 200, 20, 3 - X, y = make_classification( - n_samples=n_samples, - n_features=n_features, - n_informative=10, - n_classes=n_classes, - random_state=global_random_seed, - ) - - X = StandardScaler(with_mean=False).fit_transform(X) - - # 'lbfgs' solver is used as a reference - it's the default - ref_i = LogisticRegression(tol=1e-10) - ref_w = LogisticRegression(fit_intercept=False, tol=1e-10) - ref_i.fit(X, y) - ref_w.fit(X, y) - assert ref_i.coef_.shape == (n_classes, n_features) - assert ref_w.coef_.shape == (n_classes, n_features) - for solver in ["sag", "saga", "newton-cg"]: - clf_i = LogisticRegression( - solver=solver, - random_state=global_random_seed, - max_iter=2000, - tol=1e-10, - ) - clf_w = LogisticRegression( - solver=solver, - random_state=global_random_seed, - max_iter=2000, - tol=1e-10, - fit_intercept=False, - ) - clf_i.fit(X, y) - clf_w.fit(X, y) - assert clf_i.coef_.shape == (n_classes, n_features) - assert clf_w.coef_.shape == (n_classes, n_features) - - # Compare solutions between lbfgs and the other solvers - assert_allclose(ref_i.coef_, clf_i.coef_, rtol=3e-3) - assert_allclose(ref_w.coef_, clf_w.coef_, rtol=1e-2) - assert_allclose(ref_i.intercept_, clf_i.intercept_, rtol=1e-3) - - # Test that the path give almost the same results. However since in this - # case we take the average of the coefs after fitting across all the - # folds, it need not be exactly the same. - for solver in ["lbfgs", "newton-cg", "sag", "saga"]: - clf_path = LogisticRegressionCV( - solver=solver, - random_state=global_random_seed, - max_iter=2000, - tol=1e-10, - Cs=[1.0], - use_legacy_attributes=False, - ) - clf_path.fit(X, y) - assert_allclose(clf_path.coef_, ref_i.coef_, rtol=1e-2) - assert_allclose(clf_path.intercept_, ref_i.intercept_, rtol=1e-2) - - def test_liblinear_decision_function_zero(global_random_seed): # Test negative prediction when decision_function values are zero. # Liblinear predicts the positive class when decision_function values @@ -1286,33 +1210,6 @@ def test_liblinear_decision_function_zero(global_random_seed): assert_array_equal(clf.predict(X), np.zeros(5)) -@pytest.mark.parametrize("csr_container", CSR_CONTAINERS) -def test_liblinear_logregcv_sparse(csr_container, global_random_seed): - # Test LogRegCV with solver='liblinear' works for sparse matrices - - X, y = make_classification( - n_samples=10, n_features=5, random_state=global_random_seed - ) - clf = LogisticRegressionCV(solver="liblinear", use_legacy_attributes=False) - clf.fit(csr_container(X), y) - - -@pytest.mark.parametrize("csr_container", CSR_CONTAINERS) -def test_saga_sparse(csr_container, global_random_seed): - # Test LogRegCV with solver='liblinear' works for sparse matrices - - X, y = make_classification( - n_samples=10, n_features=5, random_state=global_random_seed - ) - clf = LogisticRegressionCV( - solver="saga", - tol=1e-2, - random_state=global_random_seed, - use_legacy_attributes=False, - ) - clf.fit(csr_container(X), y) - - def test_logreg_intercept_scaling_zero(): # Test that intercept_scaling is ignored when fit_intercept is False @@ -1321,7 +1218,8 @@ def test_logreg_intercept_scaling_zero(): assert clf.intercept_ == 0.0 -def test_logreg_l1(global_random_seed): +@pytest.mark.parametrize("csr_container", CSR_CONTAINERS) +def test_logreg_l1(global_random_seed, csr_container): # Because liblinear penalizes the intercept and saga does not, we do not # fit the intercept to make it possible to compare the coefficients of # the two models at convergence. @@ -1333,86 +1231,31 @@ def test_logreg_l1(global_random_seed): X_noise = rng.normal(size=(n_samples, 3)) X_constant = np.ones(shape=(n_samples, 2)) X = np.concatenate((X, X_noise, X_constant), axis=1) - lr_liblinear = LogisticRegression( + params = dict( l1_ratio=1, C=1.0, - solver="liblinear", fit_intercept=False, max_iter=10000, tol=1e-10, random_state=global_random_seed, ) + lr_liblinear = LogisticRegression(solver="liblinear", **params) lr_liblinear.fit(X, y) - lr_saga = LogisticRegression( - l1_ratio=1, - C=1.0, - solver="saga", - fit_intercept=False, - max_iter=10000, - tol=1e-10, - random_state=global_random_seed, - ) + lr_saga = LogisticRegression(solver="saga", **params) lr_saga.fit(X, y) assert_allclose(lr_saga.coef_, lr_liblinear.coef_, atol=0.3) - -@pytest.mark.parametrize("csr_container", CSR_CONTAINERS) -def test_logreg_l1_sparse_data(global_random_seed, csr_container): - # Because liblinear penalizes the intercept and saga does not, we do not - # fit the intercept to make it possible to compare the coefficients of - # the two models at convergence. - rng = np.random.RandomState(global_random_seed) - n_samples = 50 - X, y = make_classification( - n_samples=n_samples, n_features=20, random_state=global_random_seed - ) - X_noise = rng.normal(scale=0.1, size=(n_samples, 3)) - X_constant = np.zeros(shape=(n_samples, 2)) - X = np.concatenate((X, X_noise, X_constant), axis=1) - X[X < 1] = 0 - X = csr_container(X) - - lr_liblinear = LogisticRegression( - l1_ratio=1, - C=1.0, - solver="liblinear", - fit_intercept=False, - tol=1e-10, - max_iter=10000, - random_state=global_random_seed, - ) - lr_liblinear.fit(X, y) - - lr_saga = LogisticRegression( - l1_ratio=1, - C=1.0, - solver="saga", - fit_intercept=False, - max_iter=10000, - tol=1e-10, - random_state=global_random_seed, - ) - lr_saga.fit(X, y) - assert_array_almost_equal(lr_saga.coef_, lr_liblinear.coef_) - # Noise and constant features should be regularized to zero by the l1 - # penalty - assert_array_almost_equal(lr_liblinear.coef_[0, -5:], np.zeros(5)) - assert_array_almost_equal(lr_saga.coef_[0, -5:], np.zeros(5)) - # Check that solving on the sparse and dense data yield the same results - lr_saga_dense = LogisticRegression( - l1_ratio=1, - C=1.0, - solver="saga", - fit_intercept=False, - max_iter=10000, - tol=1e-10, - random_state=global_random_seed, - ) - lr_saga_dense.fit(X.toarray(), y) - assert_array_almost_equal(lr_saga.coef_, lr_saga_dense.coef_) + X_sp = csr_container(X) + lr_liblinear_sp = LogisticRegression(solver="liblinear", **params) + lr_liblinear_sp.fit(X_sp, y) + assert_allclose(lr_liblinear_sp.coef_, lr_liblinear.coef_) + + lr_saga_sp = LogisticRegression(solver="saga", **params) + lr_saga_sp.fit(X_sp, y) + assert_allclose(lr_saga_sp.coef_, lr_saga.coef_) @pytest.mark.parametrize("l1_ratio", [1, 0]) # L1 and L2 penalty @@ -1444,7 +1287,7 @@ def test_logistic_regression_cv_refit(global_random_seed, l1_ratio): lr_cv.fit(X, y) lr = LogisticRegression(C=1.0, l1_ratio=l1_ratio, **common_params) lr.fit(X, y) - assert_array_almost_equal(lr_cv.coef_, lr.coef_) + assert_allclose(lr_cv.coef_, lr.coef_) def test_logreg_predict_proba_multinomial(global_random_seed): From dc882ace84bb339284881bc87f235c619ef843d6 Mon Sep 17 00:00:00 2001 From: Marco Edward Gorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Mon, 5 Jan 2026 15:18:49 +0000 Subject: [PATCH 096/462] MNT: Fix `pre-commit run --all-files` (#32813) --- doc/about.rst | 14 ++++++-------- doc/maintainers_emeritus.rst | 2 +- doc/modules/manifold.rst | 2 +- pyproject.toml | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/doc/about.rst b/doc/about.rst index d8f9f95807e8d..9c45e274c8869 100644 --- a/doc/about.rst +++ b/doc/about.rst @@ -263,7 +263,7 @@ Bronze sponsors .. div:: text-box - `NVIDIA `_ supports scikit-learn through their sponsorship and employs full-time core maintainer Tim Head. + `NVIDIA `_ supports scikit-learn through their sponsorship and employs full-time core maintainer Tim Head. .. div:: image-box @@ -525,7 +525,7 @@ list of events. Donating to the project ======================= -If you have found scikit-learn to be useful in your work, research, or company, +If you have found scikit-learn to be useful in your work, research, or company, please consider making a donation to the project commensurate with your resources. There are several options for making donations: @@ -558,15 +558,15 @@ There are several options for making donations: able to make a donation with a company match as high as 100%. Our project ID is `433725 `_. -All donations are managed by `NumFOCUS `_, a 501(c)(3) +All donations are managed by `NumFOCUS `_, a 501(c)(3) non-profit organization based in Austin, Texas, USA. The NumFOCUS board -consists of `SciPy community members `_. +consists of `SciPy community members `_. Contributions are tax-deductible to the extent allowed by law. .. rubric:: Notes -Contributions support the maintenance of the project, including development, -documentation, infrastructure and coding sprints. +Contributions support the maintenance of the project, including development, +documentation, infrastructure and coding sprints. scikit-learn Swag @@ -574,5 +574,3 @@ scikit-learn Swag Official scikit-learn swag is available for purchase at the `NumFOCUS online store `_. A portion of the proceeds from each sale goes to support the scikit-learn project. - - diff --git a/doc/maintainers_emeritus.rst b/doc/maintainers_emeritus.rst index 18edbfa90e3c6..04aef7fd0d7ac 100644 --- a/doc/maintainers_emeritus.rst +++ b/doc/maintainers_emeritus.rst @@ -40,4 +40,4 @@ - Nelle Varoquaux - David Warde-Farley - Ron Weiss -- Roman Yurchak \ No newline at end of file +- Roman Yurchak diff --git a/doc/modules/manifold.rst b/doc/modules/manifold.rst index 10f2b9c14d181..e04ef6b9187f0 100644 --- a/doc/modules/manifold.rst +++ b/doc/modules/manifold.rst @@ -522,7 +522,7 @@ Formally, the loss function of classical MDS (strain) is given by where :math:`Z` is the :math:`n \times d` embedding matrix whose rows are :math:`z_i^T`, :math:`\|\cdot\|_F` denotes the Frobenius norm, and -:math:`B` is the Gram matrix with elements :math:`b_{ij}`, +:math:`B` is the Gram matrix with elements :math:`b_{ij}`, given by :math:`B = -\frac{1}{2}C\Delta C`. Here :math:`C\Delta C` is the double-centered matrix of squared dissimilarities, with :math:`\Delta` being the matrix of squared input dissimilarities diff --git a/pyproject.toml b/pyproject.toml index 4eb1bd4c53371..11eb36a7986ef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -291,7 +291,7 @@ package = "sklearn" # name of your package whatsnew_pattern = 'doc/whatsnew/upcoming_changes/[^/]+/\d+\.[^.]+\.rst' [tool.codespell] -skip = ["./.git", "*.svg", "./.mypy_cache", "./sklearn/feature_extraction/_stop_words.py", "./sklearn/feature_extraction/tests/test_text.py", "./doc/_build", "./doc/auto_examples", "./doc/modules/generated"] +skip = ["./.git", "*.svg", "./.mypy_cache", "*sklearn/feature_extraction/_stop_words.py", "*sklearn/feature_extraction/tests/test_text.py", "./doc/_build", "./doc/auto_examples", "./doc/modules/generated"] ignore-words = "build_tools/codespell_ignore_words.txt" [tool.towncrier] From fafe37e414cf22448e861371c537fa2c476639b7 Mon Sep 17 00:00:00 2001 From: Lev <168672350+lsakovykh@users.noreply.github.com> Date: Mon, 5 Jan 2026 22:21:59 +0300 Subject: [PATCH 097/462] DOC add links to plot_ridge_coeffs example (#31454) Co-authored-by: Maren Westermann --- sklearn/linear_model/_ridge.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sklearn/linear_model/_ridge.py b/sklearn/linear_model/_ridge.py index edc40e45e8090..359916d93600e 100644 --- a/sklearn/linear_model/_ridge.py +++ b/sklearn/linear_model/_ridge.py @@ -454,6 +454,9 @@ def ridge_regression( If an array is passed, penalties are assumed to be specific to the targets. Hence they must correspond in number. + For an illustration of the effect of alpha on the model coefficients, see + :ref:`sphx_glr_auto_examples_linear_model_plot_ridge_coeffs.py`. + sample_weight : float or array-like of shape (n_samples,), default=None Individual weights for each sample. If given a float, every sample will have the same weight. If sample_weight is not None and @@ -1054,6 +1057,9 @@ class Ridge(MultiOutputMixin, RegressorMixin, _BaseRidge): If an array is passed, penalties are assumed to be specific to the targets. Hence they must correspond in number. + See :ref:`sphx_glr_auto_examples_linear_model_plot_ridge_coeffs.py` + for an illustration of the effect of alpha on the model coefficients. + fit_intercept : bool, default=True Whether to fit the intercept for this model. If set to false, no intercept will be used in calculations @@ -1396,6 +1402,9 @@ class RidgeClassifier(_RidgeClassifierMixin, _BaseRidge): :class:`~sklearn.linear_model.LogisticRegression` or :class:`~sklearn.svm.LinearSVC`. + For an illustration of the effect of alpha on the model coefficients, see + :ref:`sphx_glr_auto_examples_linear_model_plot_ridge_coeffs.py`. + fit_intercept : bool, default=True Whether to calculate the intercept for this model. If set to false, no intercept will be used in calculations (e.g. data is expected to be @@ -2622,6 +2631,9 @@ class RidgeCV(MultiOutputMixin, RegressorMixin, _BaseRidgeCV): :class:`~sklearn.svm.LinearSVC`. If using Leave-One-Out cross-validation, alphas must be strictly positive. + For an example on how regularization strength affects the model coefficients, + see :ref:`sphx_glr_auto_examples_linear_model_plot_ridge_coeffs.py`. + fit_intercept : bool, default=True Whether to calculate the intercept for this model. If set to false, no intercept will be used in calculations @@ -2812,6 +2824,9 @@ class RidgeClassifierCV(_RidgeClassifierMixin, _BaseRidgeCV): :class:`~sklearn.svm.LinearSVC`. If using Leave-One-Out cross-validation, alphas must be strictly positive. + For an example on how regularization strength affects the model coefficients, + see :ref:`sphx_glr_auto_examples_linear_model_plot_ridge_coeffs.py`. + fit_intercept : bool, default=True Whether to calculate the intercept for this model. If set to false, no intercept will be used in calculations From 173b8d51ecd9586dba2559e3389609ed5cd66f61 Mon Sep 17 00:00:00 2001 From: Arturo Amor <86408019+ArturoAmorQ@users.noreply.github.com> Date: Mon, 5 Jan 2026 19:48:51 -0600 Subject: [PATCH 098/462] DOC Rework StackingRegressor example and add SuperLearner (#32163) Co-authored-by: ArturoAmorQ Co-authored-by: Virgil Chan --- examples/ensemble/plot_stack_predictors.py | 368 +++++++++++---------- 1 file changed, 198 insertions(+), 170 deletions(-) diff --git a/examples/ensemble/plot_stack_predictors.py b/examples/ensemble/plot_stack_predictors.py index 78d1aab5dcc09..7922e2a794682 100644 --- a/examples/ensemble/plot_stack_predictors.py +++ b/examples/ensemble/plot_stack_predictors.py @@ -5,14 +5,18 @@ .. currentmodule:: sklearn -Stacking refers to a method to blend estimators. In this strategy, some -estimators are individually fitted on some training data while a final -estimator is trained using the stacked predictions of these base estimators. +Stacking is an :ref:`ensemble method `. In this strategy, the +out-of-fold predictions from several base estimators are used to train a +meta-model that combines their outputs at inference time. Unlike +:class:`~sklearn.ensemble.VotingRegressor`, which averages predictions with +fixed (optionally user-specified) weights, +:class:`~sklearn.ensemble.StackingRegressor` learns the combination through its +`final_estimator`. In this example, we illustrate the use case in which different regressors are -stacked together and a final linear penalized regressor is used to output the +stacked together and a final regularized linear regressor is used to output the prediction. We compare the performance of each individual regressor with the -stacking strategy. Stacking slightly improves the overall performance. +stacking strategy. Here, stacking slightly improves the overall performance. """ @@ -20,175 +24,73 @@ # SPDX-License-Identifier: BSD-3-Clause # %% -# Download the dataset -# #################### +# Generate data +# ############# # -# We will use the `Ames Housing`_ dataset which was first compiled by Dean De Cock -# and became better known after it was used in Kaggle challenge. It is a set -# of 1460 residential homes in Ames, Iowa, each described by 80 features. We -# will use it to predict the final logarithmic price of the houses. In this -# example we will use only 20 most interesting features chosen using -# GradientBoostingRegressor() and limit number of entries (here we won't go -# into the details on how to select the most interesting features). -# -# The Ames housing dataset is not shipped with scikit-learn and therefore we -# will fetch it from `OpenML`_. -# -# .. _`Ames Housing`: http://jse.amstat.org/v19n3/decock.pdf -# .. _`OpenML`: https://www.openml.org/d/42165 +# We use synthetic data generated from a sinusoid plus a linear trend with +# heteroscedastic Gaussian noise. A sudden drop is introduced, as it cannot be +# described by a linear model, but a tree-based model can naturally deal with +# it. import numpy as np +import pandas as pd -from sklearn.datasets import fetch_openml -from sklearn.utils import shuffle - - -def load_ames_housing(): - df = fetch_openml(name="house_prices", as_frame=True) - X = df.data - y = df.target - - features = [ - "YrSold", - "HeatingQC", - "Street", - "YearRemodAdd", - "Heating", - "MasVnrType", - "BsmtUnfSF", - "Foundation", - "MasVnrArea", - "MSSubClass", - "ExterQual", - "Condition2", - "GarageCars", - "GarageType", - "OverallQual", - "TotalBsmtSF", - "BsmtFinSF1", - "HouseStyle", - "MiscFeature", - "MoSold", - ] - - X = X.loc[:, features] - X, y = shuffle(X, y, random_state=0) - - X = X.iloc[:600] - y = y.iloc[:600] - return X, np.log(y) - - -X, y = load_ames_housing() - -# %% -# Make pipeline to preprocess the data -# #################################### -# -# Before we can use Ames dataset we still need to do some preprocessing. -# First, we will select the categorical and numerical columns of the dataset to -# construct the first step of the pipeline. - -from sklearn.compose import make_column_selector - -cat_selector = make_column_selector(dtype_include=[object, "string"]) -num_selector = make_column_selector(dtype_include=np.number) -cat_selector(X) +rng = np.random.RandomState(42) +X = rng.uniform(-3, 3, size=500) +trend = 2.4 * X +seasonal = 3.1 * np.sin(3.2 * X) +drop = 10.0 * (X > 2).astype(float) +sigma = 0.75 + 0.75 * X**2 +y = trend + seasonal - drop + rng.normal(loc=0.0, scale=np.sqrt(sigma)) -# %% -num_selector(X) - -# %% -# Then, we will need to design preprocessing pipelines which depends on the -# ending regressor. If the ending regressor is a linear model, one needs to -# one-hot encode the categories. If the ending regressor is a tree-based model -# an ordinal encoder will be sufficient. Besides, numerical values need to be -# standardized for a linear model while the raw numerical data can be treated -# as is by a tree-based model. However, both models need an imputer to -# handle missing values. -# -# We will first design the pipeline required for the tree-based models. - -from sklearn.compose import make_column_transformer -from sklearn.impute import SimpleImputer -from sklearn.pipeline import make_pipeline -from sklearn.preprocessing import OrdinalEncoder - -cat_tree_processor = OrdinalEncoder( - handle_unknown="use_encoded_value", - unknown_value=-1, - encoded_missing_value=-2, -) -num_tree_processor = SimpleImputer(strategy="mean", add_indicator=True) - -tree_preprocessor = make_column_transformer( - (num_tree_processor, num_selector), (cat_tree_processor, cat_selector) -) -tree_preprocessor - -# %% -# Then, we will now define the preprocessor used when the ending regressor -# is a linear model. - -from sklearn.preprocessing import OneHotEncoder, StandardScaler - -cat_linear_processor = OneHotEncoder(handle_unknown="ignore") -num_linear_processor = make_pipeline( - StandardScaler(), SimpleImputer(strategy="mean", add_indicator=True) -) - -linear_preprocessor = make_column_transformer( - (num_linear_processor, num_selector), (cat_linear_processor, cat_selector) -) -linear_preprocessor +df = pd.DataFrame({"X": X, "y": y}) +_ = df.plot.scatter(x="X", y="y") # %% # Stack of predictors on a single data set # ######################################## # -# It is sometimes tedious to find the model which will best perform on a given -# dataset. Stacking provide an alternative by combining the outputs of several -# learners, without the need to choose a model specifically. The performance of -# stacking is usually close to the best model and sometimes it can outperform -# the prediction performance of each individual model. +# It is sometimes not evident which model is more suited for a given task, as +# different model families can achieve similar performance while exhibiting +# different strengths and weaknesses. Stacking combines their outputs to exploit +# these complementary behaviors and can correct systematic errors that no single +# model can fix on its own. With appropriate regularization in the +# `final_estimator`, the :class:`~sklearn.ensemble.StackingRegressor` often +# matches the strongest base model, and can outperform it when base learners' +# errors are only partially correlated, allowing the combination to reduce +# individual bias/variance. # -# Here, we combine 3 learners (linear and non-linear) and use a ridge regressor -# to combine their outputs together. +# Here, we combine 3 learners (linear and non-linear) and use the default +# :class:`~sklearn.linear_model.RidgeCV` regressor to combine their outputs +# together. # # .. note:: -# Although we will make new pipelines with the processors which we wrote in -# the previous section for the 3 learners, the final estimator -# :class:`~sklearn.linear_model.RidgeCV()` does not need preprocessing of -# the data as it will be fed with the already preprocessed output from the 3 -# learners. - -from sklearn.linear_model import LassoCV - -lasso_pipeline = make_pipeline(linear_preprocessor, LassoCV()) -lasso_pipeline - -# %% -from sklearn.ensemble import RandomForestRegressor - -rf_pipeline = make_pipeline(tree_preprocessor, RandomForestRegressor(random_state=42)) -rf_pipeline +# Although some base learners include preprocessing (such as the +# :class:`~sklearn.preprocessing.StandardScaler`), the `final_estimator` does +# not need additional preprocessing when using the default +# `passthrough=False`, as it receives only the base learners' predictions. If +# `passthrough=True`, `final_estimator` should be a pipeline with proper +# preprocessing. + +from sklearn.ensemble import HistGradientBoostingRegressor, StackingRegressor +from sklearn.linear_model import RidgeCV +from sklearn.pipeline import make_pipeline +from sklearn.preprocessing import PolynomialFeatures, SplineTransformer, StandardScaler -# %% -from sklearn.ensemble import HistGradientBoostingRegressor +linear_ridge = make_pipeline(StandardScaler(), RidgeCV()) -gbdt_pipeline = make_pipeline( - tree_preprocessor, HistGradientBoostingRegressor(random_state=0) +spline_ridge = make_pipeline( + SplineTransformer(n_knots=6, degree=3), + PolynomialFeatures(interaction_only=True), + RidgeCV(), ) -gbdt_pipeline -# %% -from sklearn.ensemble import StackingRegressor -from sklearn.linear_model import RidgeCV +hgbt = HistGradientBoostingRegressor(random_state=0) estimators = [ - ("Random Forest", rf_pipeline), - ("Lasso", lasso_pipeline), - ("Gradient Boosting", gbdt_pipeline), + ("Linear Ridge", linear_ridge), + ("Spline Ridge", spline_ridge), + ("HGBT", hgbt), ] stacking_regressor = StackingRegressor(estimators=estimators, final_estimator=RidgeCV()) @@ -198,14 +100,54 @@ def load_ames_housing(): # Measure and plot the results # ############################ # -# Now we can use Ames Housing dataset to make the predictions. We check the -# performance of each individual predictor as well as of the stack of the -# regressors. +# We can directly plot the predictions. Indeed, the sudden drop is correctly +# described by the :class:`~sklearn.ensemble.HistGradientBoostingRegressor` +# model (HGBT), but the spline model is smoother and less overfitting. The stacked +# regressor then turns to be a smoother version of the HGBT. +import matplotlib.pyplot as plt -import time +X = X.reshape(-1, 1) +linear_ridge.fit(X, y) +spline_ridge.fit(X, y) +hgbt.fit(X, y) +stacking_regressor.fit(X, y) + +x_plot = np.linspace(X.min() - 0.1, X.max() + 0.1, 500).reshape(-1, 1) +preds = { + "Linear Ridge": linear_ridge.predict(x_plot), + "Spline Ridge": spline_ridge.predict(x_plot), + "HGBT": hgbt.predict(x_plot), + "Stacking (Ridge final estimator)": stacking_regressor.predict(x_plot), +} + +fig, axes = plt.subplots(2, 2, figsize=(10, 8), sharex=True, sharey=True) +axes = axes.ravel() +for ax, (name, y_pred) in zip(axes, preds.items()): + ax.scatter( + X[:, 0], + y, + s=6, + alpha=0.35, + linewidths=0, + label="observed (sample)", + ) -import matplotlib.pyplot as plt + ax.plot(x_plot.ravel(), y_pred, linewidth=2, alpha=0.9, label=name) + ax.set_title(name) + ax.set_xlabel("x") + ax.set_ylabel("y") + ax.legend(loc="lower right") + +plt.suptitle("Base Models Predictions versus Stacked Predictions", y=1) +plt.tight_layout() +plt.show() + +# %% +# We can plot the prediction errors as well and evaluate the performance of the +# individual predictors and the stack of the regressors. + +import time from sklearn.metrics import PredictionErrorDisplay from sklearn.model_selection import cross_val_predict, cross_validate @@ -216,18 +158,17 @@ def load_ames_housing(): for ax, (name, est) in zip( axs, estimators + [("Stacking Regressor", stacking_regressor)] ): - scorers = {"R2": "r2", "MAE": "neg_mean_absolute_error"} + scorers = {r"$R^2$": "r2", "MAE": "neg_mean_absolute_error"} start_time = time.time() - scores = cross_validate( - est, X, y, scoring=list(scorers.values()), n_jobs=-1, verbose=0 - ) + scores = cross_validate(est, X, y, scoring=list(scorers.values()), n_jobs=-1) elapsed_time = time.time() - start_time - y_pred = cross_val_predict(est, X, y, n_jobs=-1, verbose=0) + y_pred = cross_val_predict(est, X, y, n_jobs=-1) scores = { key: ( - f"{np.abs(np.mean(scores[f'test_{value}'])):.2f} +- " + f"{np.abs(np.mean(scores[f'test_{value}'])):.2f}" + r" $\pm$ " f"{np.std(scores[f'test_{value}']):.2f}" ) for key, value in scorers.items() @@ -247,12 +188,99 @@ def load_ames_housing(): ax.plot([], [], " ", label=f"{name}: {score}") ax.legend(loc="upper left") -plt.suptitle("Single predictors versus stacked predictors") +plt.suptitle("Prediction Errors of Base versus Stacked Predictors", y=1) plt.tight_layout() plt.subplots_adjust(top=0.9) plt.show() # %% -# The stacked regressor will combine the strengths of the different regressors. -# However, we also see that training the stacked regressor is much more -# computationally expensive. +# Even if the scores overlap considerably after cross-validation, the predictions +# from the stacked regressor are slightly better. +# +# Once fitted, we can inspect the coefficients (or meta-weights) of the trained +# `final_estimator_` (as long as it is a linear model). They reveal how much the +# individual estimators contribute to the the stacked regressor: + +stacking_regressor.fit(X, y) +stacking_regressor.final_estimator_.coef_ + +# %% +# We see that in this case, the HGBT model dominates, with the spline +# ridge also contributing meaningfully. The plain linear model does not add +# useful signal once those two are included; with +# :class:`~sklearn.linear_model.RidgeCV` as the `final_estimator`, it is not +# dropped, but receives a small negative weight to correct its residual bias. +# +# If we use :class:`~sklearn.linear_model.LassoCV` as the +# `final_estimator`, that small, unhelpful contribution is set exactly to zero, +# yielding a simpler blend of the spline ridge and HGBT models. + +from sklearn.linear_model import LassoCV + +stacking_regressor = StackingRegressor(estimators=estimators, final_estimator=LassoCV()) +stacking_regressor.fit(X, y) +stacking_regressor.final_estimator_.coef_ + +# %% +# How to mimic SuperLearner with scikit-learn +# ########################################### +# +# The `SuperLearner` [Polley2010]_ is a stacking strategy implemented as `an R +# package `_, but +# not available off-the-shelf in Python. It is closely related to the +# :class:`~sklearn.ensemble.StackingRegressor`, as both train the meta-model on +# out-of-fold predictions from the base estimators. +# +# The key difference is that `SuperLearner` estimates a convex set of +# meta-weights (non-negative and summing to 1) and omits an intercept; by +# contrast, :class:`~sklearn.ensemble.StackingRegressor` uses an unconstrained +# meta-learner with an intercept by default (and can optionally include raw +# features via passthrough). +# +# Without an intercept, the meta-weights are directly interpretable as +# fractional contributions to the final prediction. + +from sklearn.linear_model import LinearRegression + +linear_reg = LinearRegression(fit_intercept=False, positive=True) +super_learner_like = StackingRegressor( + estimators=estimators, final_estimator=linear_reg +) +super_learner_like.fit(X, y) +super_learner_like.final_estimator_.coef_ + +# %% +# The sum of meta-weights in the stacked regressor is close to 1.0, but not +# exactly one: + +super_learner_like.final_estimator_.coef_.sum() + +# %% +# Beyond interpretability, the normalization to 1.0 constraint in the `SuperLearner` +# presents the following advantages: +# +# - Consensus-preserving: if all base models output the same value at a point, +# the ensemble returns that same value (no artificial amplification or +# attenuation). +# - Translation-equivariant: adding a constant to every base prediction shifts +# the ensemble by the same constant. +# - Removes one degree of freedom: avoiding redundancy with a constant term and +# modestly stabilizing weights under collinearity. +# +# The cleanest way to enforce the coefficient normalization with scikit-learn is +# by defining a custom estimator, but doing so is beyond the scope of this +# tutorial. +# +# Conclusions +# ########### +# +# The stacked regressor combines the strengths of the different regressors. +# However, notice that training the stacked regressor is much more +# computationally expensive than selecting the best performing model. +# +# .. rubric:: References +# +# .. [Polley2010] Polley, E. C. and van der Laan, M. J., `Super Learner In +# Prediction +# `_, +# 2010. From 8061a3988f277b80e4ddc4db52c3980c2664a532 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Tue, 6 Jan 2026 13:53:28 +0100 Subject: [PATCH 099/462] TST missing random state seed in test_ridge_regression_check_arguments_validity (#33013) --- sklearn/linear_model/tests/test_ridge.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sklearn/linear_model/tests/test_ridge.py b/sklearn/linear_model/tests/test_ridge.py index 19757b1d0ebc3..b6032baa29e8e 100644 --- a/sklearn/linear_model/tests/test_ridge.py +++ b/sklearn/linear_model/tests/test_ridge.py @@ -1900,6 +1900,7 @@ def test_ridge_regression_check_arguments_validity( return_intercept=return_intercept, positive=positive, tol=tol, + random_state=rng, ) return @@ -1912,6 +1913,7 @@ def test_ridge_regression_check_arguments_validity( positive=positive, return_intercept=return_intercept, tol=tol, + random_state=rng, ) if return_intercept: From 39e3116fe0b0c2da2d74edfae99964ece33d4e9e Mon Sep 17 00:00:00 2001 From: "Emily (Xinyi) Chen" <52259856+EmilyXinyi@users.noreply.github.com> Date: Tue, 6 Jan 2026 09:24:05 -0500 Subject: [PATCH 100/462] Add array API support for Nystroem approximation (#29661) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivier Grisel Co-authored-by: Loïc Estève Co-authored-by: Lucy Liu --- .github/workflows/cuda-ci.yml | 2 +- doc/modules/array_api.rst | 1 + .../array-api/29661.enhancement.rst | 2 + sklearn/kernel_approximation.py | 31 ++++++++--- sklearn/metrics/pairwise.py | 5 +- sklearn/tests/test_kernel_approximation.py | 55 ++++++++++++++++++- 6 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/29661.enhancement.rst diff --git a/.github/workflows/cuda-ci.yml b/.github/workflows/cuda-ci.yml index 935e5b187a8ae..4f87cbff95737 100644 --- a/.github/workflows/cuda-ci.yml +++ b/.github/workflows/cuda-ci.yml @@ -66,6 +66,6 @@ jobs: conda activate sklearn python -c "import sklearn; sklearn.show_versions()" - SCIPY_ARRAY_API=1 pytest --pyargs sklearn -k 'array_api' -v + SCIPY_ARRAY_API=1 pytest --pyargs sklearn -k 'array_api' -vl # Run in /home/runner to not load sklearn from the checkout repo working-directory: /home/runner diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index b3cf4dd7476f0..11d7d8c37cc0d 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -125,6 +125,7 @@ Estimators - :class:`decomposition.PCA` (with `svd_solver="full"`, `svd_solver="covariance_eigh"`, or `svd_solver="randomized"` (`svd_solver="randomized"` only if `power_iteration_normalizer="QR"`)) +- :class:`kernel_approximation.Nystroem` - :class:`linear_model.Ridge` (with `solver="svd"`) - :class:`linear_model.RidgeCV` (with `solver="svd"`, see :ref:`device_support_for_float64`) - :class:`linear_model.RidgeClassifier` (with `solver="svd"`) diff --git a/doc/whats_new/upcoming_changes/array-api/29661.enhancement.rst b/doc/whats_new/upcoming_changes/array-api/29661.enhancement.rst new file mode 100644 index 0000000000000..f5e2921ca96ba --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/29661.enhancement.rst @@ -0,0 +1,2 @@ +- :class:`kernel_approximation.Nystroem` now supports array API compatible inputs. + By :user:`Emily Chen ` \ No newline at end of file diff --git a/sklearn/kernel_approximation.py b/sklearn/kernel_approximation.py index 564295339fc77..21672d28ced5c 100644 --- a/sklearn/kernel_approximation.py +++ b/sklearn/kernel_approximation.py @@ -9,7 +9,6 @@ import numpy as np import scipy.sparse as sp from scipy.fft import fft, ifft -from scipy.linalg import svd from sklearn.base import ( BaseEstimator, @@ -20,9 +19,15 @@ from sklearn.metrics.pairwise import ( KERNEL_PARAMS, PAIRWISE_KERNEL_FUNCTIONS, + _find_floating_dtype_allow_sparse, pairwise_kernels, ) from sklearn.utils import check_random_state +from sklearn.utils._array_api import ( + _find_matching_floating_dtype, + get_namespace_and_device, +) +from sklearn.utils._indexing import _safe_indexing from sklearn.utils._param_validation import Interval, StrOptions from sklearn.utils.extmath import safe_sparse_dot from sklearn.utils.validation import ( @@ -384,7 +389,6 @@ def fit(self, X, y=None): # output data type during `transform`. self.random_weights_ = self.random_weights_.astype(X.dtype, copy=False) self.random_offset_ = self.random_offset_.astype(X.dtype, copy=False) - self._n_features_out = self.n_components return self @@ -1013,6 +1017,7 @@ def fit(self, X, y=None): self : object Returns the instance itself. """ + xp, _, device = get_namespace_and_device(X) X = validate_data(self, X, accept_sparse="csr") rnd = check_random_state(self.random_state) n_samples = X.shape[0] @@ -1031,8 +1036,11 @@ def fit(self, X, y=None): n_components = self.n_components n_components = min(n_samples, n_components) inds = rnd.permutation(n_samples) - basis_inds = inds[:n_components] - basis = X[basis_inds] + basis_inds = xp.asarray(inds[:n_components], dtype=xp.int64, device=device) + if sp.issparse(X): + basis = X[basis_inds] + else: + basis = _safe_indexing(X, basis_inds, axis=0) basis_kernel = pairwise_kernels( basis, @@ -1043,9 +1051,11 @@ def fit(self, X, y=None): ) # sqrt of kernel matrix on basis vectors - U, S, V = svd(basis_kernel) - S = np.maximum(S, 1e-12) - self.normalization_ = np.dot(U / np.sqrt(S), V) + _, _, dtype = _find_floating_dtype_allow_sparse(basis_kernel, Y=None, xp=xp) + basis_kernel = xp.asarray(basis_kernel, dtype=dtype, device=device) + U, S, V = xp.linalg.svd(basis_kernel) + S = xp.clip(S, 1e-12, None) + self.normalization_ = U / xp.sqrt(S) @ V self.components_ = basis self.component_indices_ = basis_inds self._n_features_out = n_components @@ -1068,6 +1078,8 @@ def transform(self, X): Transformed data. """ check_is_fitted(self) + + xp, _, device = get_namespace_and_device(X) X = validate_data(self, X, accept_sparse="csr", reset=False) kernel_params = self._get_kernel_params() @@ -1079,7 +1091,9 @@ def transform(self, X): n_jobs=self.n_jobs, **kernel_params, ) - return np.dot(embedded, self.normalization_.T) + dtype = _find_matching_floating_dtype(embedded, xp=xp) + embedded = xp.asarray(embedded, dtype=dtype, device=device) + return embedded @ self.normalization_.T def _get_kernel_params(self): params = self.kernel_params @@ -1105,6 +1119,7 @@ def _get_kernel_params(self): def __sklearn_tags__(self): tags = super().__sklearn_tags__() + tags.array_api_support = True tags.input_tags.sparse = True tags.transformer_tags.preserves_dtype = ["float64", "float32"] return tags diff --git a/sklearn/metrics/pairwise.py b/sklearn/metrics/pairwise.py index 80ce9fd89bfd6..458fce2e284bb 100644 --- a/sklearn/metrics/pairwise.py +++ b/sklearn/metrics/pairwise.py @@ -52,8 +52,9 @@ def _return_float_dtype(X, Y): 1. If dtype of X and Y is float32, then dtype float32 is returned. 2. Else dtype float is returned. """ + xp, _ = get_namespace(X, Y) if not issparse(X) and not isinstance(X, np.ndarray): - X = np.asarray(X) + X = xp.asarray(X) if Y is None: Y_dtype = X.dtype @@ -1545,12 +1546,14 @@ def sigmoid_kernel(X, Y=None, gamma=None, coef0=1): """ xp, _ = get_namespace(X, Y) X, Y = check_pairwise_arrays(X, Y) + if gamma is None: gamma = 1.0 / X.shape[1] K = safe_sparse_dot(X, Y.T, dense_output=True) K *= gamma K += coef0 + # compute tanh in-place for numpy K = _modify_in_place_if_numpy(xp, xp.tanh, K, out=K) return K diff --git a/sklearn/tests/test_kernel_approximation.py b/sklearn/tests/test_kernel_approximation.py index a3b0c47adc3eb..9372ddb2ca72a 100644 --- a/sklearn/tests/test_kernel_approximation.py +++ b/sklearn/tests/test_kernel_approximation.py @@ -3,6 +3,7 @@ import numpy as np import pytest +from sklearn._config import config_context from sklearn.datasets import make_classification from sklearn.kernel_approximation import ( AdditiveChi2Sampler, @@ -17,7 +18,17 @@ polynomial_kernel, rbf_kernel, ) +from sklearn.utils._array_api import ( + _atol_for_type, + _convert_to_numpy, + get_namespace_and_device, + yield_namespace_device_dtype_combinations, +) +from sklearn.utils._array_api import ( + device as array_device, +) from sklearn.utils._testing import ( + _array_api_for_tests, assert_allclose, assert_array_almost_equal, assert_array_equal, @@ -90,8 +101,8 @@ def test_polynomial_count_sketch_dense_sparse(gamma, degree, coef0, csr_containe assert_allclose(Yt_dense, Yt_sparse) -def _linear_kernel(X, Y): - return np.dot(X, Y.T) +def _linear_kernel(x, y): + return x @ y @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) @@ -338,6 +349,46 @@ def test_nystroem_approximation(): assert X_transformed.shape == (X.shape[0], 2) +@pytest.mark.parametrize( + "array_namespace, device, dtype_name", yield_namespace_device_dtype_combinations() +) +@pytest.mark.parametrize( + "kernel", list(kernel_metrics()) + [_linear_kernel, "precomputed"] +) +@pytest.mark.parametrize("n_components", [2, 100]) +def test_nystroem_approximation_array_api( + array_namespace, device, dtype_name, kernel, n_components +): + xp = _array_api_for_tests(array_namespace, device) + rnd = np.random.RandomState(0) + n_samples = 10 + # Ensure full-rank linear kernel to limit the impact of device-specific + # rounding discrepancies. + n_features = 2 * n_samples + X_np = rnd.uniform(size=(n_samples, n_features)).astype(dtype_name) + if kernel == "precomputed": + X_np = rbf_kernel(X_np[:n_components]) + + X_xp = xp.asarray(X_np, device=device) + + nystroem = Nystroem(n_components=n_components, kernel=kernel, random_state=0) + X_np_transformed = nystroem.fit_transform(X_np) + + with config_context(array_api_dispatch=True): + X_xp_transformed = nystroem.fit_transform(X_xp) + X_xp_transformed_np = _convert_to_numpy(X_xp_transformed, xp=xp) + + for attribute_name in ["components_", "normalization_"]: + xp_attr, _, device_attr = get_namespace_and_device( + getattr(nystroem, attribute_name) + ) + assert xp_attr is xp + assert device_attr == array_device(X_xp) + + atol = _atol_for_type(dtype_name) + assert_allclose(X_np_transformed, X_xp_transformed_np, atol=atol) + + def test_nystroem_default_parameters(): rnd = np.random.RandomState(42) X = rnd.uniform(size=(10, 4)) From 938cd9798879757d8f681d5c82cdf0503aac96a3 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Tue, 6 Jan 2026 15:26:20 +0100 Subject: [PATCH 101/462] Fix make sure enabling `array_api_dispatch=True` does not break any estimator on NumPy inputs (#32846) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Omar Salman Co-authored-by: Lucy Liu Co-authored-by: Loïc Estève Co-authored-by: Tim Head --- .../upcoming_changes/array-api/32846.fix.rst | 3 + sklearn/decomposition/_dict_learning.py | 2 +- sklearn/utils/_array_api.py | 50 ++++++-- .../utils/_test_common/instance_generator.py | 24 +++- sklearn/utils/estimator_checks.py | 118 +++++++++++------- sklearn/utils/tests/test_array_api.py | 13 +- 6 files changed, 142 insertions(+), 68 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/32846.fix.rst diff --git a/doc/whats_new/upcoming_changes/array-api/32846.fix.rst b/doc/whats_new/upcoming_changes/array-api/32846.fix.rst new file mode 100644 index 0000000000000..c9df3929e14c6 --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/32846.fix.rst @@ -0,0 +1,3 @@ +- Fixed a bug that would cause Cython-based estimators to fail when fit on + NumPy inputs when setting `sklearn.set_config(array_api_dispatch=True)`. By + :user:`Olivier Grisel `. diff --git a/sklearn/decomposition/_dict_learning.py b/sklearn/decomposition/_dict_learning.py index d4550e4ce8982..2a32ad92de83e 100644 --- a/sklearn/decomposition/_dict_learning.py +++ b/sklearn/decomposition/_dict_learning.py @@ -1360,7 +1360,7 @@ def fit(self, X, y=None): if X.shape[1] != self.dictionary.shape[1]: raise ValueError( "Dictionary and X have different numbers of features:" - f"dictionary.shape: {self.dictionary.shape} X.shape{X.shape}" + f"dictionary.shape: {self.dictionary.shape} X.shape: {X.shape}" ) return self diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 8bcf8bde132ea..23239ee062267 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -23,6 +23,11 @@ __all__ = ["xpx"] # we import xpx here just to re-export it, need this to appease ruff _NUMPY_NAMESPACE_NAMES = {"numpy", "sklearn.externals.array_api_compat.numpy"} +REMOVE_TYPES_DEFAULT = ( + str, + list, + tuple, +) def yield_namespaces(include_numpy_namespaces=True): @@ -167,7 +172,7 @@ def _single_array_device(array): return array.device -def device(*array_list, remove_none=True, remove_types=(str,)): +def device(*array_list, remove_none=True, remove_types=REMOVE_TYPES_DEFAULT): """Hardware device where the array data resides on. If the hardware device is not the same for all arrays, an error is raised. @@ -180,7 +185,7 @@ def device(*array_list, remove_none=True, remove_types=(str,)): remove_none : bool, default=True Whether to ignore None objects passed in array_list. - remove_types : tuple or list, default=(str,) + remove_types : tuple or list, default=(str, list, tuple) Types to ignore in array_list. Returns @@ -290,7 +295,7 @@ def supported_float_dtypes(xp, device=None): return tuple(valid_float_dtypes) -def _remove_non_arrays(*arrays, remove_none=True, remove_types=(str,)): +def _remove_non_arrays(*arrays, remove_none=True, remove_types=REMOVE_TYPES_DEFAULT): """Filter arrays to exclude None and/or specific types. Sparse arrays are always filtered out. @@ -303,7 +308,7 @@ def _remove_non_arrays(*arrays, remove_none=True, remove_types=(str,)): remove_none : bool, default=True Whether to ignore None objects passed in arrays. - remove_types : tuple or list, default=(str,) + remove_types : tuple or list, default=(str, list, tuple) Types to ignore in the arrays. Returns @@ -328,7 +333,27 @@ def _remove_non_arrays(*arrays, remove_none=True, remove_types=(str,)): return filtered_arrays -def get_namespace(*arrays, remove_none=True, remove_types=(str,), xp=None): +def _unwrap_memoryviewslices(*arrays): + # Since _cyutility._memoryviewslice is an implementation detail of the + # Cython runtime, we would rather not introduce a possibly brittle + # import statement to run `isinstance`-based filtering, hence the + # attribute-based type inspection. + unwrapped = [] + for a in arrays: + a_type = type(a) + if ( + a_type.__module__ == "_cyutility" + and a_type.__name__ == "_memoryviewslice" + and hasattr(a, "base") + ): + a = a.base + unwrapped.append(a) + return unwrapped + + +def get_namespace( + *arrays, remove_none=True, remove_types=REMOVE_TYPES_DEFAULT, xp=None +): """Get namespace of arrays. Introspect `arrays` arguments and return their common Array API compatible @@ -364,7 +389,7 @@ def get_namespace(*arrays, remove_none=True, remove_types=(str,), xp=None): remove_none : bool, default=True Whether to ignore None objects passed in arrays. - remove_types : tuple or list, default=(str,) + remove_types : tuple or list, default=(str, list, tuple) Types to ignore in the arrays. xp : module, default=None @@ -399,12 +424,19 @@ def get_namespace(*arrays, remove_none=True, remove_types=(str,), xp=None): remove_types=remove_types, ) + # get_namespace can be called by helper functions that are used both in + # array API compatible code and non-array API Cython related code. To + # support the latter on NumPy inputs without raising a TypeError, we + # unwrap potential Cython memoryview slices here. + arrays = _unwrap_memoryviewslices(*arrays) + if not arrays: return np_compat, False _check_array_api_dispatch(array_api_dispatch) - namespace, is_array_api_compliant = array_api_compat.get_namespace(*arrays), True + namespace = array_api_compat.get_namespace(*arrays) + is_array_api_compliant = True if namespace.__name__ == "array_api_strict" and hasattr( namespace, "set_array_api_strict_flags" @@ -415,7 +447,7 @@ def get_namespace(*arrays, remove_none=True, remove_types=(str,), xp=None): def get_namespace_and_device( - *array_list, remove_none=True, remove_types=(str,), xp=None + *array_list, remove_none=True, remove_types=REMOVE_TYPES_DEFAULT, xp=None ): """Combination into one single function of `get_namespace` and `device`. @@ -425,7 +457,7 @@ def get_namespace_and_device( Array objects. remove_none : bool, default=True Whether to ignore None objects passed in arrays. - remove_types : tuple or list, default=(str,) + remove_types : tuple or list, default=(str, list, tuple) Types to ignore in the arrays. xp : module, default=None Precomputed array namespace module. When passed, typically from a caller diff --git a/sklearn/utils/_test_common/instance_generator.py b/sklearn/utils/_test_common/instance_generator.py index 14f8090b96cf8..176d1ab070ca6 100644 --- a/sklearn/utils/_test_common/instance_generator.py +++ b/sklearn/utils/_test_common/instance_generator.py @@ -46,7 +46,10 @@ SparsePCA, TruncatedSVD, ) -from sklearn.discriminant_analysis import LinearDiscriminantAnalysis +from sklearn.discriminant_analysis import ( + LinearDiscriminantAnalysis, + QuadraticDiscriminantAnalysis, +) from sklearn.dummy import DummyClassifier from sklearn.ensemble import ( AdaBoostClassifier, @@ -79,6 +82,7 @@ SequentialFeatureSelector, ) from sklearn.frozen import FrozenEstimator +from sklearn.impute import SimpleImputer from sklearn.kernel_approximation import ( Nystroem, PolynomialCountSketch, @@ -559,11 +563,16 @@ dict(solver="lbfgs"), ], }, - GaussianMixture: {"check_dict_unchanged": dict(max_iter=5, n_init=2)}, + GaussianMixture: { + "check_dict_unchanged": dict(max_iter=5, n_init=2), + "check_array_api_input": dict( + max_iter=5, n_init=2, init_params="random_from_data" + ), + }, GaussianRandomProjection: {"check_dict_unchanged": dict(n_components=1)}, + GraphicalLasso: {"check_array_api_input": dict(max_iter=5, alpha=1.0)}, IncrementalPCA: {"check_dict_unchanged": dict(batch_size=10, n_components=1)}, Isomap: {"check_dict_unchanged": dict(n_components=1)}, - KMeans: {"check_dict_unchanged": dict(max_iter=5, n_clusters=1, n_init=2)}, # TODO(1.9) simplify when averaged_inverted_cdf is the default KBinsDiscretizer: { "check_sample_weight_equivalence_on_dense_data": [ @@ -595,7 +604,11 @@ strategy="quantile", quantile_method="averaged_inverted_cdf" ), }, - KernelPCA: {"check_dict_unchanged": dict(n_components=1)}, + KernelPCA: { + "check_dict_unchanged": dict(n_components=1), + "check_array_api_input": dict(fit_inverse_transform=True), + }, + KMeans: {"check_dict_unchanged": dict(max_iter=5, n_clusters=1, n_init=2)}, LassoLars: {"check_non_transformer_estimators_n_iter": dict(alpha=0.0)}, LatentDirichletAllocation: { "check_dict_unchanged": dict(batch_size=10, max_iter=5, n_components=1) @@ -693,6 +706,7 @@ dict(solver="highs-ipm"), ], }, + QuadraticDiscriminantAnalysis: {"check_array_api_input": dict(reg_param=1.0)}, RBFSampler: {"check_dict_unchanged": dict(n_components=1)}, Ridge: { "check_sample_weight_equivalence_on_dense_data": [ @@ -720,7 +734,9 @@ ], }, SkewedChi2Sampler: {"check_dict_unchanged": dict(n_components=1)}, + SimpleImputer: {"check_array_api_input": dict(add_indicator=True)}, SparseCoder: { + "check_array_api_input": dict(dictionary=rng.normal(size=(5, 10))), "check_estimators_dtypes": dict(dictionary=rng.normal(size=(5, 5))), "check_dtype_object": dict(dictionary=rng.normal(size=(5, 10))), "check_transformers_unfitted_stateless": dict( diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index 7fd36041f608a..3d166d875fb6c 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -196,9 +196,11 @@ def _yield_checks(estimator): yield check_estimators_pickle yield partial(check_estimators_pickle, readonly_memmap=True) - if tags.array_api_support: - for check in _yield_array_api_checks(estimator): - yield check + for check in _yield_array_api_checks( + estimator, + only_numpy=not tags.array_api_support, + ): + yield check yield check_f_contiguous_array_estimator @@ -336,18 +338,30 @@ def _yield_outliers_checks(estimator): yield check_non_transformer_estimators_n_iter -def _yield_array_api_checks(estimator): - for ( - array_namespace, - device, - dtype_name, - ) in yield_namespace_device_dtype_combinations(): +def _yield_array_api_checks(estimator, only_numpy=False): + if only_numpy: + # Enabling array API dispatch and using NumPy inputs should not + # change results, even if the estimator does not explicitly support + # array API. yield partial( check_array_api_input, - array_namespace=array_namespace, - dtype_name=dtype_name, - device=device, + array_namespace="numpy", + expect_only_array_outputs=False, ) + else: + # These extended checks should pass for all estimators that declare + # array API support in their tags. + for ( + array_namespace, + device, + dtype_name, + ) in yield_namespace_device_dtype_combinations(): + yield partial( + check_array_api_input, + array_namespace=array_namespace, + dtype_name=dtype_name, + device=device, + ) def _yield_all_checks(estimator, legacy: bool): @@ -1048,6 +1062,7 @@ def check_array_api_input( dtype_name="float64", check_values=False, check_sample_weight=False, + expect_only_array_outputs=True, ): """Check that the estimator can work consistently with the Array API @@ -1057,17 +1072,25 @@ def check_array_api_input( When check_values is True, it also checks that calling the estimator on the array_api Array gives the same results as ndarrays. - When sample_weight is True, dummy sample weights are passed to the fit call. + When check_sample_weight is True, dummy sample weights are passed to the + fit call. + + When expect_only_array_outputs is False, the check is looser: in particular + it accepts non-array outputs such as sparse data structures. This is + useful to test that enabling array API dispatch does not change the + behavior of any estimator fed with NumPy inputs, even for estimators that + do not support array API. """ xp = _array_api_for_tests(array_namespace, device) - X, y = make_classification(random_state=42) + X, y = make_classification(n_samples=30, n_features=10, random_state=42) X = X.astype(dtype_name, copy=False) X = _enforce_estimator_tags_X(estimator_orig, X) y = _enforce_estimator_tags_y(estimator_orig, y) est = clone(estimator_orig) + set_random_state(est) X_xp = xp.asarray(X, device=device) y_xp = xp.asarray(y, device=device) @@ -1193,47 +1216,48 @@ def check_array_api_input( f"got {result_ns}." ) - with config_context(array_api_dispatch=True): - assert array_device(result_xp) == array_device(X_xp) - - result_xp_np = _convert_to_numpy(result_xp, xp=xp) + if expect_only_array_outputs: + with config_context(array_api_dispatch=True): + assert array_device(result_xp) == array_device(X_xp) - if check_values: - assert_allclose( - result, - result_xp_np, - err_msg=f"{method} did not the return the same result", - atol=_atol_for_type(X.dtype), - ) - else: - if hasattr(result, "shape"): + result_xp_np = _convert_to_numpy(result_xp, xp=xp) + if check_values: + assert_allclose( + result, + result_xp_np, + err_msg=f"{method} did not the return the same result", + atol=_atol_for_type(X.dtype), + ) + elif hasattr(result, "shape"): assert result.shape == result_xp_np.shape assert result.dtype == result_xp_np.dtype if method_name == "transform" and hasattr(est, "inverse_transform"): inverse_result = est.inverse_transform(result) with config_context(array_api_dispatch=True): - invese_result_xp = est_xp.inverse_transform(result_xp) - inverse_result_ns = get_namespace(invese_result_xp)[0].__name__ - assert inverse_result_ns == input_ns, ( - "'inverse_transform' output is in wrong namespace, expected" - f" {input_ns}, got {inverse_result_ns}." - ) - - with config_context(array_api_dispatch=True): - assert array_device(invese_result_xp) == array_device(X_xp) - - invese_result_xp_np = _convert_to_numpy(invese_result_xp, xp=xp) - if check_values: - assert_allclose( - inverse_result, - invese_result_xp_np, - err_msg="inverse_transform did not the return the same result", - atol=_atol_for_type(X.dtype), + inverse_result_xp = est_xp.inverse_transform(result_xp) + + if expect_only_array_outputs: + with config_context(array_api_dispatch=True): + inverse_result_ns = get_namespace(inverse_result_xp)[0].__name__ + assert inverse_result_ns == input_ns, ( + "'inverse_transform' output is in wrong namespace, expected" + f" {input_ns}, got {inverse_result_ns}." ) - else: - assert inverse_result.shape == invese_result_xp_np.shape - assert inverse_result.dtype == invese_result_xp_np.dtype + with config_context(array_api_dispatch=True): + assert array_device(result_xp) == array_device(X_xp) + + inverse_result_xp_np = _convert_to_numpy(inverse_result_xp, xp=xp) + if check_values: + assert_allclose( + inverse_result, + inverse_result_xp_np, + err_msg="inverse_transform did not the return the same result", + atol=_atol_for_type(X.dtype), + ) + elif hasattr(result, "shape"): + assert inverse_result.shape == inverse_result_xp_np.shape + assert inverse_result.dtype == inverse_result_xp_np.dtype def check_array_api_input_and_values( diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index a1fc81c109af8..785bb668e9878 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -50,8 +50,8 @@ from sklearn.utils.fixes import _IS_32BIT, CSR_CONTAINERS, np_version, parse_version -@pytest.mark.parametrize("X", [numpy.asarray([1, 2, 3]), [1, 2, 3]]) -def test_get_namespace_ndarray_default(X): +@pytest.mark.parametrize("X", [numpy.asarray([1, 2, 3]), [1, 2, 3], (1, 2, 3)]) +def test_get_namespace_ndarray_or_similar_default(X): """Check that get_namespace returns NumPy wrapper""" xp_out, is_array_api_compliant = get_namespace(X) assert xp_out is np_compat @@ -71,14 +71,13 @@ def test_get_namespace_ndarray_creation_device(): @skip_if_array_api_compat_not_configured -def test_get_namespace_ndarray_with_dispatch(): +@pytest.mark.parametrize("X", [numpy.asarray([1, 2, 3]), [1, 2, 3], (1, 2, 3)]) +def test_get_namespace_ndarray_or_similar_default_with_dispatch(X): """Test get_namespace on NumPy ndarrays.""" - X_np = numpy.asarray([[1, 2, 3]]) - with config_context(array_api_dispatch=True): - xp_out, is_array_api_compliant = get_namespace(X_np) - assert is_array_api_compliant + xp_out, is_array_api_compliant = get_namespace(X) + assert is_array_api_compliant == isinstance(X, numpy.ndarray) # In the future, NumPy should become API compliant library and we should have # assert xp_out is numpy From 8a59044f2b8310a11213399cca06c3a7c42f1948 Mon Sep 17 00:00:00 2001 From: ANAND VENUGOPAL Date: Wed, 7 Jan 2026 15:56:30 +0530 Subject: [PATCH 102/462] DOC: clarify verbose behavior in GridSearchCV and RandomizedSearchCV (#32968) Co-authored-by: Stefanie Senger --- sklearn/model_selection/_search.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/sklearn/model_selection/_search.py b/sklearn/model_selection/_search.py index 362c652b660e9..420df1d79250e 100644 --- a/sklearn/model_selection/_search.py +++ b/sklearn/model_selection/_search.py @@ -1360,14 +1360,15 @@ class GridSearchCV(BaseSearchCV): .. versionchanged:: 0.22 ``cv`` default value if None changed from 3-fold to 5-fold. - verbose : int - Controls the verbosity: the higher, the more messages. + verbose : int, default=0 + Controls the verbosity of information printed during fitting, with higher + values yielding more detailed logging. - - >1 : the computation time for each fold and parameter candidate is - displayed; - - >2 : the score is also displayed; - - >3 : the fold and candidate parameter indexes are also displayed - together with the starting time of the computation. + - 0 : no messages are printed; + - >=1 : summary of the total number of fits; + - >=2 : computation time for each fold and parameter candidate; + - >=3 : fold indices and scores; + - >=10 : parameter candidate indices and START messages before each fit. pre_dispatch : int, or str, default='2*n_jobs' Controls the number of jobs that get dispatched during parallel @@ -1744,14 +1745,15 @@ class RandomizedSearchCV(BaseSearchCV): .. versionchanged:: 0.22 ``cv`` default value if None changed from 3-fold to 5-fold. - verbose : int - Controls the verbosity: the higher, the more messages. + verbose : int, default = 0 + Controls the verbosity of information printed during fitting, with higher + values yielding more detailed logging. - - >1 : the computation time for each fold and parameter candidate is - displayed; - - >2 : the score is also displayed; - - >3 : the fold and candidate parameter indexes are also displayed - together with the starting time of the computation. + - 0 : no messages are printed; + - >=1 : summary of the total number of fits; + - >=2 : computation time for each fold and parameter candidate; + - >=3 : fold indices and scores; + - >=10 : parameter candidate indices and START messages before each fit. pre_dispatch : int, or str, default='2*n_jobs' Controls the number of jobs that get dispatched during parallel From e5aa6efedad6f7e45ab68d25a46c1b5ccc344916 Mon Sep 17 00:00:00 2001 From: Omar Salman Date: Wed, 7 Jan 2026 18:33:42 +0500 Subject: [PATCH 103/462] TST Fix some tests with `global_random_seed` in `test_logistic.py` (#33021) --- sklearn/linear_model/tests/test_logistic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index 81891951a3fa0..22e7458373f99 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -920,14 +920,14 @@ def test_logistic_cv_sparse(global_random_seed, solver, csr_container): n_samples=100, n_features=5, random_state=global_random_seed ) X[X < 0.0] = 0.0 # make it a bit sparse - params = dict(Cs=[1e-1, 1, 1e1], max_iter=10_000, tol=1e-6, random_state=42) + params = dict(Cs=[1e-1, 1, 1e1], max_iter=10_000, tol=1e-7, random_state=42) clf = LogisticRegressionCV(solver=solver, use_legacy_attributes=False, **params) clf.fit(X, y) clfs = LogisticRegressionCV(solver=solver, use_legacy_attributes=False, **params) clfs.fit(csr_container(X), y) - rtol = 5e-2 if solver in ("sag", "saga") else 1e-5 + rtol = 6e-2 if solver in ("sag", "saga") else 1e-5 assert_allclose(clfs.coef_, clf.coef_, rtol=rtol) assert_allclose(clfs.intercept_, clf.intercept_, rtol=rtol) assert clfs.C_ == clf.C_ From aef9c5e8d6e6914fc068f9edec593593a3eb4668 Mon Sep 17 00:00:00 2001 From: Xiao Yuan Date: Wed, 7 Jan 2026 17:27:42 +0200 Subject: [PATCH 104/462] DOC fix link to NNDSVD paper (#32983) --- doc/modules/decomposition.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/modules/decomposition.rst b/doc/modules/decomposition.rst index ebf4302d3ce5b..21e8b73de5b8a 100644 --- a/doc/modules/decomposition.rst +++ b/doc/modules/decomposition.rst @@ -959,7 +959,7 @@ is not readily available from the start, or when the data does not fit into memo .. [4] `"SVD based initialization: A head start for nonnegative matrix factorization" - `_ + `_ C. Boutsidis, E. Gallopoulos, 2008 .. [5] `"Fast local algorithms for large scale nonnegative matrix and tensor From 8455af812e8d8dc27225eff42073f1b8be215502 Mon Sep 17 00:00:00 2001 From: prakritim01 Date: Wed, 7 Jan 2026 21:53:05 +0530 Subject: [PATCH 105/462] DOC Switch insecure http links to https (#32969) Co-authored-by: Prakriti Manhar Co-authored-by: Olivier Grisel Co-authored-by: Lucy Liu --- doc/about.rst | 4 ++-- doc/conf.py | 2 +- doc/developers/contributing.rst | 4 ++-- doc/developers/performance.rst | 2 +- doc/install.rst | 2 +- doc/model_persistence.rst | 4 ++-- doc/modules/clustering.rst | 6 +++--- doc/modules/cross_validation.rst | 2 +- doc/modules/decomposition.rst | 2 +- doc/modules/grid_search.rst | 2 +- doc/modules/linear_model.rst | 4 ++-- doc/modules/model_evaluation.rst | 2 +- doc/modules/svm.rst | 2 +- doc/modules/tree.rst | 2 +- doc/testimonials/testimonials.rst | 12 ++++++------ doc/whats_new/_contributors.rst | 20 ++++++++++---------- doc/whats_new/v0.16.rst | 2 +- doc/whats_new/v0.23.rst | 2 +- 18 files changed, 38 insertions(+), 38 deletions(-) diff --git a/doc/about.rst b/doc/about.rst index 9c45e274c8869..e3b015c5f9fee 100644 --- a/doc/about.rst +++ b/doc/about.rst @@ -385,13 +385,13 @@ program. - 2013 - Kemal Eren, Nicolas Trésegnie - 2014 - Hamzeh Alsalhi, Issam Laradji, Maheshakya Wijewardena, Manoj Kumar - 2015 - `Raghav RV `_, Wei Xue -- 2016 - `Nelson Liu `_, `YenChen Lin `_ +- 2016 - `Nelson Liu `_, `YenChen Lin `_ .. _Vlad Niculae: https://vene.ro/ ................... -The `NeuroDebian `_ project providing `Debian +The `NeuroDebian `_ project providing `Debian `_ packaging and contributions is supported by `Dr. James V. Haxby `_ (`Dartmouth College `_). diff --git a/doc/conf.py b/doc/conf.py index 0a06daa3e9df4..b0bed18209e93 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -910,7 +910,7 @@ def setup(app): r"^..?/", # ignore links to specific pdf pages because linkcheck does not handle them # ('utf-8' codec can't decode byte error) - r"http://www.utstat.toronto.edu/~rsalakhu/sta4273/notes/Lecture2.pdf#page=.*", + r"https://www.utstat.toronto.edu/~rsalakhu/sta4273/notes/Lecture2.pdf#page=.*", ( "https://www.fordfoundation.org/media/2976/roads-and-bridges" "-the-unseen-labor-behind-our-digital-infrastructure.pdf#page=.*" diff --git a/doc/developers/contributing.rst b/doc/developers/contributing.rst index c51d092708862..06f36cc0fe3d5 100644 --- a/doc/developers/contributing.rst +++ b/doc/developers/contributing.rst @@ -358,7 +358,7 @@ line .. topic:: Learning Git The `Git documentation `_ and - http://try.github.io are excellent resources to get started with git, + https://try.github.io are excellent resources to get started with git, and understanding all of the commands shown here. .. _pr_checklist: @@ -508,7 +508,7 @@ profiling and Cython optimizations. For two very well documented and more detailed guides on development workflow, please pay a visit to the `Scipy Development Workflow - `_ - + `_ - and the `Astropy Workflow for Developers `_ sections. diff --git a/doc/developers/performance.rst b/doc/developers/performance.rst index ae2dc9cf7ce9e..89c410fbec6c3 100644 --- a/doc/developers/performance.rst +++ b/doc/developers/performance.rst @@ -311,7 +311,7 @@ standalone function in a ``.pyx`` file, add static type declarations and then use Cython to generate a C program suitable to be compiled as a Python extension module. -The `Cython's documentation `_ contains a tutorial and +The `Cython's documentation `_ contains a tutorial and reference guide for developing such a module. For more information about developing in Cython for scikit-learn, see :ref:`cython`. diff --git a/doc/install.rst b/doc/install.rst index 7d03be12cf42c..e8832660d2343 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -295,7 +295,7 @@ It can be installed using ``dnf``: NetBSD ------ -scikit-learn is available via `pkgsrc-wip `_: +scikit-learn is available via `pkgsrc-wip `_: https://pkgsrc.se/math/py-scikit-learn diff --git a/doc/model_persistence.rst b/doc/model_persistence.rst index 21d6934a48730..af1b455660562 100644 --- a/doc/model_persistence.rst +++ b/doc/model_persistence.rst @@ -149,7 +149,7 @@ facilitate the conversion of the data models between different machine learning frameworks, and to improve their portability on different computing architectures. More details are available from the `ONNX tutorial `__. To convert scikit-learn model to `ONNX` -`sklearn-onnx `__ has been developed. However, +`sklearn-onnx `__ has been developed. However, not all scikit-learn models are supported, and it is limited to the core scikit-learn and does not support most third party estimators. One can write a custom converter for third party or custom estimators, but the documentation to @@ -159,7 +159,7 @@ do that is sparse and it might be challenging to do so. To convert the model to `ONNX` format, you need to give the converter some information about the input as well, about which you can read more `here - `__:: + `__:: from skl2onnx import to_onnx onx = to_onnx(clf, X[:1].astype(numpy.float32), target_opset=12) diff --git a/doc/modules/clustering.rst b/doc/modules/clustering.rst index 3bc4991733d5f..45ea46155de74 100644 --- a/doc/modules/clustering.rst +++ b/doc/modules/clustering.rst @@ -847,7 +847,7 @@ clusters from Bisecting K-Means are well ordered and create quite a visible hier .. dropdown:: References * `"A Comparison of Document Clustering Techniques" - `_ Michael + `_ Michael Steinbach, George Karypis and Vipin Kumar, Department of Computer Science and Egineering, University of Minnesota (June 2000) * `"Performance Analysis of K-Means and Bisecting K-Means Algorithms in Weblog @@ -1584,7 +1584,7 @@ Bad (e.g. independent labelings) have non-positive scores:: * Strehl, Alexander, and Joydeep Ghosh (2002). "Cluster ensembles - a knowledge reuse framework for combining multiple partitions". Journal of Machine Learning Research 3: 583-617. `doi:10.1162/153244303321897735 - `_. + `_. * `Wikipedia entry for the (normalized) Mutual Information `_ @@ -1769,7 +1769,7 @@ homogeneous but not complete:: Hirschberg, 2007 .. [B2011] `Identification and Characterization of Events in Social Media - `_, Hila + `_, Hila Becker, PhD Thesis. diff --git a/doc/modules/cross_validation.rst b/doc/modules/cross_validation.rst index b1c9ccec8f641..24478cf7ecf5f 100644 --- a/doc/modules/cross_validation.rst +++ b/doc/modules/cross_validation.rst @@ -1022,5 +1022,5 @@ computation and thus speeds it up. .. dropdown:: References * Ojala and Garriga. `Permutation Tests for Studying Classifier Performance - `_. + `_. J. Mach. Learn. Res. 2010. diff --git a/doc/modules/decomposition.rst b/doc/modules/decomposition.rst index 21e8b73de5b8a..2b062154a544b 100644 --- a/doc/modules/decomposition.rst +++ b/doc/modules/decomposition.rst @@ -950,7 +950,7 @@ is not readily available from the start, or when the data does not fit into memo .. rubric:: References .. [1] `"Learning the parts of objects by non-negative matrix factorization" - `_ + `_ D. Lee, S. Seung, 1999 .. [2] `"Non-negative Matrix Factorization with Sparseness Constraints" diff --git a/doc/modules/grid_search.rst b/doc/modules/grid_search.rst index edb915b193e37..9e71e62e5fbf0 100644 --- a/doc/modules/grid_search.rst +++ b/doc/modules/grid_search.rst @@ -536,7 +536,7 @@ additional information related to the successive halving process. .. [1] K. Jamieson, A. Talwalkar, `Non-stochastic Best Arm Identification and Hyperparameter - Optimization `_, in + Optimization `_, in proc. of Machine Learning Research, 2016. .. [2] L. Li, K. Jamieson, G. DeSalvo, A. Rostamizadeh, A. Talwalkar, diff --git a/doc/modules/linear_model.rst b/doc/modules/linear_model.rst index 0d66074ff2e62..242f2fb5515b9 100644 --- a/doc/modules/linear_model.rst +++ b/doc/modules/linear_model.rst @@ -1448,7 +1448,7 @@ eta0=1.0)` can be used for PA-I or with ``learning_rate="pa2"`` for PA-II. .. dropdown:: References * `"Online Passive-Aggressive Algorithms" - `_ + `_ K. Crammer, O. Dekel, J. Keshat, S. Shalev-Shwartz, Y. Singer - JMLR 7 (2006) Robustness regression: outliers and modeling errors @@ -1655,7 +1655,7 @@ better than an ordinary least squares in high dimension. .. [#f1] Xin Dang, Hanxiang Peng, Xueqin Wang and Heping Zhang: `Theil-Sen Estimators in a Multiple Linear Regression Model. `_ - .. [#f2] T. Kärkkäinen and S. Äyrämö: `On Computation of Spatial Median for Robust Data Mining. `_ + .. [#f2] T. Kärkkäinen and S. Äyrämö: `On Computation of Spatial Median for Robust Data Mining. `_ Also see the `Wikipedia page `_ diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index 922eb3a752c79..86e46d562db26 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -2009,7 +2009,7 @@ the same does a lower Brier score loss always mean better calibration" .. [Bella2012] Bella, Ferri, Hernández-Orallo, and Ramírez-Quintana `"Calibration of Machine Learning Models" - `_ + `_ in Khosrow-Pour, M. "Machine learning: concepts, methodologies, tools and applications." Hershey, PA: Information Science Reference (2012). diff --git a/doc/modules/svm.rst b/doc/modules/svm.rst index dc912a289ed46..3518962603ab1 100644 --- a/doc/modules/svm.rst +++ b/doc/modules/svm.rst @@ -813,4 +813,4 @@ used, please refer to their respective papers. .. [#8] Crammer and Singer `On the Algorithmic Implementation of Multiclass Kernel-based Vector Machines - `_, JMLR 2001. + `_, JMLR 2001. diff --git a/doc/modules/tree.rst b/doc/modules/tree.rst index 5ebc7b0e398e6..756d1305c19ef 100644 --- a/doc/modules/tree.rst +++ b/doc/modules/tree.rst @@ -310,7 +310,7 @@ the lower half of those faces. * M. Dumont et al, `Fast multi-class image annotation with random subwindows and multiple output randomized trees - `_, + `_, International Conference on Computer Vision Theory and Applications 2009 .. _tree_complexity: diff --git a/doc/testimonials/testimonials.rst b/doc/testimonials/testimonials.rst index 3c8c15b2e25ee..dca5d71515718 100644 --- a/doc/testimonials/testimonials.rst +++ b/doc/testimonials/testimonials.rst @@ -390,8 +390,8 @@ Who is using scikit-learn? :target: https://www.phimeca.com/?lang=en -`HowAboutWe `_ ------------------------------------------- +`HowAboutWe `_ +------------------------------------------- .. div:: sk-text-image-grid-large @@ -413,7 +413,7 @@ Who is using scikit-learn? .. div:: image-box .. image:: images/howaboutwe.png - :target: http://www.howaboutwe.com/ + :target: https://www.howaboutwe.com/ `PeerIndex `_ @@ -598,8 +598,8 @@ Who is using scikit-learn? :target: https://www.solidodesign.com/ -`INFONEA `_ ---------------------------------------- +`INFONEA `_ +---------------------------------------- .. div:: sk-text-image-grid-large @@ -620,7 +620,7 @@ Who is using scikit-learn? .. div:: image-box .. image:: images/infonea.jpg - :target: http://www.infonea.com/en/ + :target: https://www.infonea.com/en/ `Dataiku `_ diff --git a/doc/whats_new/_contributors.rst b/doc/whats_new/_contributors.rst index c74a2964e57bc..da23c137b194a 100644 --- a/doc/whats_new/_contributors.rst +++ b/doc/whats_new/_contributors.rst @@ -22,11 +22,11 @@ .. _Olivier Grisel: https://bsky.app/profile/ogrisel.bsky.social -.. _Gael Varoquaux: http://gael-varoquaux.info +.. _Gael Varoquaux: https://gael-varoquaux.info -.. _Alexandre Gramfort: http://alexandre.gramfort.net +.. _Alexandre Gramfort: https://alexandre.gramfort.net -.. _Fabian Pedregosa: http://fa.bianp.net +.. _Fabian Pedregosa: https://fa.bianp.net .. _Mathieu Blondel: http://www.mblondel.org @@ -42,7 +42,7 @@ .. _Peter Prettenhofer: https://sites.google.com/site/peterprettenhofer/ -.. _Alexandre Passos: http://atpassos.me +.. _Alexandre Passos: https://atpassos.me .. _Nicolas Pinto: https://twitter.com/npinto @@ -54,7 +54,7 @@ .. _Jake Vanderplas: https://staff.washington.edu/jakevdp/ -.. _Gilles Louppe: http://www.montefiore.ulg.ac.be/~glouppe/ +.. _Gilles Louppe: https://www.montefiore.ulg.ac.be/~glouppe/ .. _INRIA: https://www.inria.fr/ @@ -90,13 +90,13 @@ .. _Kyle Kastner: https://kastnerkyle.github.io/ -.. _Daniel Nouri: http://danielnouri.org +.. _Daniel Nouri: https://danielnouri.org .. _Manoj Kumar: https://manojbits.wordpress.com -.. _Luis Pedro Coelho: http://luispedro.org +.. _Luis Pedro Coelho: https://luispedro.org -.. _Fares Hedyati: http://www.eecs.berkeley.edu/~fareshed +.. _Fares Hedyati: https://www.eecs.berkeley.edu/~fareshed .. _Antony Lee: https://www.ocf.berkeley.edu/~antonyl/ @@ -104,7 +104,7 @@ .. _Matteo Visconti di Oleggio Castello: http://www.mvdoc.me -.. _Trevor Stephens: http://trevorstephens.com/ +.. _Trevor Stephens: https://trevorstephens.com/ .. _Jan Hendrik Metzen: https://jmetzen.github.io/ @@ -156,7 +156,7 @@ .. _Vincent Pham: https://github.com/vincentpham1991 -.. _Denis Engemann: http://denis-engemann.de +.. _Denis Engemann: https://denis-engemann.de .. _Anish Shah: https://github.com/AnishShah diff --git a/doc/whats_new/v0.16.rst b/doc/whats_new/v0.16.rst index b5656d3bff64c..4296b0cd8b9fd 100644 --- a/doc/whats_new/v0.16.rst +++ b/doc/whats_new/v0.16.rst @@ -414,7 +414,7 @@ Bug fixes - Fixed handling of ties in :class:`isotonic.IsotonicRegression`. We now use the weighted average of targets (secondary method). By - `Andreas Müller`_ and `Michael Bommarito `_. + `Andreas Müller`_ and `Michael Bommarito `_. API changes summary ------------------- diff --git a/doc/whats_new/v0.23.rst b/doc/whats_new/v0.23.rst index 379fa7adfe7aa..8983bbc9db52e 100644 --- a/doc/whats_new/v0.23.rst +++ b/doc/whats_new/v0.23.rst @@ -708,7 +708,7 @@ Changelog generates 31bits/63bits random numbers on all platforms. In addition, the crude "modulo" postprocessor used to get a random number in a bounded interval was replaced by the tweaked Lemire method as suggested by `this blog - post `_. + post `_. Any model using the `svm.libsvm` or the `svm.liblinear` solver, including :class:`svm.LinearSVC`, :class:`svm.LinearSVR`, :class:`svm.NuSVC`, :class:`svm.NuSVR`, :class:`svm.OneClassSVM`, From 131cc425fdf4d93f86dddbf0a0434750f0fd11ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= Date: Thu, 8 Jan 2026 07:09:46 +0100 Subject: [PATCH 106/462] MAINT Remove CSS template substitution in estimators' HTML Display (#32839) --- sklearn/utils/_repr_html/estimator.css | 90 +++++++++++++------------- sklearn/utils/_repr_html/estimator.py | 12 ++-- 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/sklearn/utils/_repr_html/estimator.css b/sklearn/utils/_repr_html/estimator.css index 41d39aee91cf3..75f55ce1499d8 100644 --- a/sklearn/utils/_repr_html/estimator.css +++ b/sklearn/utils/_repr_html/estimator.css @@ -1,4 +1,4 @@ -#$id { +.sk-global { /* Definition of color scheme common for light and dark mode */ --sklearn-color-text: #000; --sklearn-color-text-muted: #666; @@ -15,7 +15,7 @@ --sklearn-color-fitted-level-3: cornflowerblue; } -#$id.light { +.sk-global.light { /* Specific color for light theme */ --sklearn-color-text-on-default-background: black; --sklearn-color-background: white; @@ -23,22 +23,22 @@ --sklearn-color-icon: #696969; } -#$id.dark { +.sk-global.dark { --sklearn-color-text-on-default-background: white; --sklearn-color-background: #111; --sklearn-color-border-box: white; --sklearn-color-icon: #878787; } -#$id { +.sk-global { color: var(--sklearn-color-text); } -#$id pre { +.sk-global pre { padding: 0; } -#$id input.sk-hidden--visually { +.sk-global input.sk-hidden--visually { border: 0; clip: rect(1px 1px 1px 1px); clip: rect(1px, 1px, 1px, 1px); @@ -50,7 +50,7 @@ width: 1px; } -#$id div.sk-dashed-wrapped { +.sk-global div.sk-dashed-wrapped { border: 1px dashed var(--sklearn-color-line); margin: 0 0.4em 0.5em 0.4em; box-sizing: border-box; @@ -58,7 +58,7 @@ background-color: var(--sklearn-color-background); } -#$id div.sk-container { +.sk-global div.sk-container { /* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the @@ -68,7 +68,7 @@ position: relative; } -#$id div.sk-text-repr-fallback { +.sk-global div.sk-text-repr-fallback { display: none; } @@ -84,14 +84,14 @@ div.sk-item { /* Parallel-specific style estimator block */ -#$id div.sk-parallel-item::after { +.sk-global div.sk-parallel-item::after { content: ""; width: 100%; border-bottom: 2px solid var(--sklearn-color-text-on-default-background); flex-grow: 1; } -#$id div.sk-parallel { +.sk-global div.sk-parallel { display: flex; align-items: stretch; justify-content: center; @@ -99,28 +99,28 @@ div.sk-item { position: relative; } -#$id div.sk-parallel-item { +.sk-global div.sk-parallel-item { display: flex; flex-direction: column; } -#$id div.sk-parallel-item:first-child::after { +.sk-global div.sk-parallel-item:first-child::after { align-self: flex-end; width: 50%; } -#$id div.sk-parallel-item:last-child::after { +.sk-global div.sk-parallel-item:last-child::after { align-self: flex-start; width: 50%; } -#$id div.sk-parallel-item:only-child::after { +.sk-global div.sk-parallel-item:only-child::after { width: 0; } /* Serial-specific style estimator block */ -#$id div.sk-serial { +.sk-global div.sk-serial { display: flex; flex-direction: column; align-items: center; @@ -138,14 +138,14 @@ clickable and can be expanded/collapsed. /* Pipeline and ColumnTransformer style (default) */ -#$id div.sk-toggleable { +.sk-global div.sk-toggleable { /* Default theme specific background. It is overwritten whether we have a specific estimator or a Pipeline/ColumnTransformer */ background-color: var(--sklearn-color-background); } /* Toggleable label */ -#$id label.sk-toggleable__label { +.sk-global label.sk-toggleable__label { cursor: pointer; display: flex; width: 100%; @@ -158,13 +158,13 @@ clickable and can be expanded/collapsed. gap: 0.5em; } -#$id label.sk-toggleable__label .caption { +.sk-global label.sk-toggleable__label .caption { font-size: 0.6rem; font-weight: lighter; color: var(--sklearn-color-text-muted); } -#$id label.sk-toggleable__label-arrow:before { +.sk-global label.sk-toggleable__label-arrow:before { /* Arrow on the left of the label */ content: "▸"; float: left; @@ -172,25 +172,25 @@ clickable and can be expanded/collapsed. color: var(--sklearn-color-icon); } -#$id label.sk-toggleable__label-arrow:hover:before { +.sk-global label.sk-toggleable__label-arrow:hover:before { color: var(--sklearn-color-text); } /* Toggleable content - dropdown */ -#$id div.sk-toggleable__content { +.sk-global div.sk-toggleable__content { display: none; text-align: left; /* unfitted */ background-color: var(--sklearn-color-unfitted-level-0); } -#$id div.sk-toggleable__content.fitted { +.sk-global div.sk-toggleable__content.fitted { /* fitted */ background-color: var(--sklearn-color-fitted-level-0); } -#$id div.sk-toggleable__content pre { +.sk-global div.sk-toggleable__content pre { margin: 0.2em; border-radius: 0.25em; color: var(--sklearn-color-text); @@ -198,78 +198,78 @@ clickable and can be expanded/collapsed. background-color: var(--sklearn-color-unfitted-level-0); } -#$id div.sk-toggleable__content.fitted pre { +.sk-global div.sk-toggleable__content.fitted pre { /* unfitted */ background-color: var(--sklearn-color-fitted-level-0); } -#$id input.sk-toggleable__control:checked~div.sk-toggleable__content { +.sk-global input.sk-toggleable__control:checked~div.sk-toggleable__content { /* Expand drop-down */ display: block; width: 100%; overflow: visible; } -#$id input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before { +.sk-global input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before { content: "▾"; } /* Pipeline/ColumnTransformer-specific style */ -#$id div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label { +.sk-global div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label { color: var(--sklearn-color-text); background-color: var(--sklearn-color-unfitted-level-2); } -#$id div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label { +.sk-global div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label { background-color: var(--sklearn-color-fitted-level-2); } /* Estimator-specific style */ /* Colorize estimator box */ -#$id div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label { +.sk-global div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label { /* unfitted */ background-color: var(--sklearn-color-unfitted-level-2); } -#$id div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label { +.sk-global div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label { /* fitted */ background-color: var(--sklearn-color-fitted-level-2); } -#$id div.sk-label label.sk-toggleable__label, -#$id div.sk-label label { +.sk-global div.sk-label label.sk-toggleable__label, +.sk-global div.sk-label label { /* The background is the default theme color */ color: var(--sklearn-color-text-on-default-background); } /* On hover, darken the color of the background */ -#$id div.sk-label:hover label.sk-toggleable__label { +.sk-global div.sk-label:hover label.sk-toggleable__label { color: var(--sklearn-color-text); background-color: var(--sklearn-color-unfitted-level-2); } /* Label box, darken color on hover, fitted */ -#$id div.sk-label.fitted:hover label.sk-toggleable__label.fitted { +.sk-global div.sk-label.fitted:hover label.sk-toggleable__label.fitted { color: var(--sklearn-color-text); background-color: var(--sklearn-color-fitted-level-2); } /* Estimator label */ -#$id div.sk-label label { +.sk-global div.sk-label label { font-family: monospace; font-weight: bold; line-height: 1.2em; } -#$id div.sk-label-container { +.sk-global div.sk-label-container { text-align: center; } /* Estimator-specific */ -#$id div.sk-estimator { +.sk-global div.sk-estimator { font-family: monospace; border: 1px dotted var(--sklearn-color-border-box); border-radius: 0.25em; @@ -279,18 +279,18 @@ clickable and can be expanded/collapsed. background-color: var(--sklearn-color-unfitted-level-0); } -#$id div.sk-estimator.fitted { +.sk-global div.sk-estimator.fitted { /* fitted */ background-color: var(--sklearn-color-fitted-level-0); } /* on hover */ -#$id div.sk-estimator:hover { +.sk-global div.sk-estimator:hover { /* unfitted */ background-color: var(--sklearn-color-unfitted-level-2); } -#$id div.sk-estimator.fitted:hover { +.sk-global div.sk-estimator.fitted:hover { /* fitted */ background-color: var(--sklearn-color-fitted-level-2); } @@ -381,7 +381,7 @@ div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover, /* "?"-specific style due to the `` HTML tag */ -#$id a.estimator_doc_link { +.sk-global a.estimator_doc_link { float: right; font-size: 1rem; line-height: 1em; @@ -396,7 +396,7 @@ div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover, border: var(--sklearn-color-unfitted-level-1) 1pt solid; } -#$id a.estimator_doc_link.fitted { +.sk-global a.estimator_doc_link.fitted { /* fitted */ background-color: var(--sklearn-color-fitted-level-0); border: var(--sklearn-color-fitted-level-1) 1pt solid; @@ -404,14 +404,14 @@ div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover, } /* On hover */ -#$id a.estimator_doc_link:hover { +.sk-global a.estimator_doc_link:hover { /* unfitted */ background-color: var(--sklearn-color-unfitted-level-3); color: var(--sklearn-color-background); text-decoration: none; } -#$id a.estimator_doc_link.fitted:hover { +.sk-global a.estimator_doc_link.fitted:hover { /* fitted */ background-color: var(--sklearn-color-fitted-level-3); } diff --git a/sklearn/utils/_repr_html/estimator.py b/sklearn/utils/_repr_html/estimator.py index d3d86e69def13..d8d8df5153d45 100644 --- a/sklearn/utils/_repr_html/estimator.py +++ b/sklearn/utils/_repr_html/estimator.py @@ -6,7 +6,6 @@ from inspect import isclass from io import StringIO from pathlib import Path -from string import Template from sklearn import config_context @@ -207,7 +206,8 @@ def _write_label_html( ) fmt_str = ( - f'{label_html}
' @@ -433,7 +433,7 @@ def estimator_html_repr(estimator): >>> from sklearn.utils._repr_html.estimator import estimator_html_repr >>> from sklearn.linear_model import LogisticRegression >>> estimator_html_repr(LogisticRegression()) - '" + f"" f"" - f'
' + f'
' '
' f"
{html.escape(estimator_str)}
{fallback_msg}" "
" From 017c91d7cb9f8aeb21bc8640e0d5dd0be5e9af56 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Thu, 8 Jan 2026 10:15:02 +0100 Subject: [PATCH 107/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#32902) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lock file bot Co-authored-by: Olivier Grisel Co-authored-by: Loïc Estève --- .circleci/config.yml | 1 + build_tools/azure/debian_32bit_lock.txt | 8 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 132 ++++++------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 42 ++--- .../pylatest_conda_forge_osx-arm64_conda.lock | 86 ++++----- ...st_pip_openblas_pandas_linux-64_conda.lock | 59 +++--- ...nblas_min_dependencies_linux-64_conda.lock | 78 ++++---- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 69 +++---- ...min_conda_forge_openblas_win-64_conda.lock | 72 +++---- build_tools/azure/ubuntu_atlas_lock.txt | 2 +- build_tools/circle/doc_linux-64_conda.lock | 177 +++++++++--------- .../doc_min_dependencies_linux-64_conda.lock | 151 ++++++++------- ...n_conda_forge_arm_linux-aarch64_conda.lock | 96 +++++----- 13 files changed, 484 insertions(+), 489 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8e9f19b5c6878..aa696d06d66ec 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -57,6 +57,7 @@ jobs: doc: docker: - image: cimg/base:current-22.04 + resource_class: medium+ environment: - MKL_NUM_THREADS: 2 - OPENBLAS_NUM_THREADS: 2 diff --git a/build_tools/azure/debian_32bit_lock.txt b/build_tools/azure/debian_32bit_lock.txt index 69fff8cc96d64..650347404e90c 100644 --- a/build_tools/azure/debian_32bit_lock.txt +++ b/build_tools/azure/debian_32bit_lock.txt @@ -4,17 +4,17 @@ # # pip-compile --output-file=build_tools/azure/debian_32bit_lock.txt build_tools/azure/debian_32bit_requirements.txt # -coverage[toml]==7.12.0 +coverage[toml]==7.13.1 # via pytest-cov -cython==3.2.2 +cython==3.2.4 # via -r build_tools/azure/debian_32bit_requirements.txt execnet==2.1.2 # via pytest-xdist iniconfig==2.3.0 # via pytest -joblib==1.5.2 +joblib==1.5.3 # via -r build_tools/azure/debian_32bit_requirements.txt -meson==1.9.2 +meson==1.10.0 # via meson-python meson-python==0.18.0 # via -r build_tools/azure/debian_32bit_requirements.txt diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index 2fe48c0e7538e..2c1b12f33034e 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -11,36 +11,36 @@ https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_46 https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.7-h4922eb0_0.conda#ec29f865968a81e1961b3c2f2765eebb +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc -https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda#f7f0d6cc2dc986d42ac2689ec88192be +https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.2-hfe17d71_0.conda#5641725dfad698909ec71dac80d16736 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 @@ -54,7 +54,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.13-h2c9d079_1.cond https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h8b1a151_9.conda#f7ec84186dfe7a9e3a9f9e5a4d023e75 https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h8b1a151_4.conda#c7e3e08b7b1b285524ab9d74162ce40b https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h8b1a151_5.conda#68da5b56dde41e172b7b24f071c4b392 -https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda#bfd56492d8346d669010eccafe0ba058 +https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717_0.conda#dbe3ec0f120af456b3477743ffd99b74 https://conda.anaconda.org/conda-forge/linux-64/fmt-12.0.0-h2b0788b_0.conda#d90bf58b03d9a958cb4f9d3de539af17 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d @@ -66,18 +66,18 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_1.conda#ad1fd565aff83b543d726382c0ab0af2 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 -https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda#7fa07cb0fb1b625a089ccc01218ee5b1 +https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 -https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 +https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.2-he8a4886_1.conda#bade189a194e66b93c03021bd36c337b https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd @@ -85,7 +85,7 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.con https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-hdaf4b65_5.conda#132e8f8f40f0ffc0bbde12bb4e8dd1a1 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 @@ -93,13 +93,13 @@ https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff86 https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 -https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_2.conda#94cb88daa0892171457d9fdc69f43eca +https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_4.conda#07479fc04ba3ddd5d9f760ef1635cfa7 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h7b12aa8_0.conda#a30848ebf39327ea078cf26d114cff53 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 @@ -116,13 +116,13 @@ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.con https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_0.conda#01e149d4a53185622dc2e788281961f2 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_1.conda#117499f93e892ea1e57fdca16c2e8351 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 -https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.9.0-heeeca48_0.conda#8a2a73951c1ea275e76fb1b92d97ff3e +https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.12.0-h36edbcc_0.conda#adc6bd7e0e0ccd769227344712e80b28 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.1-hd747db4_0.conda#ddab8b2af55b88d63469c040377bd37e https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e @@ -132,20 +132,20 @@ https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.1-hef928c7_8.conda#bf749bed7435c6ed446de490d48e0444 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.3-hef928c7_0.conda#bdd464b33f6540ed70845b946c11a7b8 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-hc63082f_11.conda#6a653aefdc5d83a4f959869d1759e6e3 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda#1d4e0d37da5f3c22ecd44033f673feba -https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.2.0-py313h18e8e13_0.conda#ab79cf30dea6ef4d1ab2623c5ac5601b +https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py313h18e8e13_0.conda#d9e90792551a527200637e23a915dd79 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda#6c4d3597cf43f3439a51b2b13e29a4ba https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py313hc80a56d_0.conda#a14fa0e1f58e2fce8d6fddf8f54ed500 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda#66b8b26023b8efdf8fcb23bac4b6325d +https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.2-pyhd8ed1ab_0.conda#7e7cf4d6c2be6991e6ae2b3f4331701c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.12.0-pyhd8ed1ab_0.conda#a3b9510e2491c20c7fc0f5e730227fbb https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.0-py313h7033f15_0.conda#2b1cf80423628afd34b4c66b767d7f6b @@ -158,23 +158,23 @@ https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda#ff63bb12ac31c176ff257e3289f20770 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/networkx-3.6-pyhcf101f3_0.conda#6725bfdf8ea7a8bf6415f096f3f1ffa5 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py313h80991f8_2.conda#37ca27d2f726f29a068230d8f6917ce4 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py313h80991f8_0.conda#183fe6b9e99e5c2b464c1573ec78eac8 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/linux-64/playwright-1.57.0-h5585027_0.conda#0a2e773b5c3f67325d1733d2b7ca0ffb https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 @@ -182,7 +182,7 @@ https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.co https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py313h07c4f96_2.conda#7824f18e343d1f846dcde7b23c9bf31a +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py313h07c4f96_0.conda#82da2dcf1ea3e298f2557b50459809e0 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 @@ -191,20 +191,20 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.2-h0019752_1.conda#d99c84b6cd98789b8d5b0ad1aed5de0a +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.3-h06ab39a_1.conda#3689a4290319587e3b54a4f9e68f70c8 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda#4e921d9c85e6559c60215497978b3cdb https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.11.0-h3d7a050_1.conda#89985ba2a3742f34be6aafd6a8f3af8c -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.12.0-py313h3dea7bd_0.conda#8ef99d298907bfd688a95cc714662ae7 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.1-py313h3dea7bd_0.conda#82315acb438e857f809f556e2dcdb822 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py313h3dea7bd_0.conda#92f09729a821c52943d4b0b3749a2380 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py313h3dea7bd_0.conda#c0f36dfbb130da4f6ce2df31f6b25ea8 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_hafda6a7_1003.conda#4fe840c6d6b3719b4231ed89d389bb17 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.7-hf7376ad_0.conda#27dc1a582b442f24979f2a28641fe478 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 @@ -219,54 +219,54 @@ https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1. https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.2-h2a9d012_5.conda#7dcf545d2a6bef32015633c5e18bbaf1 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.4-h8824e59_0.conda#113b9d9913280474c0868b0e290c0326 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.15.0-h2a74896_1.conda#ffd553ff98ce5d74d3d89ac269153149 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_1.conda#d3042ebdaacc689fd1daa701885fc96c -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_1.conda#66508e5f84c3dc9af1a0a62694325ef2 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_3.conda#b450493426793d5fe7d8216a27120050 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_3.conda#ee42c44c3676cdbb6e63190077ca57d3 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 -https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.56.0-pyhcf101f3_0.conda#d0753cdc3baeacf68e697f457749a58b -https://conda.anaconda.org/conda-forge/noarch/pytest-8.4.2-pyhcf101f3_1.conda#da0c42269086f5170e2b296878ec13a6 +https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.57.0-pyhcf101f3_0.conda#a61bfabd06f24469454086deb7f8166e +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.0-pyhd8ed1ab_0.conda#de7372f43e63ff0876b4023b79b55e95 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-hf38915e_8.conda#af98ca0cb5bc454e249872270084e9aa +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.2-pyhd8ed1ab_0.conda#4949ca7b83065cfe94ebe320aece8c72 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10.conda#937d1d4c233adc6eeb2ac3d6e9a73e53 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.13.0-hf38f1be_1.conda#f10b9303c7239fbce3580a60a92bcf97 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.35.2-py310hffdcd12_0.conda#2b90c3aaf73a5b6028b068cf3c76e0b7 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda#af35229f34c80dcfab5a40414440df23 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-h773bc41_4_cpu.conda#9d89be0b1ca8be7eedf821a365926338 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-4_h5875eb1_mkl.conda#bd1a86e560c3b26961279ef6b6e8d45f +https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-hb6ed5f4_6_cpu.conda#fbaa3742ccca0f7096216c0832137b72 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 -https://conda.anaconda.org/conda-forge/noarch/polars-1.35.2-pyh6a1acc5_0.conda#24e8f78d79881b3c035f89f4b83c565c +https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda#160b41862a43936cbe509d1879d67f54 https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.3-h5c1c036_1.conda#762af6d08fdfa7a45346b1466740bacd -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-22.0.0-h8c2c5c3_4_cpu.conda#fdecd3d6168561098fa87d767de05171 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-4_hfef963f_mkl.conda#41f4f9428b9d92b1b06f1fff80a2674d -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-4_h5e43f62_mkl.conda#f647e3368af2453546812658b5393901 -https://conda.anaconda.org/conda-forge/linux-64/libparquet-22.0.0-h7376487_4_cpu.conda#5e9383b1d25179787aff71aaad8208aa -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.3-py313h85046ba_1.conda#bb7ac52bfa917611096023598a7df152 -https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_0.conda#e6475f566489789e65ebd5544db36b3e -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-22.0.0-h635bf11_4_cpu.conda#20f1a4625bce6e9b41e01232895450d9 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-4_hdba1596_mkl.conda#f0b31cc6189ebd85a2e16b15de09850b +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-h6f76662_3.conda#f134a496ef494f2b6c5a26e5d739acc6 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-22.0.0-h8c2c5c3_6_cpu.conda#d2cd924b5f451a7c258001cb1c14155d +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 +https://conda.anaconda.org/conda-forge/linux-64/libparquet-22.0.0-h7376487_6_cpu.conda#83fd8f55f38ac972947c9eca12dc4657 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py313h85046ba_0.conda#2c5d21d466ef1ff0c0a98cfdbaf5c64b +https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-22.0.0-h635bf11_6_cpu.conda#5a8f878ca313083960ab819a009848b3 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.9.1-cpu_mkl_hf3ca1bf_101.conda#5ef08e134f6dfcf431732cb0db6f877d -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py313hf6604e3_0.conda#15f43bcd12c90186e78801fafc53d89b +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py313hf6604e3_0.conda#07963f5dbb5351201035e1f8815ed8da https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-22.0.0-py313he109ebe_0_cpu.conda#0b4a0a9ab270b275eb6da8671edb9458 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-4_hcf00494_mkl.conda#7f7c616ec25c252749fa4945ea1db3fd +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda#6186382cb34a9953bf2a18fc763dc346 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-22.0.0-h635bf11_4_cpu.conda#6389644214f7707ab05f17f464863ed3 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-22.0.0-h635bf11_6_cpu.conda#579bdb829ab093d048e49a289d3c9883 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_2.conda#8a69ea71fdd37bfe42a28f0967dbb75a https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.9.1-cpu_mkl_py313_h5a1586b_101.conda#48b128d28e7849060753d14a5f249f27 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h11c21cd_1.conda#26b089b9e5fcdcdca714b01f8008d808 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.0.1-pyhe01879c_0.conda#303ec962addf1b6016afd536e9db6bc6 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.304-mkl.conda#adbc1b7f2e7acf80f45bd6592f88f0ae -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-22.0.0-h3f74fd7_4_cpu.conda#6f07bf204431fb87d8f827807d752662 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-22.0.0-h3f74fd7_6_cpu.conda#cfc7d2c5a81eb6de3100661a69de5f3d https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.9.1-cpu_mkl_hd61e0f4_101.conda#d053f5fbadaf26fcb23a7acb2b0e21e6 diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index b497327c72150..ad90866891c34 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -4,12 +4,12 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/osx-64/mkl-include-2023.2.0-h694c41f_50502.conda#f394610725ab086080230c5d8fd96cd4 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda#97c4b3bd8a90722104798175a1bdddbf -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/osx-64/icu-75.1-h120a0e1_0.conda#d68d48a3060eb5abdc1cdc8e2a3a5966 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/osx-64/icu-78.1-h14c5de8_0.conda#1e648e0c6657a29dc44102d6e3b10ebc https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 -https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.7-h3d58e20_0.conda#67c086bf0efc67b54a235dd9184bd7a2 +https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.8-h3d58e20_0.conda#9f8a60a77ecafb7966ca961c94f33bd1 https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda#222e0732a1d0780a622926265bee14ef https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda#d214916b24c625bcc459b245d509f22e @@ -19,7 +19,7 @@ https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda#846 https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda#18b81186a6adb43f000ad19ed7b70381 https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda#7bb6608cf1f83578587297a158a6630b https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda#003a54a4e32b02f7355b50a837e699da -https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.7-h472b3d1_0.conda#c9f0fc88c8f46637392b95bef78dc036 +https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.8-h472b3d1_0.conda#e2d811e9f464dd67398b4ce1f9c7c872 https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda#ced34dd9929f491ca6dab6a2927aff25 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda#47f1b8b4a76ebd0cd22bd7153e54a4dc @@ -29,26 +29,26 @@ https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda#21f765 https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda#63186ac7a8a24b3528b4b14f21c03f54 https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.53-h380d223_0.conda#0cdbbd56f660997cfe5d33e516afac2f -https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.1-h6cc646a_0.conda#f71213ed0c51030cb17a77fc60a757f1 +https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.1-hd09e2f1_1.conda#75ba9aba95c277f12e23cdb0856fd9cd https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc -https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-ha1d9b0f_0.conda#453807a4b94005e7148f89f9327eb1b7 +https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-he456531_1.conda#6cd21078a491bdf3fdb7482e1680ef63 https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda#afda563484aa0017278866707807a335 https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda#3f50cdf9a97d0280655758b735781096 https://conda.anaconda.org/conda-forge/osx-64/qhull-2020.2-h3c5361c_5.conda#dd1ea9ff27c93db7c01a7b7656bd4ad4 -https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda#342570f8e02f2f022147a7f841475784 +https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda#eefd65452dfe7cce476a519bece46704 https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda#bd9f1de651dbd80b51281c694827f78f -https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.2-h53ec75d_0.conda#1e979f90e823b82604ab1da7e76c75e5 +https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.2-h8bce59a_1.conda#cdd69480d52f2b871fad1a91324d9942 https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.conda#dfbdc8fd781dc3111541e4234c19fdbd https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_15.conda#c816665789d1e47cdfd6da8a81e1af64 https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 -https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h7b7ecba_0.conda#e7ed73b34f9d43d80b7e80eba9bce9f3 +https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h24ca049_1.conda#c58fc83257ad06634b9c935099ef2680 https://conda.anaconda.org/conda-forge/osx-64/python-3.14.2-hf88997e_100_cp314.conda#48921d5efb314c3e628089fc6e27e54a https://conda.anaconda.org/conda-forge/osx-64/brotli-1.2.0-hf139dec_1.conda#149d8ee7d6541a02a6117d8814fd9413 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/osx-64/cython-3.2.2-py314h9fad922_0.conda#4e8210b53b2a0cb9d397c6cc025d0fec +https://conda.anaconda.org/conda-forge/osx-64/cython-3.2.4-py314hf0dd12f_0.conda#4dbcccd0d8e2bfe89246de1547d58c17 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.9-py314hf3ac25a_2.conda#28a77c52c425fa9c6d914c609c626b1a @@ -56,31 +56,31 @@ https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.17-h72f5680_0.conda#bf210d https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.1-h694c41f_0.conda#e0e2edaf5e0c71b843e25a7ecc451cc9 https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_15.conda#c2a6149bf7f82774a0118b9efef966dd https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.1-default_h273dbb7_1003.conda#5a87dfe5dcdc54ca4dc839e1d3577785 -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h87e8dc5_0.conda#a67d3517ebbf615b91ef9fdc99934e0c https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 -https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.2-py314h6482030_2.conda#d97f0d30ffb1b03fa8d09ef8ba0fdd7c +https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.4-py314h3d180e3_0.conda#e9dfcd5b883e35aebe6dbe2c197dddbe https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.0-py314h6482030_1.conda#d69097de15cbad36f1eaafda0bad598a -https://conda.anaconda.org/conda-forge/osx-64/coverage-7.12.0-py314hb9c7d66_0.conda#d8805ca5ce27c9a2182baf03a16209ab +https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.1-py314h10d0514_0.conda#66abbb27b2ed5b9797c5d686bbf97446 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.0-pyh7db6752_0.conda#2ae6c63938d6dd000e940673df75419c +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.1-h694c41f_0.conda#ca641fdf8b7803f4b7212b6d66375930 -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_15.conda#a089323fefeeaba2ae60e1ccebf86ddc -https://conda.anaconda.org/conda-forge/osx-64/pillow-12.0.0-py314hedf0282_2.conda#399177697c7225b64edeaeb373a8c98b +https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.0-py314hf9dbaa9_0.conda#ca55b2df1530e093f26d25ed503aafe8 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.13.0-hf0c99ee_4.conda#411c95470bff187ae555120702f28c0e @@ -96,11 +96,11 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.co https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-20_osx64_mkl.conda#51089a4865eb4aec2bc5c7468bd07f9f https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-20_osx64_mkl.conda#58f08e12ad487fac4a08f90ff0b87aec https://conda.anaconda.org/conda-forge/osx-64/liblapacke-3.9.0-20_osx64_mkl.conda#124ae8e384268a8da66f1d64114a1eda -https://conda.anaconda.org/conda-forge/osx-64/numpy-2.3.5-py314hf08249b_0.conda#5c9e4bc0c170115fd3602d7377c9e8da +https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.0-py314hfc4c462_0.conda#5e45547a4a84dc6f6da82aa4bee9fe7c https://conda.anaconda.org/conda-forge/osx-64/blas-devel-3.9.0-20_osx64_mkl.conda#cc3260179093918b801e373c6e888e02 https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h00ed6fe_3.conda#761aa19f97a0dd5dedb9a0a6003707c1 https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.3-py314hc4308db_2.conda#b082e18eb2696625aa09c80e0fbd1997 -https://conda.anaconda.org/conda-forge/osx-64/scipy-1.16.3-py314h9d854bd_1.conda#017b471251f1d7401ed1dd63370bad2f +https://conda.anaconda.org/conda-forge/osx-64/scipy-1.16.3-py314hbb40827_2.conda#306e89b8db5482c47324978efcf59f7d https://conda.anaconda.org/conda-forge/osx-64/blas-2.120-mkl.conda#b041a7677a412f3d925d8208936cb1e2 https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.8-py314hd47142c_0.conda#91d76a5937b47f7f0894857ce88feb9f https://conda.anaconda.org/conda-forge/osx-64/pyamg-5.3.0-py314h81027db_1.conda#47390f4299f43bcdae539d454178596e diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock index fe44be4c0899f..1e48c4161c03f 100644 --- a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock @@ -7,11 +7,12 @@ https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a668 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-14.5-hfa17104_3.conda#3351af6c29661d56d7ef9ea9699d1314 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda#58fd217444c2a5701a44244faf518206 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.1-h38cb7af_0.conda#5446161926f45f3a14f7ca9db4d53e3b https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa -https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.7-hf598326_0.conda#0de94f39727c31c0447e408c5a210a56 +https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-hf598326_0.conda#780f0251b757564e062187044232c2b7 https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda#b79875dbb5b1db9a4a22a4520f918e1a @@ -23,7 +24,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda#c0d87c3c8e075daf1daf6c31b53e8083 https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda#e5e7d467f80da752be17796b87fe6385 https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda#369964e85dc26bfe78f41399b366c435 -https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.7-h4a912ad_0.conda#05d475f50ddcc2173a6beece9960c6cb +https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.8-h4a912ad_0.conda#206ad2df1b5550526e386087bef543c7 https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda#068d497125e4bf8a66bf707254fff5ae https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda#415816daf82e0b23a736a069a75e9da7 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda#78b548eed8227a689f93775d5d23ae09 @@ -38,83 +39,84 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.c https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.53-hfab5511_0.conda#62b6111feeffe607c3ecc8ca5bd1514b -https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.1-h9a5124b_0.conda#67e50e5bd4e5e2310d66b88c4da50096 +https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.1-h1b79a29_1.conda#8c3951797658e10b610929c3e57e9ad9 https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 -https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h8eac4d7_0.conda#cf7291a970b93fe3bb726879f2037af8 +https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h5ef1a60_1.conda#7eed1026708e26ee512f43a04d9d0027 https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda#175809cc57b2c67f27a0f238bd7f069d https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda#b34dc4172653c13dcf453862f251af2b https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda#6483b1f59526e05d7d894e466b5b6924 -https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda#63ef3f6e6d6d5c589e64f11263dc5676 +https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda#f8381319127120ce51e081dce4865cf4 https://conda.anaconda.org/conda-forge/osx-arm64/sleef-3.9.0-hb028509_0.conda#68f833178f171cfffdd18854c0e9b7f9 https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_0.conda#347261d575a245cb6111fb2cb5a79fc7 https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_3.conda#a73d54a5abba6543cb2f0af1bfbd6851 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda#e3170d898ca6cb48f1bb567afb92f775 -https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.2-h248ca61_0.conda#c2a30a3b30cf86ef97ec880d53a6571a +https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.2-hed4e4f5_1.conda#75f39a44c08cb5dc4ea847698de34ba3 https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda#6d4ede03e2a8e20eb51f7f681d2a2550 -https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_15.conda#9633bbd83cdc75ca0d325bf26fa32375 -https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.31.1-h658db43_2.conda#155d3d17eaaf49ddddfe6c73842bc671 +https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_16.conda#8b216bac0de7a9d60f3ddeba2515545c +https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.31.1-h98f38fd_4.conda#8a6b4281c176f1695ae0015f420e6aa9 +https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda#c08557d00807785decafb932b5be7ef5 https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 -https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-hba2cd1d_0.conda#a53d5f7fff38853ddb6bdc8fb609c039 +https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-h8d039ee_1.conda#fd804ee851e20faca4fecc7df0901d07 https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.1-hb693164_3.conda#4e4ea852d54cc2b869842de5044662fb https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.11-hfc2f54d_100_cp313.conda#18a8c69608151098a8fb75eea64cc266 -https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-0.1.3-h44b9a77_0.tar.bz2#4a2cac04f86a4540b8c9b8d8f597848f https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda#48ece20aa479be6ac9a284772827d00c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.2-py313h66a7184_0.conda#e5fd9ec2e9f89306a3f48302b29df4e1 +https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py313hf5aebd8_0.conda#6dc684ec14e88ff9485928f81286c7a5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.0-pyhd8ed1ab_0.conda#66b8b26023b8efdf8fcb23bac4b6325d +https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.2-pyhd8ed1ab_0.conda#7e7cf4d6c2be6991e6ae2b3f4331701c https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.12.0-pyhd8ed1ab_0.conda#a3b9510e2491c20c7fc0f5e730227fbb https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py313h7add70c_2.conda#9583687276aaa393e723f3b7970be69f https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda#92a61fd30b19ebd5c1621a5bfe6d8b5f https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda#f35fb38e89e2776994131fbf961fa44b -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_15.conda#75737d092770ee4695e13f6b181bdbd2 +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_16.conda#265a9d03461da24884ecc8eb58396d57 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h7d74516_0.conda#3df5979cc0b761dda0053ffdb0bca3ea -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.3.1-h8f1351a_1.conda#a5635df796b71f6ca400fc7026f50701 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/networkx-3.6-pyhcf101f3_0.conda#6725bfdf8ea7a8bf6415f096f3f1ffa5 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hbfb3c88_0.conda#6bf3d24692c157a41c01ce0bd17daeea https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda#ade77ad7513177297b1d75e351e136ce https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 -https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.2-py313h6535dbc_2.conda#c7fea1e31871009ff882a327ba4b7d9a +https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py313h6535dbc_0.conda#67a85c1b5c17124eaf9194206afd5159 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.12.0-py313h7d74516_0.conda#35d87ef273c80581a7f73172b757e4e2 +https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.1-py313h65a2061_0.conda#3283d95f985c7f293cb13bb7e33500a5 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.61.0-py313h7d74516_0.conda#4c69b2b96797e459051f24ae70d22220 +https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.61.1-py313h7d74516_0.conda#894eb0c3e9a17643906a6da3209bf045 https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.1-hce30654_0.conda#1ec9a1ee7a2c9339774ad9bb6fe6caec https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.2.1-py313hc1c22ca_2.conda#08bbc47d90ccee895465f61b8692e236 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_h6922315_1.conda#66697cc97d32afa29c17855b3d56680e +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 +https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_h6922315_3.conda#a9527064ed0ed4514de7a7d35ab28c97 https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_h73dfc95_5.conda#0b1110de04b80ea62e93fef6f8056fbb -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_15.conda#5c9f004d0b98ce792a022f1095d1b338 +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_16.conda#11e09edf0dde4c288508501fe621bab4 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef -https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.0.0-py313ha86496b_2.conda#d52bb6207093e90d6b70649728257e3f +https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.1.0-py313h45e5a15_0.conda#78a39731fd50dbd511de305934fe7e62 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_h73dfc95_5.conda#561b822bdb2c1bb41e16e59a090f1e36 -https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_1.conda#3a3ff7c8991ea2807eb13425733491c2 -https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-4_h8d724d3_accelerate.conda#2a826a3c1c83fe42be22ee4efddfe597 +https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_3.conda#fac8bcc3f72041318061b92c1f269aa4 +https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h8d724d3_accelerate.conda#c32b3b0d73d5cb1ab2a095a69bf3a7bd https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.0.2-hbec66e7_0.tar.bz2#37ca71a16015b17397da4a5e6883f66f https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 @@ -122,38 +124,38 @@ https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.18.0-py313ha61f8ec_0.c https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.11.3-hd7c7cec_0.conda#7fe1ee81492f43731ea583b4bee50b8b -https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_h8c76c84_1.conda#296de61644a3372f5cf13f266eb6ad88 +https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_h8c76c84_3.conda#972e9ed0155a9f563d1bd7a0a4ffeb28 https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_5.conda#6773a2b7d7d1b0a8d0e0f3bf4e928936 -https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-4_h752f6bc_accelerate.conda#e296bcad6b433ca2c30cee42fd43603a -https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-4_hcb0d94e_accelerate.conda#4285e49fbda8dc95c699f71ccc1527ac +https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_h752f6bc_accelerate.conda#e5733907c1c77e6db5012c299e42a5ad +https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hcb0d94e_accelerate.conda#3b5a735865842f8d6bf8b78b376ca9e1 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_1.conda#4df7fec2dac84a966f9de8addd561561 -https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_1.conda#e9d1109b5313ca4969210c3bedec6f0b +https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_3.conda#7b0ea95f0288f1a25f692800b407daf2 +https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_3.conda#d197a4b2169c054aa91252e1f95d7b08 https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_h36137df_5.conda#c11a3a5a0cdb74d8ce58c6eac8d1f662 https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda#8d99c82e0f5fed6cc36fcf66a11e03f0 -https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-4_hbdd07e9_accelerate.conda#14bf7f811c9e1b7c4af5387d4878ebbf +https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-5_hbdd07e9_accelerate.conda#29c7d09cbe6d342ced64b0447e1f3792 https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.9.1-cpu_generic_h040b7fb_1.conda#4d3dbf224d7d41e146777ae04c05ecc0 -https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.3.5-py313h9771d21_0.conda#3f8330206033158d3e443120500af416 +https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.0-py313h16eae64_0.conda#c87aab85fa09a22ef300bd50ffcf4691 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 -https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-4_h55bc449_accelerate.conda#cc98d2287a45077d377bdaf45bf27069 +https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-5_h55bc449_accelerate.conda#6696b095e91860523bcc97303e11d30d https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313ha61f8ec_3.conda#5643cff3e9ab77999fba139465156e35 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_impl_osx-arm64-14.3.0-h6d03799_1.conda#1e9ec88ecc684d92644a45c6df2399d0 https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.3-py313h7d16b84_2.conda#03771a1c710d15974372ae791811bcde https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.9.1-cpu_generic_py313_h6bf06e3_1.conda#b47dd1b58e9c6aa7b45239f7902b1243 -https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.16.3-py313h0d10b07_1.conda#55c947938346fb644c2752383c40f935 -https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.304-accelerate.conda#6515d85975013b221a4b97bb96540f5d -https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-h76e6a08_27.conda#2fb912af00fa523f5968855053bebd13 +https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.16.3-py313h29d7d31_2.conda#a3324bd937a39cbbf1cbe0940160e19e +https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.305-accelerate.conda#5f941c90faaca70599ef8302d0c2738f +https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-h76e6a08_28.conda#310923b3b53c3bdd5593bb5ee459d4fb https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py313h58042b9_0.conda#745c18472bc6d3dc9146c3dec18bb740 https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py313h28ea3aa_1.conda#51a353d043e612a8f520627cf0e73653 https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.9.1-cpu_generic_hcc7c195_1.conda#139bf77a4b1174e2e30c7d884fb160c8 -https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h07b0088_27.conda#0c9ac1e5d33185824ced44ce0aeab0b2 +https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h07b0088_28.conda#df9cdd6140ce2a72982cd86d887d991d https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py313h39782a4_0.conda#bae471007cbebf097a19e851c219d56a https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda#148516e0c9edf4e9331a4d53ae806a9b -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-h276745f_27.conda#834e2e73c7a45604603b5e586f53a377 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-h276745f_28.conda#5f6c2330bbefee96ed5c4f41e726b489 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_osx-arm64-14.3.0-h3c33bd0_0.conda#8db8c0061c0f3701444b7b9cc9966511 -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h07b0088_27.conda#de5434190db50b34f78341ae3c58cb1b +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h07b0088_28.conda#20e0e35b2cc60c621975b2374d2e4f45 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran-14.3.0-h3ef1dbf_0.conda#e148e0bc9bbc90b6325a479a5501786d https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda#043afed05ca5a0f2c18252ae4378bdee https://conda.anaconda.org/conda-forge/osx-arm64/fortran-compiler-1.11.0-h81a4f41_0.conda#d221c62af175b83186f96d8b0880bff6 diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index 9872a43eb2915..09f6782b51f95 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -4,61 +4,62 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 -https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda#518e9bbbc3e3486d6a4519192ba690f8 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 -# pip certifi @ https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl#sha256=97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b +# pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c # pip charset-normalizer @ https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 -# pip coverage @ https://files.pythonhosted.org/packages/76/b6/67d7c0e1f400b32c883e9342de4a8c2ae7c1a0b57c5de87622b7262e2309/coverage-7.12.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=bc13baf85cd8a4cfcf4a35c7bc9d795837ad809775f782f697bf630b7e200211 +# pip coverage @ https://files.pythonhosted.org/packages/12/da/91a52516e9d5aea87d32d1523f9cdcf7a35a3b298e6be05d6509ba3cfab2/coverage-7.13.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=fa3edde1aa8807de1d05934982416cb3ec46d1d4d91e280bcce7cca01c507992 # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 -# pip cython @ https://files.pythonhosted.org/packages/57/c1/76928c07176a4402c74d5b304936ad8ee167dd04a07cf7dca545e8c25f9b/cython-3.2.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=a473df474ba89e9fee81ee82b31062a267f9e598096b222783477e56d02ad12c -# pip docutils @ https://files.pythonhosted.org/packages/11/a8/c6a4b901d17399c77cd81fb001ce8961e9f5e04d3daf27e8925cb012e163/docutils-0.22.3-py3-none-any.whl#sha256=bd772e4aca73aff037958d44f2be5229ded4c09927fcf8690c577b66234d6ceb +# pip cython @ https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 +# pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec -# pip fonttools @ https://files.pythonhosted.org/packages/4e/80/c87bc524a90dbeb2a390eea23eae448286983da59b7e02c67fa0ca96a8c5/fonttools-4.61.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl#sha256=b2b734d8391afe3c682320840c8191de9bd24e7eb85768dd4dc06ed1b63dbb1b +# pip fonttools @ https://files.pythonhosted.org/packages/a3/4b/d67eedaed19def5967fade3297fed8161b25ba94699efc124b14fb68cdbc/fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl#sha256=64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5 # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea # pip imagesize @ https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl#sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 -# pip joblib @ https://files.pythonhosted.org/packages/1e/e8/685f47e0d754320684db4425a0967f7d3fa70126bffd76110b7009a0090f/joblib-1.5.2-py3-none-any.whl#sha256=4e1f0bdbb987e6d843c70cf43714cb276623def372df3c22fe5266b2670bc241 +# pip joblib @ https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl#sha256=5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 # pip kiwisolver @ https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 -# pip meson @ https://files.pythonhosted.org/packages/d7/ab/115470e7c6dcce024e43e2e00986864c56e48c59554bb19f4b02ed72814c/meson-1.9.2-py3-none-any.whl#sha256=1a284dc1912929098a6462401af58dc49ae3f324e94814a38a8f1020cee07cba +# pip meson @ https://files.pythonhosted.org/packages/32/4f/c398c6f06ece1c6c246e008d5dac3824c98f54d3eb3d8014f4910afd6d48/meson-1.10.0-py3-none-any.whl#sha256=4b27aafce281e652dcb437b28007457411245d975c48b5db3a797d3e93ae1585 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa -# pip numpy @ https://files.pythonhosted.org/packages/f5/10/ca162f45a102738958dcec8023062dad0cbc17d1ab99d68c4e4a6c45fb2b/numpy-2.3.5-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=11e06aa0af8c0f05104d56450d6093ee639e15f24ecf62d417329d06e522e017 +# pip numpy @ https://files.pythonhosted.org/packages/99/98/9d4ad53b0e9ef901c2ef1d550d2136f5ac42d3fd2988390a6def32e23e48/numpy-2.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=8cfa5f29a695cb7438965e6c3e8d06e0416060cf0d709c1b1c1653a939bf5c2a # pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 -# pip pillow @ https://files.pythonhosted.org/packages/38/57/755dbd06530a27a5ed74f8cb0a7a44a21722ebf318edbe67ddbd7fb28f88/pillow-12.0.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=f4f1231b7dec408e8670264ce63e9c71409d9583dd21d32c163e25213ee2a344 +# pip pillow @ https://files.pythonhosted.org/packages/01/9a/632e58ec89a32738cabfd9ec418f0e9898a2b4719afc581f07c04a05e3c9/pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b -# pip pyparsing @ https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl#sha256=e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e +# pip pyparsing @ https://files.pythonhosted.org/packages/8b/40/2614036cdd416452f5bf98ec037f38a1afb17f327cb8e6b652d4729e0af8/pyparsing-3.3.1-py3-none-any.whl#sha256=023b5e7e5520ad96642e2c6db4cb683d3970bd640cdf7115049a6e9c3682df82 # pip pytz @ https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl#sha256=5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 -# pip roman-numerals @ https://files.pythonhosted.org/packages/82/1d/7356f115a0e5faf8dc59894a3e9fc8b1821ab949163458b0072db0a12a68/roman_numerals-3.1.0-py3-none-any.whl#sha256=842ae5fd12912d62720c9aad8cab706e8c692556d01a38443e051ee6cc158d90 +# pip roman-numerals @ https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl#sha256=647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7 # pip six @ https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl#sha256=4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 # pip snowballstemmer @ https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl#sha256=6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 # pip sphinxcontrib-applehelp @ https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl#sha256=4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5 @@ -69,8 +70,8 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip sphinxcontrib-serializinghtml @ https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl#sha256=6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 # pip tabulate @ https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl#sha256=024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb -# pip tzdata @ https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl#sha256=1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8 -# pip urllib3 @ https://files.pythonhosted.org/packages/56/1a/9ffe814d317c5224166b23e7c47f606d6e473712a2fad0f704ea9b99f246/urllib3-2.6.0-py3-none-any.whl#sha256=c90f7a39f716c572c4e3e58509581ebd83f9b59cced005b7db7ad2d22b0db99f +# pip tzdata @ https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl#sha256=06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 +# pip urllib3 @ https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl#sha256=ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd # pip array-api-strict @ https://files.pythonhosted.org/packages/e1/7b/81bef4348db9705d829c58b9e563c78eddca24438f1ce1108d709e6eed55/array_api_strict-2.4.1-py3-none-any.whl#sha256=22198ceb47cd3d9c0534c50650d265848d0da6ff71707171215e6678ce811ca5 # pip contourpy @ https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 @@ -80,12 +81,12 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 # pip scipy @ https://files.pythonhosted.org/packages/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=7dc1360c06535ea6116a2220f760ae572db9f661aba2d88074fe30ec2aa1ff88 # pip lightgbm @ https://files.pythonhosted.org/packages/42/86/dabda8fbcb1b00bcfb0003c3776e8ade1aa7b413dff0a2c08f457dace22f/lightgbm-4.6.0-py3-none-manylinux_2_28_x86_64.whl#sha256=cb19b5afea55b5b61cbb2131095f50538bd608a00655f23ad5d25ae3e3bf1c8d -# pip matplotlib @ https://files.pythonhosted.org/packages/22/ff/6425bf5c20d79aa5b959d1ce9e65f599632345391381c9a104133fe0b171/matplotlib-3.10.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=b3c4ea4948d93c9c29dc01c0c23eef66f2101bf75158c291b88de6525c55c3d1 +# pip matplotlib @ https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486 # pip meson-python @ https://files.pythonhosted.org/packages/28/58/66db620a8a7ccb32633de9f403fe49f1b63c68ca94e5c340ec5cceeb9821/meson_python-0.18.0-py3-none-any.whl#sha256=3b0fe051551cc238f5febb873247c0949cd60ded556efa130aa57021804868e2 # pip pandas @ https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac # pip pyamg @ https://files.pythonhosted.org/packages/63/f3/c13ae1422434baeefe4d4f306a1cc77f024fe96d2abab3c212cfa1bf3ff8/pyamg-5.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=5cc223c66a7aca06fba898eb5e8ede6bb7974a9ddf7b8a98f56143c829e63631 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 # pip scipy-doctest @ https://files.pythonhosted.org/packages/f5/99/a17f725f45e57efcf5a84494687bba7176e0b5cba7ca0f69161a063fa86d/scipy_doctest-2.0.1-py3-none-any.whl#sha256=7725b1cb5f4722ab2a77b39f0aadd39726266e682b19e40f96663d7afb2d46b1 -# pip sphinx @ https://files.pythonhosted.org/packages/c6/3f/4bbd76424c393caead2e1eb89777f575dee5c8653e2d4b6afd7a564f5974/sphinx-9.0.4-py3-none-any.whl#sha256=5bebc595a5e943ea248b99c13814c1c5e10b3ece718976824ffa7959ff95fffb +# pip sphinx @ https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl#sha256=c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978 # pip numpydoc @ https://files.pythonhosted.org/packages/6c/45/56d99ba9366476cd8548527667f01869279cedb9e66b28eb4dfb27701679/numpydoc-1.8.0-py3-none-any.whl#sha256=72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541 diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index e94fdf6ae3dec..06e0c42dd62f3 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -7,26 +7,26 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.7-h4922eb0_0.conda#ec29f865968a81e1961b3c2f2765eebb +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc -https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.5-hb9d3cd8_0.conda#f7f0d6cc2dc986d42ac2689ec88192be +https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc @@ -36,9 +36,9 @@ https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb9d3cd8_3.conda# https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda#b64523fb87ac6f87f0790f324ad43046 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -49,24 +49,22 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.8.23-hd590300_0.conda#cc4f06f7eedb1523f3b83fd0fb3942ff -https://conda.anaconda.org/conda-forge/linux-64/gettext-tools-0.25.1-h3f43e3d_1.conda#a59c05d22bdcbb4e984bf0c021a2a02f https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libasprintf-0.25.1-h3f43e3d_1.conda#3b0d184bc9404516d418d4509e418bdc https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.0.9-h166bdaf_9.conda#61641e239f96eae2b8492dc7e755828c https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.25.1-h3f43e3d_1.conda#2f4de899028319b27eb7a4023be5dfd2 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed +https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_1.conda#ad1fd565aff83b543d726382c0ab0af2 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -75,12 +73,12 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda#e235d5566c9cc8970eb2798dd4ecf62f https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 -https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 +https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/s2n-1.3.46-h06160fa_0.conda#413d96a0b655c8f8aacc36473a2dbb04 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda#580a52a05f5be28ce00764149017c6d4 https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c @@ -89,19 +87,18 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1. https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda#d1db1b8be7c3a8983dcbbbfe4f0765de -https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.25.1-h3f43e3d_1.conda#fd9cf4a11d07f0ef3e44fc061611b1ed https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.conda#081aa22f4581c08e4372b0b6c2f8478e https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.conda#1f0a03af852a9659ed2bf08f2f1704fd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.25.1-h3f43e3d_1.conda#3f7a43b3160ec0345c9535a9f0d7908e -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h6548e54_1.conda#f01292fb36b6d00d5c51e5d46b513bcf +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_2.conda#b04e0a2163a72588a40cde1afd6f2d18 +https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_3.conda#70d1de6301b58ed99fea01490a9802a3 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h8fd135c_2.conda#bbf65f7688512872f063810623b755dc https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318b08df404f9c9be5712aaa5a6f0bb0 @@ -118,11 +115,10 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.13.27-h3870b5a_0.cond https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.conda#d47dee1856d9cb955b8076eeff304a5b https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/gettext-0.25.1-h3f43e3d_1.conda#c42356557d7f2e37676e121515417e3b -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.2-hf516916_1.conda#495c262933b7c5b8c09413d44fa5974b +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_0.conda#fd6acbf37b40cbe919450fa58309fbe1 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_0.conda#01e149d4a53185622dc2e788281961f2 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_1.conda#117499f93e892ea1e57fdca16c2e8351 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 @@ -143,7 +139,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.7.10-h9ab9c9b_2.con https://conda.anaconda.org/conda-forge/linux-64/brotli-1.0.9-h166bdaf_9.conda#4601544b4982ba1861fa9b9c607b2c06 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.0.9-py311ha362b79_9.conda#ced5340f5dc6cff43a80deac8d0e398f https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -156,29 +152,29 @@ https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc -https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda#ee48bf17cc83a00f59ca1494d5646869 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e +https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda#978d03388b62173b8e6f79162cf52b86 https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py311h49ec1c0_2.conda#8d7a63fc9653ed0bdc253a51d9a5c371 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 @@ -188,18 +184,17 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.0-h435f46f_0.conda#c7726f96aab024855ede05e0ca6e94a0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.8.13-hd4f18eb_5.conda#860fb8c0efec64a4a678eb2ea066ff65 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.12.0-py311h3778330_0.conda#4ef5919a315f5c2834fc8da49044156d +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.1-py311h3778330_0.conda#9d38ee59f3535da3ee59652dcef8fd96 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py311h3778330_0.conda#f5ee391df23b7f50676ebe79fc53ee03 -https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.2-h5192d8d_1.conda#7071a9745767777b4be235f8c164ea75 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 +https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.3-h5192d8d_0.conda#48560c0be24568c3d53a944d2d496818 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.7-hf7376ad_0.conda#27dc1a582b442f24979f2a28641fe478 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb -https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda#ef1910918dd895516a769ed36b5b3a4e https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 @@ -208,12 +203,11 @@ https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_1.conda#d3042ebdaacc689fd1daa701885fc96c -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_1.conda#66508e5f84c3dc9af1a0a62694325ef2 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_3.conda#b450493426793d5fe7d8216a27120050 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_3.conda#ee42c44c3676cdbb6e63190077ca57d3 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 -https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 @@ -230,7 +224,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h7b9373a_16. https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h3c3fd16_6.conda#5aab84b9d164509b5bbe3af660518606 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 +https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_3.conda#d2bbbd293097e664ffb01fc4cdaf5729 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index f0adc2af81009..44fac6766980c 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -4,22 +4,22 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -27,57 +27,58 @@ https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f +https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda#518e9bbbc3e3486d6a4519192ba690f8 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 -https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 +https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-4_h4a7cf45_openblas.conda#14ff9fdfbd8bd590fca383b995470711 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a -https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.2.0-py311h6b1f9c4_0.conda#596b9cc36b7af0640825b399e6b11ccc +https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a -https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py311h0daaf2c_0.conda#93f275715239f0ad95343a75fb15dbd7 -https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.3-pyhd8ed1ab_0.conda#abbe8c85619c87c4f4f61b44173434af +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 +https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-4_h0358290_openblas.conda#25f5e5af61cee1ffedd9b4c9947d3af8 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-4_h47877c9_openblas.conda#8ba8431802764597f400ee3e99026367 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/roman-numerals-3.1.0-pyhd8ed1ab_0.conda#b272e95116c1449e584fb397e12bc3db +https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 @@ -91,22 +92,22 @@ https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-4_h6ae95b6_openblas.conda#91ee3fce1a4fb8495b9aa110de74d926 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py311h2e04523_0.conda#01da92ddaf561cabebd06019ae521510 +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py311h2e04523_0.conda#c6c7e0db448312b204667a13d7f7346d https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-4_h1ea3ea9_openblas.conda#b94457a746ba3bba8cc39881a18d6d41 +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311h1e13796_1.conda#e1947291b713cb0afa949e1bcda1f935 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.0-pyhd8ed1ab_0.conda#de7372f43e63ff0876b4023b79b55e95 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.304-openblas.conda#9f3df6e080be9558b0eced56c01b1ce5 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311hbe70eeb_2.conda#1f9587850322d7d77ea14d4fee3d16d8 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.2-pyhd8ed1ab_0.conda#4949ca7b83065cfe94ebe320aece8c72 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 +https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda#5af206d64d18d6c8dfb3122b4d9e643b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda#16e3f039c0aa6446513e94ab18a8784b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda#910f28a05c178feba832f842155cbfff diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock index f510d9a52f8a8..f070e3e7e07b3 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock @@ -7,32 +7,32 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda#71b24316859acd00bdb8b38f5e2ce328 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-h4c7d964_0.conda#f98fb7db808b94bc1ec5b0e62f9f1069 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-h4c7d964_0.conda#84d389c9eee640dda3d26fc5335c67d8 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda#8a86073cf3b343b87d03f41790d8b4e5 -https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda#58f67b437acbf2764317ba273d731f1d +https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda#242d9f25d2ae60c76b38a5e42858e51d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_15.conda#18713a6d90ce576053ac3ce9f792fe14 -https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda#378d5dcec45eaea8d303da6f00447ac0 +https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_16.conda#ab8189163748f95d4cb18ea1952943c3 +https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda#37eb311485d2d8b2c419449582046a42 https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda#37e16618af5c4851a3f3d66dd0e11141 -https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h2b53caa_32.conda#ef02bbe151253a72b8eda264a935db66 +https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda#1e610f2416b6acdd231c5f573d754a0f https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda#1077e9333c41ff0be8edd1a5ec0ddace -https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.3.1-he0c23c2_0.conda#e9a1402439c18a4e3c7a52e4246e9e1c +https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_0.conda#3d3caf4ccc6415023640af4b1b33060a https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda#b785694dd3ec77a011ccf0c24725382b -https://conda.anaconda.org/conda-forge/win-64/icu-75.1-he0c23c2_0.conda#8579b6bb8d18be7c0b27fb08adeeeb40 +https://conda.anaconda.org/conda-forge/win-64/icu-78.1-h637d24d_0.conda#cb8048bed35ef01431184d6a88e46b3e https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda#c1b81da6d29a14b542da14a36c9fbf3f https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda#444b0a45bbd1cb24f82eedb56721b9c4 https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda#8c9e4f1a0e688eef2e95711178061a0f https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda#ba4ad812d2afc22b9a34ce8327a0930f -https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_15.conda#e05ab7ace69b10ae32f8a710a5971f4f +https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_16.conda#1edb8bd8e093ebd31558008e9cb23b47 https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#64571d1dd6cdcfa25d0664a5950fdaa2 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda#56a686f92ac0273c0f6af58858a3f013 https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda#c15148b2e18da456f5108ccb5e411446 https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.30-pthreads_h877e47f_4.conda#f551f8ae0ae6535be1ffde181f9377f3 -https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.1-hf5d6505_0.conda#f92bef2f8e523bb0eabe60099683617a +https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.1-hf5d6505_1.conda#be65be5f758709fc01b01626152e96b0 https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.328.1-h477610d_0.conda#4403eae6c81f448d63a7f66c0b330536 https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda#f9bbae5e2537e3b06e0f7310ba76c893 https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda#41fbfac52c601159df6c01f875de31b9 @@ -41,16 +41,16 @@ https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda#84f https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda#08c8fa3b419df480d985e304f7884d35 https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda#854fbdff64b572b5c0b470f334d34c11 https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_3.conda#7cb36e506a7dba4817970f8adb6396f9 -https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.2-h5112557_0.conda#2b4f8712b09b5fd3182cda872ce8482c +https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.2-h0261ad2_1.conda#bc2fba648e1e784c549e20bbe1a8af40 https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda#31aec030344e962fbd7dbbbbd68e60a9 -https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-4_h0adab6e_openblas.conda#1e44e1899ea86037873e65de3f5c19c5 +https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_h0adab6e_openblas.conda#bae34d8f039de36cc4384371aa12bd61 https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda#450e3ae947fc46b60f1d8f8f318b40d4 https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda#ccd93cfa8e54fd9df4e83dbe55ff6e8c https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda#2cf0cf76cc15d360dfa2f17fd6cf9772 https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.53-h7351971_0.conda#fb6f43f6f08ca100cb24cff125ab0d9e -https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h06f855e_0.conda#4a5ea6ec2055ab0dfd09fd0c498f834a +https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h3cfd58e_1.conda#07d73826fde28e7dbaec52a3297d7d26 https://conda.anaconda.org/conda-forge/win-64/openblas-0.3.30-pthreads_h4a7f399_4.conda#482e61f83248a880d180629bf8ed36b2 -https://conda.anaconda.org/conda-forge/win-64/pcre2-10.46-h3402e2f_0.conda#889053e920d15353c2665fa6310d7a7a +https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda#77eaf2336f3ae749e712f63e36b0f0a1 https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda#3c8f2573569bb816483e5cf57efbbe29 https://conda.anaconda.org/conda-forge/win-64/python-3.11.14-h0159041_2_cpython.conda#02a9ba5950d8b78e6c9862d6ba7a5045 https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda#8436cab9a76015dfe7208d3c9f97c156 @@ -59,61 +59,61 @@ https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda#053b84 https://conda.anaconda.org/conda-forge/win-64/brotli-bin-1.2.0-hfd05255_1.conda#6abd7089eb3f0c790235fe469558d190 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/win-64/cython-3.2.2-py311h9990397_0.conda#c146d51910e29a6d6060ecf84ba7978d +https://conda.anaconda.org/conda-forge/win-64/cython-3.2.4-py311h9990397_0.conda#74e8c626533a6011c33fdf2a47fbf71c https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py311h275cad7_2.conda#e9eb24a8d111be48179bf82a9e0e13ca -https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-4_h2a8eebe_openblas.conda#464b3434e245c2967c0e226f1611f6f9 -https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.7-default_ha2db4b5_1.conda#065bcc5d1a29de06d4566b7b9ac89882 +https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a8eebe_openblas.conda#1db756824d3aec6a25599c7821cb3e24 +https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.7-default_ha2db4b5_3.conda#9ff0d8534c2a24abbe8f7ca8144147b1 https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda#6e7c5c5ab485057b5d07fd8188ba5c28 -https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.2-hd9c3897_0.conda#fbd144e60009d93f129f0014a76512d3 -https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-4_hd232482_openblas.conda#808ae0372f0b1495c41a1ce2064f291f +https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.3-h0c9aed9_0.conda#c2d5b6b790ef21abac0b5331094ccb56 +https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hd232482_openblas.conda#78240c2b4322025a74e7e6edad247103 https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c -https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-ha29bfb0_0.conda#87116b9de9c1825c3fd4ef92c984877b -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-h779ef1b_1.conda#68dc154b8d415176c07b6995bd3a65d9 +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 -https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.2-py311h3485c13_2.conda#56b468f7a48593bc555c35e4a610d1f2 +https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py311h3485c13_0.conda#6e8d1faf5c0c08641c151e0fb79cb4db https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.0-py311h3485c13_1.conda#a30a6a70ab7754dbf0b06fe1a96af9cb https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda#bc58fdbced45bb096364de0fba1637af -https://conda.anaconda.org/conda-forge/win-64/coverage-7.12.0-py311h3f79411_0.conda#5eb14cad407cb102cc678fcaba4b0ee3 +https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.1-py311h3f79411_0.conda#2bc1a645fd4c574855277c6ab0061f49 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda#3538827f77b82a837fa681a4579e37a1 https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda#3235024fe48d4087721797ebd6c9d28c -https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-4_hbb0e6ff_openblas.conda#cf28f3b4945a9b76dbb64c60d534d7b7 +https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-5_hbb0e6ff_openblas.conda#b96fdd694dc8b7a5869613121c40d086 https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 -https://conda.anaconda.org/conda-forge/win-64/numpy-2.3.5-py311h80b3fa1_0.conda#1e0fb210584b09130000c4404b77f0f6 +https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.0-py311h80b3fa1_0.conda#341bab3c29a3b81d5ef81eac749b51ce https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h24db6dd_0.conda#5af852046226bb3cb15c7f61c2ac020a https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-4_ha590de0_openblas.conda#e3e893858dd88ee0351f1a5b9cb140f3 +https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-5_ha590de0_openblas.conda#e19a49b16cf765708e6d8676a50f74e1 https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h3fd045d_3.conda#5e7e380c470e9f4683b3129fedafbcdf -https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.0-py311h3f79411_0.conda#448f4a9f042eec9a840e3a0090e9a6d8 +https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py311h3f79411_0.conda#e5445b571c6e2919198c40c6db3d25c5 https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda#d69c21967f35eb2ce7f1f85d6b6022d3 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/win-64/pillow-12.0.0-py311h17b8079_2.conda#a80f6ec79f4ea2bf7572f4f8e8b467f7 +https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.0-py311h17b8079_0.conda#da30e4de83b61f936f73660eb4fa3cd5 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/win-64/scipy-1.16.3-py311hf127856_1.conda#48d562b3a3fb120d7c3f5e6af6d4b3e9 -https://conda.anaconda.org/conda-forge/win-64/blas-2.304-openblas.conda#a17d4405929291b138f4fb3068b44b2a +https://conda.anaconda.org/conda-forge/win-64/scipy-1.16.3-py311h9c22a71_2.conda#4b663de0f0c8ac0fbb4a4d9ee8536b0f +https://conda.anaconda.org/conda-forge/win-64/blas-2.305-openblas.conda#19bbf270f61bbef238e16a9509377a52 https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.15.0-h765892d_1.conda#9bb0026a2131b09404c59c4290c697cd https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h5782bbf_0.conda#20e32ced54300292aff690a69c5e7b97 -https://conda.anaconda.org/conda-forge/win-64/harfbuzz-12.2.0-h5f2951f_0.conda#e798ef748fc564e42f381d3d276850f0 -https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.9.3-ha0de62e_1.conda#ca2bfad3a24794a0f7cf413b03906ade -https://conda.anaconda.org/conda-forge/win-64/pyside6-6.9.3-py311hf70c7b4_1.conda#db3dc429d8fa0cb3562eca20d94af620 +https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda#52ea1beba35b69852d210242dd20f97d +https://conda.anaconda.org/conda-forge/win-64/harfbuzz-12.3.0-h5a1b470_0.conda#0eb57e84ceeb62c0189827fe7966bdc5 +https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.10.1-h68b6638_4.conda#c4a3cf4e79a59cb46ad2d56b74c89e57 +https://conda.anaconda.org/conda-forge/win-64/pyside6-6.10.1-py311hf70c7b4_0.conda#fe94fb3de0c9ef09dfe49e4f4098299d https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py311h1ea47a8_0.conda#64fe28aa2486e41918239d385336e88e diff --git a/build_tools/azure/ubuntu_atlas_lock.txt b/build_tools/azure/ubuntu_atlas_lock.txt index b7e46d69c03b0..12a53d14e1085 100644 --- a/build_tools/azure/ubuntu_atlas_lock.txt +++ b/build_tools/azure/ubuntu_atlas_lock.txt @@ -12,7 +12,7 @@ iniconfig==2.3.0 # via pytest joblib==1.3.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt -meson==1.9.2 +meson==1.10.0 # via meson-python meson-python==0.18.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 5776d859d9d67..964a2a160d95b 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -7,38 +7,38 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 -https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_8.conda#ff007ab0f0fdc53d245972bba8a6d40c +https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_115.conda#eedcd688f597873e1d16f0529f4d6d10 +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_116.conda#0141e19cb0cd5602c49c84f920e81921 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_115.conda#1ef1a0376c610365eb26e67f5da5e48d -https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_8.conda#1bad93f0aa428d618875ef3a588a889e +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_116.conda#badba6a9f0e90fdaff87b06b54736ea6 +https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -50,9 +50,10 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda#a77f85f77be52ff59391544bfe73390a https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 -https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda#bfd56492d8346d669010eccafe0ba058 +https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717_0.conda#dbe3ec0f120af456b3477743ffd99b74 https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d +https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda#518e9bbbc3e3486d6a4519192ba690f8 https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.4-h3f801dc_0.conda#01ba04e414e47f95c03d6ddd81fd37be @@ -60,27 +61,26 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_15.conda#9e82f96224931323c6ed53d88fb3241b +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_16.conda#0617b134e4dc4474c1038707499f7eed https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda#a587892d3c13b6621a6091be690dbca2 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 -https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda#7fa07cb0fb1b625a089ccc01218ee5b1 +https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 -https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 +https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/svt-av1-3.1.2-hecca717_0.conda#9859766c658e78fec9afa4a54891d920 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 -https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_3.conda#03b04e4effefa41aee638f8ba30a6e78 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_5.conda#6a0eb48e58684cca4d7acc8b7a0fd3c7 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d @@ -88,14 +88,15 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.cond https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.22.0-hc31b594_1.conda#52019609422a72ec80c32bbc16a889d8 https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 -https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_5.conda#82954a6f42e3fba59628741dca105c98 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 @@ -103,19 +104,20 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 -https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_104.conda#a7a67bf132a4a2dea92a7cb498cdc5b1 +https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_105.conda#e410a8f80e22eb6d840e39ac6a34bd0e https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h6395336_2.conda#c09c4ac973f7992ba0c6bb1aafd77bd4 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-4_h4a7cf45_openblas.conda#14ff9fdfbd8bd590fca383b995470711 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.0-h8d634f6_0.conda#65900b71509b2fd6c0a34a5dc1bd893a https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 @@ -125,76 +127,78 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_ https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda#8035e5b54c08429354d5d64027041cad https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda#537296d57ea995666c68c821b00e360b -https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.2.0-py311h6b1f9c4_0.conda#596b9cc36b7af0640825b399e6b11ccc -https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-default_h4852527_104.conda#d351e4894d6c4d9d8775bf169a97089d -https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-default_h4852527_104.conda#e30e71d685e23cc1e5ac1c1990ba1f81 +https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a +https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-default_h4852527_105.conda#1bc3e6c577a1a206c36456bdeae406de +https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-default_h4852527_105.conda#4b1e4ae87a52e9724a9ec0c7b822bc89 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2#576d629e47797577ab0f1b351297ef4a -https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 -https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.2-pyhd8ed1ab_0.conda#fcac5929097ba1f2a0e5b6ecaa13b253 +https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.2-pyhcf101f3_1.conda#61b8078a0905b12529abc622406cb62c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.14-py311hd8ed1ab_2.conda#43ed151bed1a0eb7181d305fed7cf051 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.2-py311h0daaf2c_0.conda#93f275715239f0ad95343a75fb15dbd7 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2#961b3a227b437d82ad7054484cfa71b2 https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h319ec69_15.conda#042695cf5fb55a63294f3575c33a468c +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-he8b2097_16.conda#d274bf1343507683e6eb2954d1871569 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/noarch/json5-0.12.1-pyhd8ed1ab_0.conda#0fc93f473c31a2f85c0bde213e7c63ca +https://conda.anaconda.org/conda-forge/noarch/json5-0.13.0-pyhd8ed1ab_0.conda#8d5f66ebf832c4ce28d5c37a0e76605c https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda#cd2214824e36b0180141d422aba01938 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b965c999135d43a3d0f7bd7d024e26a -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-4_h0358290_openblas.conda#25f5e5af61cee1ffedd9b4c9947d3af8 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-4_h47877c9_openblas.conda#8ba8431802764597f400ee3e99026367 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 +https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.13.0-pyhcf101f3_0.conda#0129bb97a81c2ca0f57031673424387a -https://conda.anaconda.org/conda-forge/noarch/networkx-3.6-pyhcf101f3_0.conda#6725bfdf8ea7a8bf6415f096f3f1ffa5 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.15.0-pyhcf101f3_0.conda#37926bb0db8b04b8b99945076e1442d0 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.23.1-pyhd8ed1ab_0.conda#a1e91db2d17fd258c64921cb38e6745a -https://conda.anaconda.org/conda-forge/linux-64/psutil-7.1.3-py311haee01d2_0.conda#2092b7977bc8e05eb17a1048724593a4 +https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.1-py311haee01d2_0.conda#8cc656ea4773e02929cc58745669b116 https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda#7d9daffbb8d8e0af0f769dbbcd173a54 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda#23029aae904a2ba587daba708208012f https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda#a61bf9ec79426938ff785eb69dbb1960 -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_0.conda#707c3d23f2476d3bfde8345b4e7d7853 https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h2315fbb_0.conda#6c87a0f4566469af3585b11d89163fd7 https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f -https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-3.1.0-pyhd8ed1ab_0.conda#5f0f24f8032c2c1bb33f59b75974f5fc +https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda#3893f7b40738f9fe87510cb4468cdda5 -https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh0d859eb_1.conda#938c8de6b9de091997145b3bf25cdbf9 +https://conda.anaconda.org/conda-forge/noarch/send2trash-2.0.0-pyha191276_0.conda#f2cc28627a451a28ddd5ef5ab0bf579d https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 -https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda#18c019ccf43769d211f2cf78e9ad46c2 +https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.1-pyhd8ed1ab_0.conda#7de28c27fe620a4f7dbfaea137c6232b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhcf101f3_3.conda#de98449f11d48d4b52eefb354e2bfe35 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py311h49ec1c0_2.conda#8d7a63fc9653ed0bdc253a51d9a5c371 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda#019a7385be9af33791c989871317e1ed https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda#f6d7aa696c67756a650e91e15e88223c @@ -217,30 +221,29 @@ https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_0.conda#b1a27250d70881943cca0dd6b4ba0956 https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_15.conda#93b9b94788b52e6f79cf6ae88de40c76 +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_16.conda#77e54ea3bd0888e65ed821f19f5d23ad https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py311h3778330_0.conda#f5ee391df23b7f50676ebe79fc53ee03 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_14.conda#fe0c2ac970a0b10835f3432a3dfd4542 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_15.conda#d10648cffe3cdacded77f7fdeacfb8f0 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_15.conda#a27be47954f8b96b0e4c383632bc80f9 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_17.conda#50dc15ac993bb5859f923979c81fafc8 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_16.conda#3065346248242b288fd4f73fe34f833e +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_16.conda#8729b9d902631b9ee604346a90a50031 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-4_h6ae95b6_openblas.conda#91ee3fce1a4fb8495b9aa110de74d926 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.7-hf7376ad_0.conda#27dc1a582b442f24979f2a28641fe478 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_0.conda#e55b5f69f6b53ec33cdaac390131f77a +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_0.conda#7e8e1d030e2d02196c498383aae486ae +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 -https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 -https://conda.anaconda.org/conda-forge/noarch/mistune-3.1.4-pyhcf101f3_0.conda#f5a4d548d1d3bdd517260409fc21e205 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.3.5-py311h2e04523_0.conda#01da92ddaf561cabebd06019ae521510 +https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b11e360fc4de2b0035fc8aaa74f17fd6 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py311h2e04523_0.conda#c6c7e0db448312b204667a13d7f7346d https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.0-pyhd8ed1ab_0.conda#6d4c79b604d50c1140c32164f7eca72a @@ -250,57 +253,55 @@ https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.14-hd8ed1ab_2.cond https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 -https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda#efba281bbdae5f6b0a1d53c6d4a97c93 +https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-4.1.0-pyhd8ed1ab_0.conda#28687768633154993d521aecfa4a56ac +https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda#17b43cee5cc84969529d5d0b0309b2cb https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.5.1-pyhcf101f3_0.conda#c0d0b883e97906f7524e2aac94be0e0d https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/noarch/anyio-4.12.0-pyhcf101f3_0.conda#9958d4a1ee7e9c768fe8f4fb51bd07ea +https://conda.anaconda.org/conda-forge/noarch/anyio-4.12.1-pyhcf101f3_0.conda#11a2b8c732d215d977998ccd69a9d5e8 https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda#6e36e9d2b535c3fbe2e093108df26695 https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda#85c4f19f377424eafc4ed7911b291642 https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-4_h1ea3ea9_openblas.conda#b94457a746ba3bba8cc39881a18d6d41 +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-h5f6438b_0.conda#08a03378bc5293c6f97637323802f480 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311hdf67eae_3.conda#c4e2f4d5193e55a70bb67a2aa07006ae https://conda.anaconda.org/conda-forge/noarch/doit-0.36.0-pyhd8ed1ab_1.conda#18d4243b3d30352f9dea8e522f6ff4d1 https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_15.conda#893d79ba69d21198012ff8212a8c563a -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h1e4d427_14.conda#5d81121caf70d8799d90dabbf98e5d3d -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-hcfe7c2f_14.conda#c4fd428cfc444609ff7dbceed7f9b3ef -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2025.11.11-py311hd2c663a_1.conda#6cbb8004493da9989e6c94c36151e4c3 +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_16.conda#dcaf539ffe75649239192101037f1406 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h9ce9316_17.conda#d5db7829d4b9b1676419fca2c63909b3 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h310e576_17.conda#94474857477981fedf74cf7c47c88ba5 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.1-py311h273f733_0.conda#1e2ccd20e277220a515d2afe5a810917 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a -https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda#4ebae00eae9705b0c3d6d1018a81d047 +https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.7.0-pyhcf101f3_0.conda#1b0397a7b1fbffa031feb690b5fd0277 https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_1.conda#2d983ff1b82a1ccb6f2e9d8784bdd6bd https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_1.conda#d3042ebdaacc689fd1daa701885fc96c -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_1.conda#66508e5f84c3dc9af1a0a62694325ef2 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.9.0-py311h0372a8f_2.conda#4e078a6bafb23473ea476450f45c9650 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311h1e13796_1.conda#e1947291b713cb0afa949e1bcda1f935 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.0-pyhd8ed1ab_0.conda#de7372f43e63ff0876b4023b79b55e95 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311hbe70eeb_2.conda#1f9587850322d7d77ea14d4fee3d16d8 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.2-pyhd8ed1ab_0.conda#4949ca7b83065cfe94ebe320aece8c72 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b -https://conda.anaconda.org/conda-forge/linux-64/blas-2.304-openblas.conda#9f3df6e080be9558b0eced56c01b1ce5 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_15.conda#2cad53f60b22fba4693d6c67ee8e0cb7 -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_15.conda#0b1faa0b6a877261a8b4ec692d41b7c4 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_16.conda#f5b82e3d5f4d345e8e1a227636eeb64f +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_16.conda#a3aa64ee3486f51eb61018939c88ef12 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.0-h6083320_0.conda#1ea5ed29aea252072b975a232b195146 https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.25.1-pyhe01879c_0.conda#341fd940c242cf33e832c0402face56f -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.0-pyhcf101f3_0.conda#4797b73e8813dce0afe8c96839118294 +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.1-pyhcf101f3_0.conda#b8e1f542770b5f88b663012fc77f9628 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 +https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.10.16-pyhd8ed1ab_0.conda#f5b9f02d19761f79c564900a2a399984 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.12.20-pyhd8ed1ab_0.conda#f8a199849a262291f127f4835c990935 https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f @@ -309,14 +310,14 @@ https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.0-p https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_3.conda#d2bbbd293097e664ffb01fc4cdaf5729 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.3-h5c1c036_1.conda#762af6d08fdfa7a45346b1466740bacd -https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.25.2-py311hed34c8f_2.conda#515ec832e4a98828374fded73405e3f3 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-hb82b983_4.conda#f4dfd61ec958d420bebdcefeb805d658 +https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py311h2a99c40_0.conda#557f5d7ca735d89d706742bc19cd7e26 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda#f56000b36f09ab7533877e695e4e8cb0 https://conda.anaconda.org/conda-forge/noarch/jupytext-1.18.1-pyh80e38bb_0.conda#3c85f79f1debe2d2c82ac08f1c1126e1 -https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.2-pyhd8ed1ab_0.conda#6bb0d77277061742744176ab555b723c -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.3-py311he4c1a5a_1.conda#8c769099c0729ff85aac64f566bcd0d7 +https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py311he4c1a5a_0.conda#6b0c36cdc506dc560538fba50e43dd03 https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda#cfc86ccc3b1de35d36ccaae4c50391f5 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 997e3d4c0d8a6..32e050642ce4c 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -6,24 +6,24 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 -https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_8.conda#ff007ab0f0fdc53d245972bba8a6d40c -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_462.conda#0ec3505e9b16acc124d1ec6e5ae8207c +https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_463.conda#291727757c8a8613312aaa4b52e82ad8 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_115.conda#eedcd688f597873e1d16f0529f4d6d10 +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_116.conda#0141e19cb0cd5602c49c84f920e81921 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_15.conda#a90d6983da0757f4c09bb8fcfaf34e71 -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_115.conda#1ef1a0376c610365eb26e67f5da5e48d -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.7-h4922eb0_0.conda#ec29f865968a81e1961b3c2f2765eebb -https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_8.conda#1bad93f0aa428d618875ef3a588a889e +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_116.conda#badba6a9f0e90fdaff87b06b54736ea6 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 +https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_15.conda#a5d86b0496174a412d531eac03af9174 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.14-hb9d3cd8_0.conda#76df83c2a9035c54df5d04ff81bcc02d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 @@ -31,8 +31,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_15.conda#7b742943660c5173bb6a5c823021c9a0 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_15.conda#356b7358fcd6df32ad50d07cdfadd27d +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc @@ -41,8 +41,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda#b64523fb87ac6f87f0790f324ad43046 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_15.conda#fccfb26375ec5e4a2192dee6604b6d02 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.2-h5347b49_1.conda#41f5c09a211985c3ce642d60721e7c3e +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -54,27 +54,25 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 -https://conda.anaconda.org/conda-forge/linux-64/gettext-tools-0.25.1-h3f43e3d_1.conda#a59c05d22bdcbb4e984bf0c021a2a02f https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.4-h3f801dc_0.conda#01ba04e414e47f95c03d6ddd81fd37be -https://conda.anaconda.org/conda-forge/linux-64/libasprintf-0.25.1-h3f43e3d_1.conda#3b0d184bc9404516d418d4509e418bdc https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.25.1-h3f43e3d_1.conda#2f4de899028319b27eb7a4023be5dfd2 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_15.conda#7deffdc77cda3d2bbc9c558efa33d3ed +https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_15.conda#9e82f96224931323c6ed53d88fb3241b -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_0.conda#2e1b84d273b01835256e53fd938de355 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_15.conda#20a8584ff8677ac9d724345b9d4eb757 +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_16.conda#0617b134e4dc4474c1038707499f7eed +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_1.conda#ad1fd565aff83b543d726382c0ab0af2 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -84,13 +82,13 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda#e235d5566c9cc8970eb2798dd4ecf62f https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 -https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda#283b96675859b20a825f8fa30f311446 +https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/svt-av1-3.1.2-hecca717_0.conda#9859766c658e78fec9afa4a54891d920 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 -https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_3.conda#03b04e4effefa41aee638f8ba30a6e78 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-h54a6638_0.conda#0faadd01896315ceea58bcc3479b1d21 +https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_5.conda#6a0eb48e58684cca4d7acc8b7a0fd3c7 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d @@ -100,14 +98,13 @@ https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.22.0-hc31b594_1.conda https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_104.conda#a6abd2796fc332536735f68ba23f7901 -https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.25.1-h3f43e3d_1.conda#fd9cf4a11d07f0ef3e44fc061611b1ed +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.25.1-h3f43e3d_1.conda#3f7a43b3160ec0345c9535a9f0d7908e -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_15.conda#83c3e3937b2715e9919bc1ca27a7f684 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h6548e54_1.conda#f01292fb36b6d00d5c51e5d46b513bcf +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_5.conda#82954a6f42e3fba59628741dca105c98 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_2.conda#b04e0a2163a72588a40cde1afd6f2d18 +https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_3.conda#70d1de6301b58ed99fea01490a9802a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee @@ -116,12 +113,11 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 -https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_104.conda#a7a67bf132a4a2dea92a7cb498cdc5b1 +https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_105.conda#e410a8f80e22eb6d840e39ac6a34bd0e https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/gettext-0.25.1-h3f43e3d_1.conda#c42356557d7f2e37676e121515417e3b -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.2-hf516916_1.conda#495c262933b7c5b8c09413d44fa5974b +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_0.conda#fd6acbf37b40cbe919450fa58309fbe1 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h6395336_2.conda#c09c4ac973f7992ba0c6bb1aafd77bd4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e @@ -129,6 +125,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.co https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.0-h8d634f6_0.conda#65900b71509b2fd6c0a34a5dc1bd893a https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 @@ -136,11 +133,11 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda#def531a3ac77b7fb8c21d17bb5d0badb -https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.2.0-py311h6b1f9c4_0.conda#596b9cc36b7af0640825b399e6b11ccc -https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-default_h4852527_104.conda#d351e4894d6c4d9d8775bf169a97089d -https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-default_h4852527_104.conda#e30e71d685e23cc1e5ac1c1990ba1f81 +https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a +https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-default_h4852527_105.conda#1bc3e6c577a1a206c36456bdeae406de +https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-default_h4852527_105.conda#4b1e4ae87a52e9724a9ec0c7b822bc89 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 -https://conda.anaconda.org/conda-forge/noarch/certifi-2025.11.12-pyhd8ed1ab_0.conda#96a02a5c1a65470a7e4eedb644c872fd +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 @@ -149,42 +146,42 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.con https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h319ec69_15.conda#042695cf5fb55a63294f3575c33a468c +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-he8b2097_16.conda#d274bf1343507683e6eb2954d1871569 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de -https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda#ee48bf17cc83a00f59ca1494d5646869 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.0.0-py311hf88fc01_2.conda#79edb22fb652ee142099df18042ca8c0 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e -https://conda.anaconda.org/conda-forge/linux-64/psutil-7.1.3-py311haee01d2_0.conda#2092b7977bc8e05eb17a1048724593a4 +https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.1-py311haee01d2_0.conda#8cc656ea4773e02929cc58745669b116 +https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.2-pyhd8ed1ab_0.conda#88476ae6ebd24f39261e0854ac244f33 -https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda#3eeeeb9e4827ace8c0c1419c85d590ad +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 +https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 -https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8-pyhd8ed1ab_0.conda#18c019ccf43769d211f2cf78e9ad46c2 +https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.1-pyhd8ed1ab_0.conda#7de28c27fe620a4f7dbfaea137c6232b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.2-pyhd8ed1ab_0.conda#5d99943f2ae3cc69e1ada12ce9d4d701 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.2-py311h49ec1c0_2.conda#8d7a63fc9653ed0bdc253a51d9a5c371 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 @@ -194,23 +191,22 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_15.conda#93b9b94788b52e6f79cf6ae88de40c76 +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_16.conda#77e54ea3bd0888e65ed821f19f5d23ad https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.0-py311h3778330_0.conda#f5ee391df23b7f50676ebe79fc53ee03 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_14.conda#fe0c2ac970a0b10835f3432a3dfd4542 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_15.conda#d10648cffe3cdacded77f7fdeacfb8f0 -https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.2-h5192d8d_1.conda#7071a9745767777b4be235f8c164ea75 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_15.conda#a27be47954f8b96b0e4c383632bc80f9 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_17.conda#50dc15ac993bb5859f923979c81fafc8 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_16.conda#3065346248242b288fd4f73fe34f833e +https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.3-h5192d8d_0.conda#48560c0be24568c3d53a944d2d496818 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_16.conda#8729b9d902631b9ee604346a90a50031 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_hafda6a7_1003.conda#4fe840c6d6b3719b4231ed89d389bb17 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.7-hf7376ad_0.conda#27dc1a582b442f24979f2a28641fe478 +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb -https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda#ef1910918dd895516a769ed36b5b3a4e https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 @@ -221,56 +217,55 @@ https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_15.conda#893d79ba69d21198012ff8212a8c563a -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h1e4d427_14.conda#5d81121caf70d8799d90dabbf98e5d3d +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_16.conda#dcaf539ffe75649239192101037f1406 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h9ce9316_17.conda#d5db7829d4b9b1676419fca2c63909b3 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-hcfe7c2f_14.conda#c4fd428cfc444609ff7dbceed7f9b3ef +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h310e576_17.conda#94474857477981fedf74cf7c47c88ba5 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_1.conda#d3042ebdaacc689fd1daa701885fc96c -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_1.conda#66508e5f84c3dc9af1a0a62694325ef2 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_0.conda#e55b5f69f6b53ec33cdaac390131f77a +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_0.conda#7e8e1d030e2d02196c498383aae486ae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 -https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.0-pyhd8ed1ab_0.conda#de7372f43e63ff0876b4023b79b55e95 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.2-pyhd8ed1ab_0.conda#4949ca7b83065cfe94ebe320aece8c72 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_15.conda#2cad53f60b22fba4693d6c67ee8e0cb7 +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_16.conda#f5b82e3d5f4d345e8e1a227636eeb64f https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.11-h651a532_0.conda#d8d8894f8ced2c9be76dc9ad1ae531ce -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_15.conda#0b1faa0b6a877261a8b4ec692d41b7c4 +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_16.conda#a3aa64ee3486f51eb61018939c88ef12 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.4-pyhd8ed1ab_2.conda#bb0230917e2473c77d615104dbe8a49d -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhd8ed1ab_0.conda#db0c6b99149880c8ba515cf4abe93ee4 +https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-4_h5875eb1_mkl.conda#bd1a86e560c3b26961279ef6b6e8d45f -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h3c3fd16_6.conda#5aab84b9d164509b5bbe3af660518606 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-4_hfef963f_mkl.conda#41f4f9428b9d92b1b06f1fff80a2674d -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-4_h5e43f62_mkl.conda#f647e3368af2453546812658b5393901 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-4_hdba1596_mkl.conda#f0b31cc6189ebd85a2e16b15de09850b +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-4_hcf00494_mkl.conda#7f7c616ec25c252749fa4945ea1db3fd +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2025.11.11-py311hd2c663a_1.conda#6cbb8004493da9989e6c94c36151e4c3 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.1-py311h273f733_0.conda#1e2ccd20e277220a515d2afe5a810917 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.conda#643f8cb35133eb1be4919fb953f0a25f +https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.2-py311h14de704_1.conda#84e2dd379d4edec4dd6382861486104d https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.8.0-py311h9f3472d_0.conda#17334e5c12abdf2db6b25bd4187cd3e4 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.304-mkl.conda#adbc1b7f2e7acf80f45bd6592f88f0ae +https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.10.16-pyhd8ed1ab_0.conda#f5b9f02d19761f79c564900a2a399984 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.12.20-pyhd8ed1ab_0.conda#f8a199849a262291f127f4835c990935 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.22.0-py311h320fe9a_2.conda#e94b7f09b52628b89e66cdbd8c3029dd https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.12.0-pyhd8ed1ab_0.tar.bz2#05ee2fb22c1eca4309c06d11aff049f3 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 97930fcc38716..9d60062fc285b 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -7,32 +7,32 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.conda#9e115653741810778c9a915a2f8439e7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_15.conda#0719da240fd6086c34c4c30080329806 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_16.conda#4d2f224e8186e7881d53e3aead912f6c https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 -https://conda.anaconda.org/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda#4222072737ccff51314b5ece9c7d6f5a +https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-2_gnu.tar.bz2#6168d71addc746e8f2b8d57dfd2edcea -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2025.11.12-hbd8a1cb_0.conda#f0991f0f84902f6b6009b4d2350a83aa +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda#cf105bce884e4ef8c8ccdca9fe6695e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_15.conda#cfdf8700e69902a113f2611e3cc09b55 -https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.14-h86ecc28_0.conda#a696b24c1b473ecc4774bcb5a6ac6337 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_16.conda#cf9cd6739a3b694dcf551d898e112331 +https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.1-he30d5cf_0.conda#50a88426e78ae8eb7d52072ba2e8db21 https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_8.conda#2921ac0b541bf37c69e66bd6d9a43bca https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda#e7df0aab10b9cbb73ab2a467ebfaf8c7 https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d5cf_1.conda#8ec1d03f3000108899d1799d9964f281 https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda#a9138815598fe6b91a1d6782ca657b0c https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.3-hfae3067_0.conda#b414e36fbb7ca122030276c75fa9c34a https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-hd65408f_0.conda#0c5ad486dcfb188885e3cf8ba209b97b -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_15.conda#ad92990dc6f608f412a01540a7c9510e -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_15.conda#77fa819fd8e8ae4b54c3fd5c7b666c5b +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_16.conda#3e54a6d0f2ff0172903c0acfda9efc0e +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_16.conda#87b4ffedaba8b4d675479313af74f612 https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda#5a86bf847b9b926f3a4f203339748d78 https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda#5109d7f837a3dfdf5c60f60e311b041f https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.1-h86ecc28_2.conda#7d362346a479256857ab338588190da0 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_15.conda#2873f805cdabcf33b880b19077cf6180 -https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.2-h1022ec0_1.conda#15b2cc72b9b05bcb141810b1bada654f +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_16.conda#52d9df8055af3f1665ba471cce77da48 +https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda#cf2861212053d05f27ec49c3784ff8bb https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda#08aad7cbe9f5a6b460d0976076b6ae64 https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda#182afabe009dc78d8b73100255ee6868 @@ -41,38 +41,39 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libice-1.1.2-h86ecc28_0.conda#c8d8ec3e00cd0fd8a231789b91a7c5b7 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda#1c246e1105000c3660558459e2fd6d43 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda#bff06dcde4a707339d66d45d96ceb2e2 -https://conda.anaconda.org/conda-forge/linux-aarch64/double-conversion-3.3.1-h5ad3122_0.conda#399959d889e1a73fc99f12ce480e77e1 +https://conda.anaconda.org/conda-forge/linux-aarch64/double-conversion-3.4.0-hfae3067_0.conda#9fd794eaf983eabf975ead524540b4be https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda#4aa540e9541cc9d6581ab23ff2043f13 +https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.1-hb1525cb_0.conda#5eba836ceb0cccf969d9518ca884de2a https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.0.0-hfdc4d58_1.conda#60dceb7e876f4d74a9cbd42bbbc6b9cf https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf_1.conda#47e5b71b77bb8b47b4ecf9659492977f https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda#6553a5d017fe14859ea8a4e6ea5def8f https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda#2079727b538f6dd16f3fa579d4c3c53f https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda#fb640d776fc92b682a14e001980825b1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_15.conda#3ec85135541290a2ebd907f1e2d439d3 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_16.conda#776cca322459d09aad229a49761c0654 https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.53-h1abf092_0.conda#7591d867dbcba9eb7fb5e88a5f756591 -https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.1-h022381a_0.conda#233efdd411317d2dc5fde72464b3df7a -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_15.conda#7a99de7c14096347968d1fd574b46bb2 +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_16.conda#20b7f96f58ccbe8931c3a20778fb3b32 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda#b4df5d7d4b63579d081fd3a4cf99740e https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda#8b5222a41b5d51fb1a5a2c514e770218 -https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.46-h15761aa_0.conda#5128cb5188b630a58387799ea1366e37 +https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.47-hf841c20_0.conda#1a30c42e32ca0ea216bd0bfe6f842f0b https://conda.anaconda.org/conda-forge/linux-aarch64/pixman-0.46.4-h7ac5ae9_1.conda#1587081d537bd4ae77d1c0635d465ba5 -https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.2-h8382b9d_2.conda#c0f08fc2737967edde1a272d4bf41ed9 +https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda#3d49cad61f829f4f0e0611547a9cda12 https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h561c983_103.conda#631db4799bc2bfe4daccf80bb3cbc433 https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.24.0-h4f8a99f_1.conda#f6966cb1f000c230359ae98c29e37d87 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda#2d1409c50882819cb1af2de82e2b7208 -https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.2-h7ac5ae9_0.conda#a51d8a3d4a928bbfacb9ae37991dde63 +https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.2-ha7cb516_1.conda#055d3357e5d6f57291a687c6983e1884 https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 -https://conda.anaconda.org/conda-forge/linux-aarch64/icu-75.1-hf9b3779_0.conda#268203e8b983fddb6412b36f2024e75c https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.21.3-h50a48e9_0.conda#29c10432a2ca1472b53f299ffb2ffa37 -https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45-default_h1979696_104.conda#28035705fe0c977ea33963489cd008ad +https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45-default_h1979696_105.conda#849c4cbbf8dd1d71e66c13afed1d2f12 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.1-hdae7a39_0.conda#9c2f56b6e011c6d8010ff43b796aab2f -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-ng-15.2.0-he9431aa_15.conda#2dfbf3e5dcef40592ea337342a3592e7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.2-he84ff74_0.conda#d184d68eaa57125062786e10440ff461 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-ng-15.2.0-he9431aa_16.conda#3b55579065fac309af0129098fa1657b +https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.3-hf53f6bf_0.conda#f226b9798c6c176d2a94eea1350b3b6b https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e +https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.1-h10b116e_1.conda#9fd37e702b4e7c85462fe79baf13974d https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d +https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.1-h79dcc73_1.conda#e42758e7b065c34fd1b0e5143752f970 https://conda.anaconda.org/conda-forge/linux-aarch64/qhull-2020.2-h70be974_5.conda#bb138086d938e2b64f5f364945793ebf https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-0.4.1-hca56bd8_2.conda#159ffec8f7fab775669a538f0b29373a https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-keysyms-0.4.1-h5c728e9_0.conda#57ca8564599ddf8b633c4ea6afee6f3a @@ -83,12 +84,12 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-hd651790_1.con https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.28-h6c5dea3_0.conda#b6d06b46e791add99cc39fbbc34530d5 https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda#a4b6b82427d15f0489cef0df2d82f926 https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.17-hc88f144_0.conda#b87b1abd2542cf65a00ad2e2461a3083 -https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-4_haddc8a3_openblas.conda#10471558ac2b0c1b4dcd5e620fd65bfe +https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda#5afcea37a46f76ec1322943b3c4dfdc0 https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h5cdc715_5.conda#ac0333d338076ef19170938bbaf97582 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.1-h8af1aa0_0.conda#1e61fb236ccd3d6ccaf9e91cb2d7e12d https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.0.2-h05efe27_0.tar.bz2#a87f068744fd20334cd41489eb163bee -https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.1-h8591a01_0.conda#e7177c6fbbf815da7b215b4cc3e70208 +https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.1-h825857f_1.conda#eb4665cdf78fd02d4abc4edf8c15b7b9 https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.30-pthreads_h3a8cbd8_4.conda#e3f245ed352bd66d181b73a78d886038 https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.14-h91f4b29_2_cpython.conda#622ae39bb186be3eeeaa564a9c7e1eec @@ -100,29 +101,31 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86e https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.11.3-h4889ad1_0.conda#e0b9e519da2bf0fb8c48381daf87a194 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.2-py311hdc11669_0.conda#324e329aea785abb32429a383f1f151d +https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.4-py311hdc11669_0.conda#931a90956062cc7219c6bce6c6ccfe7f https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.1-h8af1aa0_0.conda#0c8f36ebd3678eed1685f0fc93fc2175 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.4.9-py311h229e7f7_2.conda#18358d47ebdc1f936003b7d407c9e16f -https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-4_hd72aa62_openblas.conda#0a9f6e328c9255fd829e5e775bb0696b +https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda#0b2f1143ae2d0aa4c991959d0daaf256 https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda#0d00176464ebb25af83d40736a2cd3bb -https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-4_h88aeb00_openblas.conda#f4930dcf31fbe6327215b6e6122f73af -https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.1-h788dabe_0.conda#a0e7779b7625b88e37df9bd73f0638dc -https://conda.anaconda.org/conda-forge/noarch/meson-1.9.2-pyhcf101f3_0.conda#7920269f1b2d2f49c49616ac5b507aae +https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda#88d1e4133d1182522b403e9ba7435f04 +https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm21-21.1.8-hfd2ba90_0.conda#de59c5148c2a8347c02e437e3ed242a0 +https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f +https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h30c48ee_0.conda#48f31a61be512ec1929f4b4a9cedf4bd https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 -https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.0.0-py311h8e17b9e_2.conda#b86d6e26631d730f43732ade7e510a3f +https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.0-py311h8e17b9e_0.conda#c771bf4d9191e68f1a09c573a9de897f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.2.5-pyhcf101f3_0.conda#6c8979be6d7a17692793114fa26916e8 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 -https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.2-py311hb9158a3_2.conda#6d68a78b162d9823e5abe63001c6df36 +https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.3-py311hb9158a3_0.conda#e3afe76a49a1a9f85e0c5cd42a408e68 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-aarch64/unicodedata2-17.0.0-py311h19352d5_1.conda#4a55814831e0ec9be84ccef6aed798c1 https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 @@ -133,35 +136,32 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdamage-1.1.6-h86ec https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda#eeee3bdb31c6acde2b81ad1b8c287087 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.4-h86ecc28_0.conda#dd3e74283a082381aa3860312e3c721e https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.6-h86ecc28_0.conda#d745faa2d7c15092652e40a22bb261ed -https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.12.0-py311h2dad8b0_0.conda#ddb3e5a915ecebd167f576268083c50b +https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.1-py311h2dad8b0_0.conda#a74e8e0a91d3fbbd8d5edef3ce5fca56 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.15.0-h8dda3cd_1.conda#112b71b6af28b47c624bcbeefeea685b -https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.0-py311h164a683_0.conda#3c533754d7ceb31f50f1f9bea8f2cb8f -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.2-pyhd8ed1ab_0.conda#4e717929cfa0d49cef92d911e31d0e90 -https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-4_hb558247_openblas.conda#447716292a5606947e25f0a8ffda7947 -https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm21-21.1.7-hfd2ba90_0.conda#6627fdee03b7c7d943f70fd74a7c2ab0 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.1-haf03d9f_2.conda#8b0d66c4db91b3ef64daad7f61a569d0 +https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.1-py311h164a683_0.conda#b59452fef1470e7e5c34a7c5deefe853 +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.7-default_he95a3c9_3.conda#71a8b7c6439119fcb9a555127d149a1a +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.7-default_h94a09a5_3.conda#b60f2316d922a558baa84ad24306bfc4 +https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-5_hb558247_openblas.conda#8046d5ae90150f00c8b40455d9b2e180 +https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.1-hf8816c8_3.conda#e0d7a6cbc0b8a6d05002cb9bd061a4af https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.328.1-h8b8848b_0.conda#e5a3ff3a266b68398bd28ed1d4363e65 -https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f -https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 -https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.3.5-py311h669026d_0.conda#5ca3db64e7fe0c00685b97104def7953 +https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.0-py311h669026d_0.conda#3ad0028f1f187e612f858009ec688227 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 -https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-4_h9678261_openblas.conda#bae5d65bab207969c4c37a1afb149f45 -https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h83712da_0.conda#cd55953a67ec727db5dc32b167201aa6 +https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-5_h9678261_openblas.conda#33a0e650392a79b56ae0bfa3db02ddbf +https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311hfca10b7_3.conda#47c305536dbf44cd3e629b6851605a50 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.7-default_he95a3c9_1.conda#6e80b4cf4d469505f168c0a16bb30ed8 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.7-default_h94a09a5_1.conda#d1124b3f50bd5e1b86033033fbd747c6 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.16.3-py311h33b5a33_1.conda#3d97f428e5e2f3d0f07f579d97e9fe70 -https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.304-openblas.conda#7987a64f37d8c509efc241968771f171 -https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-12.2.0-he4899c9_0.conda#1437bf9690976948f90175a65407b65f +https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.16.3-py311h399493a_2.conda#cacb6fbad878af1122e1301482fbc957 +https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.305-openblas.conda#2efe635198609d0d2a122c6a0923b8f8 +https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-12.3.0-h1134a53_0.conda#60d635185d9c39e6c8dbd1771e6c7267 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.9.3-h224e339_1.conda#ffcc8b87dd0a6315f231e690a7d7b6f2 -https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.9.3-py311hf1caecd_1.conda#73f404b29ee67faa8db72314a73ac714 +https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.10.1-h5343e53_4.conda#e14686527190e7b30fad9a49da71325b +https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.10.1-py311hf1caecd_0.conda#5877515b7a3ef76e2468c4f20d6d6997 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.8-py311hfecb2dc_0.conda#3920b856b59a909812f1913b96adaad8 From 255a5429bd2ec6d6e81864a37e9a8476c1748c26 Mon Sep 17 00:00:00 2001 From: Tim Head Date: Thu, 8 Jan 2026 11:08:53 +0100 Subject: [PATCH 108/462] Fix `log_loss` and `d2_log_loss_score` type promotion mismatch (#33022) Co-authored-by: Olivier Grisel Co-authored-by: Virgil Chan --- sklearn/metrics/_classification.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 227a3a6d7e416..19191475d0950 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -17,7 +17,6 @@ import numpy as np from scipy.sparse import coo_matrix, csr_matrix, issparse -from scipy.special import xlogy from sklearn.exceptions import UndefinedMetricWarning from sklearn.preprocessing import LabelBinarizer, LabelEncoder @@ -40,6 +39,7 @@ _isin, _max_precision_float_dtype, _union1d, + _xlogy, get_namespace, get_namespace_and_device, move_to, @@ -3390,7 +3390,8 @@ def _log_loss(transformed_labels, y_pred, *, normalize=True, sample_weight=None) sample_weight = move_to(sample_weight, xp=xp, device=device_) eps = xp.finfo(y_pred.dtype).eps y_pred = xp.clip(y_pred, eps, 1 - eps) - loss = -xp.sum(xlogy(transformed_labels, y_pred), axis=1) + transformed_labels = xp.astype(transformed_labels, y_pred.dtype, copy=False) + loss = -xp.sum(_xlogy(transformed_labels, y_pred, xp=xp), axis=1) return float(_average(loss, weights=sample_weight, normalize=normalize)) From 3ca712bec1a90f54adc7d7883f0f5f0c6b325e2b Mon Sep 17 00:00:00 2001 From: Chaitanya Dasari Date: Thu, 8 Jan 2026 04:09:20 -0600 Subject: [PATCH 109/462] DOC: Fix duplicate words in comments and docstrings (#33023) --- sklearn/metrics/_classification.py | 2 +- sklearn/utils/_plotting.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 19191475d0950..8540dd53640b3 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -533,7 +533,7 @@ def confusion_matrix( ensure_min_samples=0, ) # Convert the input arrays to NumPy (on CPU) irrespective of the original - # namespace and device so as to be able to leverage the the efficient + # namespace and device so as to be able to leverage the efficient # counting operations implemented by SciPy in the coo_matrix constructor. # The final results will be converted back to the input namespace and device # for the sake of consistency with other metric functions with array API support. diff --git a/sklearn/utils/_plotting.py b/sklearn/utils/_plotting.py index 3e247e5fc4a93..2486d5cba72bc 100644 --- a/sklearn/utils/_plotting.py +++ b/sklearn/utils/_plotting.py @@ -427,7 +427,7 @@ def _check_param_lengths(required, optional, class_name): # TODO(1.10): remove after the end of the deprecation period of `y_pred` def _deprecate_y_pred_parameter(y_score, y_pred, version): - """Deprecate `y_pred` in favour of of `y_score`.""" + """Deprecate `y_pred` in favour of `y_score`.""" version = parse_version(version) version_remove = f"{version.major}.{version.minor + 2}" if y_score is not None and not (isinstance(y_pred, str) and y_pred == "deprecated"): From 5035f737e983a0bc28fe9da323058dcaeabcb558 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Fri, 9 Jan 2026 00:06:42 +1100 Subject: [PATCH 110/462] MNT: Remove numpydoc upperbound in lock files (#33018) Co-authored-by: Olivier Grisel --- ...latest_conda_forge_mkl_linux-64_conda.lock | 14 ++-- .../pylatest_conda_forge_osx-arm64_conda.lock | 25 ++++--- ...latest_pip_openblas_pandas_environment.yml | 2 +- ...st_pip_openblas_pandas_linux-64_conda.lock | 7 +- .../pylatest_pip_scipy_dev_environment.yml | 2 +- ...pylatest_pip_scipy_dev_linux-64_conda.lock | 7 +- ...nblas_min_dependencies_linux-64_conda.lock | 6 +- ...forge_openblas_ubuntu_2204_environment.yml | 2 +- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 7 +- ...min_conda_forge_openblas_win-64_conda.lock | 2 +- build_tools/circle/doc_environment.yml | 2 +- build_tools/circle/doc_linux-64_conda.lock | 17 +++-- .../doc_min_dependencies_linux-64_conda.lock | 6 +- ...a_forge_cuda_array-api_linux-64_conda.lock | 71 +++++++++---------- ...n_conda_forge_arm_linux-aarch64_conda.lock | 4 +- .../update_environments_and_lock_files.py | 3 - 16 files changed, 82 insertions(+), 95 deletions(-) diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index 2c1b12f33034e..072b0b77ed5d6 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_1.conda#9e298d76f543deb06eb0f3413675e13a -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_462.conda#0ec3505e9b16acc124d1ec6e5ae8207c +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_463.conda#291727757c8a8613312aaa4b52e82ad8 https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 @@ -116,7 +116,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.con https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_1.conda#117499f93e892ea1e57fdca16c2e8351 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a @@ -222,8 +222,8 @@ https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_ https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.4-h8824e59_0.conda#113b9d9913280474c0868b0e290c0326 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.15.0-h2a74896_1.conda#ffd553ff98ce5d74d3d89ac269153149 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_3.conda#b450493426793d5fe7d8216a27120050 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_3.conda#ee42c44c3676cdbb6e63190077ca57d3 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_1.conda#e933f92cedca212eb2916f24823cf90b +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_1.conda#e00afd65b88a3258212661b32c1469cb https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 @@ -231,18 +231,18 @@ https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.57.0-pyhcf101f https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.2-pyhd8ed1ab_0.conda#4949ca7b83065cfe94ebe320aece8c72 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10.conda#937d1d4c233adc6eeb2ac3d6e9a73e53 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.13.0-hf38f1be_1.conda#f10b9303c7239fbce3580a60a92bcf97 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_462.conda#a2e8e73f7132ea5ea70fda6f3cf05578 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda#af35229f34c80dcfab5a40414440df23 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-hb6ed5f4_6_cpu.conda#fbaa3742ccca0f7096216c0832137b72 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_462.conda#619188d87dc94ed199e790d906d74bc3 +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda#160b41862a43936cbe509d1879d67f54 https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-h6f76662_3.conda#f134a496ef494f2b6c5a26e5d739acc6 diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock index 1e48c4161c03f..c88b5307b30b1 100644 --- a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock @@ -6,7 +6,7 @@ https://conda.anaconda.org/conda-forge/noarch/libgfortran-devel_osx-arm64-14.3.0 https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a66894dfd07c4510beb6b3f9672ccc0 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 -https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-14.5-hfa17104_3.conda#3351af6c29661d56d7ef9ea9699d1314 +https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-hc6f8731_5.conda#a3d76f9e9e3f49dc8bf03f1ef8d4757e https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda#58fd217444c2a5701a44244faf518206 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 @@ -106,7 +106,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.2.1-py313hc1c22ca_2.con https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_h6922315_3.conda#a9527064ed0ed4514de7a7d35ab28c97 -https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_h73dfc95_5.conda#0b1110de04b80ea62e93fef6f8056fbb +https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_6.conda#509700140f1de6d0b31e7d3181b3d8b2 https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_16.conda#11e09edf0dde4c288508501fe621bab4 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.1.0-py313h45e5a15_0.conda#78a39731fd50dbd511de305934fe7e62 @@ -114,7 +114,7 @@ https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda# https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_h73dfc95_5.conda#561b822bdb2c1bb41e16e59a090f1e36 +https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_6.conda#f7b47b7a0c20180be00833b6c68a8668 https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_3.conda#fac8bcc3f72041318061b92c1f269aa4 https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h8d724d3_accelerate.conda#c32b3b0d73d5cb1ab2a095a69bf3a7bd https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.0.2-hbec66e7_0.tar.bz2#37ca71a16015b17397da4a5e6883f66f @@ -125,38 +125,37 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.11.3-hd7c7cec_0.conda#7fe1ee81492f43731ea583b4bee50b8b https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_h8c76c84_3.conda#972e9ed0155a9f563d1bd7a0a4ffeb28 -https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_5.conda#6773a2b7d7d1b0a8d0e0f3bf4e928936 https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_h752f6bc_accelerate.conda#e5733907c1c77e6db5012c299e42a5ad https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hcb0d94e_accelerate.conda#3b5a735865842f8d6bf8b78b376ca9e1 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_3.conda#7b0ea95f0288f1a25f692800b407daf2 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_3.conda#d197a4b2169c054aa91252e1f95d7b08 -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_h36137df_5.conda#c11a3a5a0cdb74d8ce58c6eac8d1f662 -https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda#8d99c82e0f5fed6cc36fcf66a11e03f0 https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-5_hbdd07e9_accelerate.conda#29c7d09cbe6d342ced64b0447e1f3792 https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.9.1-cpu_generic_h040b7fb_1.conda#4d3dbf224d7d41e146777ae04c05ecc0 https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.0-py313h16eae64_0.conda#c87aab85fa09a22ef300bd50ffcf4691 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-5_h55bc449_accelerate.conda#6696b095e91860523bcc97303e11d30d -https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313ha61f8ec_3.conda#5643cff3e9ab77999fba139465156e35 -https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_impl_osx-arm64-14.3.0-h6d03799_1.conda#1e9ec88ecc684d92644a45c6df2399d0 https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.3-py313h7d16b84_2.conda#03771a1c710d15974372ae791811bcde https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.9.1-cpu_generic_py313_h6bf06e3_1.conda#b47dd1b58e9c6aa7b45239f7902b1243 https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.16.3-py313h29d7d31_2.conda#a3324bd937a39cbbf1cbe0940160e19e https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.305-accelerate.conda#5f941c90faaca70599ef8302d0c2738f -https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-h76e6a08_28.conda#310923b3b53c3bdd5593bb5ee459d4fb https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py313h58042b9_0.conda#745c18472bc6d3dc9146c3dec18bb740 https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py313h28ea3aa_1.conda#51a353d043e612a8f520627cf0e73653 https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.9.1-cpu_generic_hcc7c195_1.conda#139bf77a4b1174e2e30c7d884fb160c8 -https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h07b0088_28.conda#df9cdd6140ce2a72982cd86d887d991d https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py313h39782a4_0.conda#bae471007cbebf097a19e851c219d56a https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda#148516e0c9edf4e9331a4d53ae806a9b -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-h276745f_28.conda#5f6c2330bbefee96ed5c4f41e726b489 +https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_6.conda#25c9924db91c665423e0630a2f51ca22 +https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda#8d99c82e0f5fed6cc36fcf66a11e03f0 +https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_impl_osx-arm64-14.3.0-h6d03799_1.conda#1e9ec88ecc684d92644a45c6df2399d0 +https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 +https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_6.conda#7d5b8960ca867ad1287aba1ed9ef45cf +https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_29.conda#e1cbe6c2279228ca3a0ee32a80e89c89 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_6.conda#0ca27aa5b6a8752b6e4183c1b8712e12 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_29.conda#8dcfeec0143f62fc8beffc8065995105 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_osx-arm64-14.3.0-h3c33bd0_0.conda#8db8c0061c0f3701444b7b9cc9966511 -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h07b0088_28.conda#20e0e35b2cc60c621975b2374d2e4f45 -https://conda.anaconda.org/conda-forge/osx-arm64/gfortran-14.3.0-h3ef1dbf_0.conda#e148e0bc9bbc90b6325a479a5501786d https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda#043afed05ca5a0f2c18252ae4378bdee +https://conda.anaconda.org/conda-forge/osx-arm64/gfortran-14.3.0-h3ef1dbf_0.conda#e148e0bc9bbc90b6325a479a5501786d https://conda.anaconda.org/conda-forge/osx-arm64/fortran-compiler-1.11.0-h81a4f41_0.conda#d221c62af175b83186f96d8b0880bff6 https://conda.anaconda.org/conda-forge/osx-arm64/compilers-1.11.0-hce30654_0.conda#aac0d423ecfd95bde39582d0de9ca657 diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_environment.yml b/build_tools/azure/pylatest_pip_openblas_pandas_environment.yml index 38f2eaa36f432..d07aa8a284181 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_environment.yml +++ b/build_tools/azure/pylatest_pip_openblas_pandas_environment.yml @@ -24,7 +24,7 @@ dependencies: - pytest-cov<=6.3.0 - coverage - sphinx - - numpydoc<1.9.0 + - numpydoc - lightgbm - array-api-strict - scipy-doctest diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index 09f6782b51f95..3ebc9c06187a1 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 87b9773659dff9019bf908b8a2c3c6529e7126ff500be1e050cce880641009dc +# input_hash: 379fba3287458f6d9cd98c2c5855086a7e8b681b1116f1ab22e6e7ffc97a8c78 @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 @@ -68,10 +68,9 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip sphinxcontrib-jsmath @ https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl#sha256=2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 # pip sphinxcontrib-qthelp @ https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl#sha256=b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb # pip sphinxcontrib-serializinghtml @ https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl#sha256=6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 -# pip tabulate @ https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl#sha256=024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb # pip tzdata @ https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl#sha256=06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 -# pip urllib3 @ https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl#sha256=ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd +# pip urllib3 @ https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl#sha256=bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 # pip array-api-strict @ https://files.pythonhosted.org/packages/e1/7b/81bef4348db9705d829c58b9e563c78eddca24438f1ce1108d709e6eed55/array_api_strict-2.4.1-py3-none-any.whl#sha256=22198ceb47cd3d9c0534c50650d265848d0da6ff71707171215e6678ce811ca5 # pip contourpy @ https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 @@ -89,4 +88,4 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 # pip scipy-doctest @ https://files.pythonhosted.org/packages/f5/99/a17f725f45e57efcf5a84494687bba7176e0b5cba7ca0f69161a063fa86d/scipy_doctest-2.0.1-py3-none-any.whl#sha256=7725b1cb5f4722ab2a77b39f0aadd39726266e682b19e40f96663d7afb2d46b1 # pip sphinx @ https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl#sha256=c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978 -# pip numpydoc @ https://files.pythonhosted.org/packages/6c/45/56d99ba9366476cd8548527667f01869279cedb9e66b28eb4dfb27701679/numpydoc-1.8.0-py3-none-any.whl#sha256=72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541 +# pip numpydoc @ https://files.pythonhosted.org/packages/62/5e/3a6a3e90f35cea3853c45e5d5fb9b7192ce4384616f932cf7591298ab6e1/numpydoc-1.10.0-py3-none-any.whl#sha256=3149da9874af890bcc2a82ef7aae5484e5aa81cb2778f08e3c307ba6d963721b diff --git a/build_tools/azure/pylatest_pip_scipy_dev_environment.yml b/build_tools/azure/pylatest_pip_scipy_dev_environment.yml index ff94ab7b1949d..c2b10397b2d99 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_environment.yml +++ b/build_tools/azure/pylatest_pip_scipy_dev_environment.yml @@ -18,5 +18,5 @@ dependencies: - coverage - pooch - sphinx - - numpydoc<1.9.0 + - numpydoc - python-dateutil diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 8076c0d955bcc..92a464bdd432a 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: ddd5063484c104d6d6a6a54471148d6838f0475cd44c46b8a3a7e74476a68343 +# input_hash: 24ef416e2330a91ab0f9ebe316ec9431025e1b63eab146a1ce2e60f14fcf4caa @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 @@ -60,9 +60,8 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip sphinxcontrib-jsmath @ https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl#sha256=2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 # pip sphinxcontrib-qthelp @ https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl#sha256=b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb # pip sphinxcontrib-serializinghtml @ https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl#sha256=6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 -# pip tabulate @ https://files.pythonhosted.org/packages/40/44/4a5f08c96eb108af5cb50b41f76142f0afa346dfa99d5296fe7202a11854/tabulate-0.9.0-py3-none-any.whl#sha256=024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb -# pip urllib3 @ https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl#sha256=ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd +# pip urllib3 @ https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl#sha256=bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/c0/57/e69a1de45ec7a99a707e9f1a5defa035a48de0cae2d8582451c72d2db456/pyproject_metadata-0.10.0-py3-none-any.whl#sha256=b1e439a9f7560f9792ee5975dcf5e89d2510b1fc84a922d7e5d665aa9102d966 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b @@ -73,4 +72,4 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 # pip sphinx @ https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl#sha256=c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978 -# pip numpydoc @ https://files.pythonhosted.org/packages/6c/45/56d99ba9366476cd8548527667f01869279cedb9e66b28eb4dfb27701679/numpydoc-1.8.0-py3-none-any.whl#sha256=72024c7fd5e17375dec3608a27c03303e8ad00c81292667955c6fea7a3ccf541 +# pip numpydoc @ https://files.pythonhosted.org/packages/62/5e/3a6a3e90f35cea3853c45e5d5fb9b7192ce4384616f932cf7591298ab6e1/numpydoc-1.10.0-py3-none-any.whl#sha256=3149da9874af890bcc2a82ef7aae5484e5aa81cb2778f08e3c307ba6d963721b diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 06e0c42dd62f3..f912c238c8857 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -118,7 +118,7 @@ https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce9 https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_0.conda#fd6acbf37b40cbe919450fa58309fbe1 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_1.conda#117499f93e892ea1e57fdca16c2e8351 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 @@ -203,8 +203,8 @@ https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.7-default_h99862b1_3.conda#b450493426793d5fe7d8216a27120050 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.7-default_h746c552_3.conda#ee42c44c3676cdbb6e63190077ca57d3 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_1.conda#e933f92cedca212eb2916f24823cf90b +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_1.conda#e00afd65b88a3258212661b32c1469cb https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_environment.yml b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_environment.yml index 761a4005adc29..17e35387366cc 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_environment.yml +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_environment.yml @@ -20,5 +20,5 @@ dependencies: - ninja - meson-python - sphinx - - numpydoc<1.9.0 + - numpydoc - ccache diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 44fac6766980c..b2bf3f4a0e85c 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 80fba64a729753c6d1d7ebd81fd1f2c83ac6c3177861bc7a1b93e668e0b4f6ee +# input_hash: 4a7e90be8a5287a384c3d5be14b2f52f18019e1dfa2c584c5325fc7d52f0a764 @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 @@ -83,7 +83,6 @@ https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.con https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb -https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhcf101f3_3.conda#de98449f11d48d4b52eefb354e2bfe35 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d @@ -103,12 +102,12 @@ https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.c https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311hbe70eeb_2.conda#1f9587850322d7d77ea14d4fee3d16d8 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.2-pyhd8ed1ab_0.conda#4949ca7b83065cfe94ebe320aece8c72 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 -https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda#5af206d64d18d6c8dfb3122b4d9e643b +https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda#16e3f039c0aa6446513e94ab18a8784b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda#910f28a05c178feba832f842155cbfff https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_1.conda#e9fb3fe8a5b758b4aff187d434f94f03 diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock index f070e3e7e07b3..20410b5526bf6 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock @@ -64,7 +64,7 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py311h275cad7_2.conda#e9eb24a8d111be48179bf82a9e0e13ca https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a8eebe_openblas.conda#1db756824d3aec6a25599c7821cb3e24 -https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.7-default_ha2db4b5_3.conda#9ff0d8534c2a24abbe8f7ca8144147b1 +https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_1.conda#2dfbc5aaac3424065eb81ec9a9f49761 https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda#6e7c5c5ab485057b5d07fd8188ba5c28 https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.3-h0c9aed9_0.conda#c2d5b6b790ef21abac0b5331094ccb56 https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hd232482_openblas.conda#78240c2b4322025a74e7e6edad247103 diff --git a/build_tools/circle/doc_environment.yml b/build_tools/circle/doc_environment.yml index be39197894b58..6621687fee54d 100644 --- a/build_tools/circle/doc_environment.yml +++ b/build_tools/circle/doc_environment.yml @@ -27,7 +27,7 @@ dependencies: - sphinx - sphinx-gallery - sphinx-copybutton - - numpydoc<1.9.0 + - numpydoc - sphinx-prompt - plotly - polars=1.34.0 diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 964a2a160d95b..61e51ae3983d9 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: ca6b5567d8c939295b5b4408ecaa611380022818d7f626c2732e529c500271e7 +# input_hash: 8ee751e2ee3835d0218c5e31f6b17221595b6def62eaad571cdb80dd568a67db @EXPLICIT https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 @@ -195,7 +195,6 @@ https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.1-pyhd8ed1ab_0.conda#7de28c27fe620a4f7dbfaea137c6232b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb -https://conda.anaconda.org/conda-forge/noarch/tabulate-0.9.0-pyhcf101f3_3.conda#de98449f11d48d4b52eefb354e2bfe35 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a @@ -235,8 +234,8 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_0.conda#e55b5f69f6b53ec33cdaac390131f77a -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_0.conda#7e8e1d030e2d02196c498383aae486ae +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_1.conda#e933f92cedca212eb2916f24823cf90b +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_1.conda#e00afd65b88a3258212661b32c1469cb https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 @@ -246,7 +245,7 @@ https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py311h2e04523_0.conda#c6c7e0db448312b204667a13d7f7346d https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 -https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.0-pyhd8ed1ab_0.conda#6d4c79b604d50c1140c32164f7eca72a +https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.1-pyhd8ed1ab_0.conda#0a8b38871cab04059c1cc04853b415a2 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.14-hd8ed1ab_2.conda#a4effc7e6eb335d0e1080a5554590425 @@ -285,7 +284,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.con https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311hbe70eeb_2.conda#1f9587850322d7d77ea14d4fee3d16d8 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.2-pyhd8ed1ab_0.conda#4949ca7b83065cfe94ebe320aece8c72 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b @@ -293,7 +292,7 @@ https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_16.cond https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_16.conda#a3aa64ee3486f51eb61018939c88ef12 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.0-h6083320_0.conda#1ea5ed29aea252072b975a232b195146 https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a -https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.25.1-pyhe01879c_0.conda#341fd940c242cf33e832c0402face56f +https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.1-pyhcf101f3_0.conda#b8e1f542770b5f88b663012fc77f9628 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 @@ -305,7 +304,7 @@ https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.12.20-pyhd8ed1ab_0.c https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f -https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.25.1-he01879c_0.conda#13e31c573c884962318a738405ca3487 +https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda#8368d58342d0825f0843dc6acdd0c483 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.0-pyhcf101f3_0.conda#97624651e6fc9ca05effe0b4a80766e3 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 @@ -324,7 +323,7 @@ https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1 https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda#d79a87dcfa726bcea8e61275feed6f83 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.0-pyhcf101f3_1.conda#e53b79419913df0b84f7c3af7727122b -https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.8.0-pyhd8ed1ab_1.conda#5af206d64d18d6c8dfb3122b4d9e643b +https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda#837aaf71ddf3b27acae0e7e9015eebc6 https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda#bf22cb9c439572760316ce0748af3713 https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.6.1-pyhd8ed1ab_2.conda#3e6c15d914b03f83fc96344f917e0838 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 32e050642ce4c..25918194c1f62 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -223,13 +223,13 @@ https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.con https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h310e576_17.conda#94474857477981fedf74cf7c47c88ba5 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_0.conda#e55b5f69f6b53ec33cdaac390131f77a -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_0.conda#7e8e1d030e2d02196c498383aae486ae +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_1.conda#e933f92cedca212eb2916f24823cf90b +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_1.conda#e00afd65b88a3258212661b32c1469cb https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.2-pyhd8ed1ab_0.conda#4949ca7b83065cfe94ebe320aece8c72 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_16.conda#f5b82e3d5f4d345e8e1a227636eeb64f https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.11-h651a532_0.conda#d8d8894f8ced2c9be76dc9ad1ae531ce diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 4f3b72530b5bd..a3142d4ed1ac8 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -8,9 +8,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.18.0-ha770c72_1.conda#4fb055f57404920a43b147031471e03b https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2024.2.2-ha770c72_17.conda#c18fd07c02239a7eb744ea728db39630 -https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 @@ -24,7 +22,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c1 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d -https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.0-hb9d3cd8_0.conda#f65c946f28f0518f41ced702f44c52b7 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.10.6-hb9d3cd8_0.conda#d7d4680337a14001b0e043e96529409b https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 @@ -41,7 +39,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f -https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.10.0-h202a827_0.conda#0f98f3e95272d118f7931b6bef69bfe5 +https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.9.0-hb9d3cd8_1.conda#1e936bd23d737aac62a18e9a1e7f8b18 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -52,10 +50,10 @@ https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002. https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f -https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.8.7-h043a21b_0.conda#4fdf835d66ea197e693125c64fbd4482 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h3870646_2.conda#17ccde79d864e6183a83c5bbb8fff34d -https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.3-h3870646_2.conda#06008b5ab42117c89c982aa2a32a5b25 -https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.3-h3870646_2.conda#303d9e83e0518f1dcb66e90054635ca6 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.8.1-h1a47875_3.conda#55a8561fdbbbd34f50f57d9be12ed084 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.0-h4e1184b_5.conda#3f4c1197462a6df2be6dc8241828fe93 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.1-h4e1184b_4.conda#a5126a90e74ac739b00564a4c7ddcc36 +https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.2-h4e1184b_4.conda#74e8c3e4df4ceae34aa2959df4b28101 https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda#bfd56492d8346d669010eccafe0ba058 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d @@ -79,16 +77,15 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda#7fa07cb0fb1b625a089ccc01218ee5b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.14-h6c98b2b_0.conda#efab4ad81ba5731b2fefa0ab4359e884 +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.11-h072c03f_0.conda#5e8060d52f676a40edef0006a75c718f https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 -https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.17.0-h3dad3f2_6.conda#3a127d28266cdc0da93384d1f59fe8df +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.15.3-h173a860_6.conda#9a063178f1af0a898526cc24ba7be486 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb03c661_4.conda#ca4ed8015764937c81b830f7f5b68543 https://conda.anaconda.org/conda-forge/linux-64/cudatoolkit-11.8.0-h4ba93d1_13.conda#eb43f5f1f16e2fad2eba22219c3e499b https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca @@ -101,7 +98,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.c https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 -https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.28.3-h6128344_1.conda#d8703f1ffe5a06356f06467f1d0b9464 +https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.28.2-h5b01275_0.conda#ab0bff36363bec94720275a681af8b83 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2024.07.02-hbbce691_2.conda#b2fede24428726dd867611664fb372e8 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.21.0-h0e7cc3e_0.conda#dcb95c0a98ba9ff737f7ae482aef7833 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 @@ -112,22 +109,22 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.4-h04a3f94_2.conda#81096a80f03fc2f0fb2a230f5d028643 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.9.4-hb9b18c6_4.conda#773c99d0dbe2b3704af165f97ff399e5 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.0-h7959bf6_11.conda#9b3fb60fe57925a92f399bc3fc42eccf +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.9.2-hefd7a92_4.conda#5ce4df662d32d3123ea8da15571b6f51 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb03c661_4.conda#eaf3fbd2aa97c212336de38a51fe404e https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.1.4-h7d33bf5_0.conda#93fe78190bc6fe40d5e7a737c8065286 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.17.0-h4e3cde8_1.conda#117499f93e892ea1e57fdca16c2e8351 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.9-h04c0eec_0.conda#35eeb0a2add53b1e50218ed230fa6a02 https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/orc-2.1.1-h2271f48_0.conda#67075ef2cb33079efee3abfe58127a3b +https://conda.anaconda.org/conda-forge/linux-64/orc-2.0.3-h97ab989_1.conda#2f46eae652623114e112df13fae311cf https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e https://conda.anaconda.org/conda-forge/linux-64/re2-2024.07.02-h9925aae_2.conda#e84ddf12bde691e8ec894b00ea829ddf https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 @@ -135,8 +132,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.8.6-hd08a7f5_4.conda#f5a770ac1fd2cb34b21327fc513013a7 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.12.2-h108da3e_2.conda#90e07c8bac8da6378ee1882ef0a9374a +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.8.0-hb921021_15.conda#c79d50f64cffa5ad51ecc1a81057962f +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.11.0-h11f4f37_12.conda#96c3e0221fa2da97619ee82faa341a73 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.14.0-h5cfcd09_0.conda#0a8838771cc2e985cd295e01ae83baf1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 @@ -152,7 +149,7 @@ https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 https://conda.anaconda.org/conda-forge/linux-64/libcudnn-dev-9.10.1.4-h0fdc2d1_0.conda#a0c0b44d26a4710e6ea577fcddbe09d1 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.67.1-h25350d4_2.conda#bfcedaf5f9b003029cc6abe9431f66bf +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.67.1-hc2c308b_0.conda#4606a4647bfe857e3cfe21ca12ac3afb https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h3d81e11_1000.conda#d821210ab60be56dd27b5525ed18366d https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.conda#9ad637a7ac380c442be142dfb0b1b955 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda#74e91c36d0eef3557915c68b6c2bef96 @@ -168,7 +165,6 @@ https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda# https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py313h80991f8_0.conda#183fe6b9e99e5c2b464c1573ec78eac8 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 @@ -187,7 +183,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.7.13-h822ba82_2.conda#9cf2c3c13468f2209ee814be2c88655f +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.7.7-hf454442_0.conda#947c82025693bebd557f782bb5d6b469 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.10.0-h113e628_0.conda#73f73f60854f325a55f1d31459f2ab73 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.8.0-h736e048_1.conda#13de36be8de3ae3f05ba127631599213 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.1-py313h3dea7bd_0.conda#82315acb438e857f809f556e2dcdb822 @@ -200,8 +196,7 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.0-default_h99862b1_1.conda#d599b346638b9216c1e8f9146713df05 https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.0-default_h746c552_1.conda#327c78a8ce710782425a89df851392f7 -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.36.0-h2b5623c_0.conda#c96ca58ad3352a964bfcb85de6cd1496 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.18.0-hfcad708_1.conda#1f5a5d66e77a39dc5bd639ec953705cf +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.32.0-h804f50b_0.conda#3d96df4d6b1c88455e05b94ce8a14a53 https://conda.anaconda.org/conda-forge/linux-64/libpq-17.7-h5c52fec_1.conda#a4769024afeab4b32ac8167c2f92c7ac https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -209,15 +204,15 @@ https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.11-h4df99d1_100.co https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-h8d10470_4.conda#e6d46d70c68d0eb69b9a040ebe3acddf https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.31.0-h55f77e1_4.conda#0627af705ed70681f5bede31e72348e5 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.29.7-hd92328a_7.conda#02b95564257d5c3db9c06beccf711f95 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.13.0-h3cf044e_1.conda#7eb66060455c7a47d9dcdbfa9f46579b https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.36.0-h0121fbd_0.conda#fc5efe1833a4d709953964037985bb72 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.32.0-h0121fbd_0.conda#877a5ec0431a5af83bf0cd0522bfe661 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha770c72_17.conda#e4ab075598123e783b788b995afbdad0 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.510-h37a5c72_3.conda#beb8577571033140c6897d257acc7724 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.458-hc430e4a_4.conda#aeefac461bea1f126653c1285cf5af08 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.12.0-ha633028_1.conda#7c1980f89dd41b097549782121a73490 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-37_h5875eb1_mkl.conda#888c2ae634bce09709dffd739ba9f1bc @@ -225,33 +220,33 @@ https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2024.2.2-ha770c72_17.c https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda#af35229f34c80dcfab5a40414440df23 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-19.0.1-hc7b3859_3_cpu.conda#9ed3ded6da29dec8417f2e1db68798f2 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-18.1.0-h44a453e_6_cpu.conda#2cf6d608d6e66506f69797d5c6944c35 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-37_hfef963f_mkl.conda#f66eb9a9396715013772b8a3ef7396be https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-37_h5e43f62_mkl.conda#0c4af651539e79160cd3f0783391e918 https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda#160b41862a43936cbe509d1879d67f54 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.2-h5bd77bc_1.conda#f7bfe5b8e7641ce7d11ea10cfd9f33cc -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-19.0.1-hcb10f89_3_cpu.conda#8f8dc214d89e06933f1bc1dcd2310b9c +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-18.1.0-hcb10f89_6_cpu.conda#143f9288b64759a6427563f058c62f2b https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-37_hdba1596_mkl.conda#4e76080972d13c913f178c90726b21ce -https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-h45b15fe_0.conda#703a1ab01e36111d8bb40bc7517e900b -https://conda.anaconda.org/conda-forge/linux-64/libparquet-19.0.1-h081d1f1_3_cpu.conda#1d04307cdb1d8aeb5f55b047d5d403ea +https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.8.0-h9ddd185_2.conda#8de40c4f75d36bb00a5870f682457f1d +https://conda.anaconda.org/conda-forge/linux-64/libparquet-18.1.0-h081d1f1_6_cpu.conda#68788df49ce7480187eb6387f15b2b67 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py313hf6604e3_0.conda#07963f5dbb5351201035e1f8815ed8da -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-19.0.1-py313he5f92c8_0_cpu.conda#7d8649531c807b24295c8f9a0a396a78 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-18.1.0-py313he5f92c8_0_cpu.conda#5380e12f4468e891911dbbd4248b521a https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.2-py313ha3f37dd_1.conda#e2ec46ec4c607b97623e7b691ad31c54 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-37_hcf00494_mkl.conda#3a3a2906daecd117aad30e4d68276394 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda#6186382cb34a9953bf2a18fc763dc346 https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.6.0-py313hc2a895b_2.conda#1b3207acc9af23dcfbccb4647df0838e -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-19.0.1-hcb10f89_3_cpu.conda#a28f04b6e68a1c76de76783108ad729d -https://conda.anaconda.org/conda-forge/linux-64/libmagma_sparse-2.9.0-h45b15fe_0.conda#beac0a5bbe0af75db6b16d3d8fd24f7e +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-18.1.0-hcb10f89_6_cpu.conda#20ca46a6bc714a6ab189d5b3f46e66d8 +https://conda.anaconda.org/conda-forge/linux-64/libmagma_sparse-2.8.0-h9ddd185_0.conda#f4eb3cfeaf9d91e72d5b2b8706bf059f https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_2.conda#8a69ea71fdd37bfe42a28f0967dbb75a https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 https://conda.anaconda.org/conda-forge/linux-64/blas-2.137-mkl.conda#9deb2d32720cc73c9991dbd9e24b499e https://conda.anaconda.org/conda-forge/linux-64/cupy-13.6.0-py313h66a2ee2_2.conda#9d83bdb568a47daf7fc38117db17fe4e -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-19.0.1-h08228c5_3_cpu.conda#a58e4763af8293deaac77b63bc7804d8 -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.4.1-cuda118_mkl_hee7131c_306.conda#28b3b3da11973494ed0100aa50f47328 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-18.1.0-h3ee7192_6_cpu.conda#aa313b3168caf98d00b3753f5ba27650 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.5.1-cuda118_hb34f2e8_303.conda#da799bf557ff6376a1a58f40bddfb293 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-19.0.1-py313h78bf25f_0.conda#e8efe6998a383dd149787c83d3d6a92e -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.4.1-cuda118_mkl_py313_h909c4c2_306.conda#de6e45613bbdb51127e9ff483c31bf41 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.4.1-cuda118_mkl_hf8a3b2d_306.conda#b1802a39f1ca7ebed5f8c35755bffec1 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-18.1.0-py313h78bf25f_0.conda#a11d880ceedc33993c6f5c14a80ea9d3 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.5.1-cuda118_py313h40cdc2d_303.conda#19ad990954a4ed89358d91d0a3e7016d +https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.5.1-cuda126hf7c78f0_303.conda#afaf760e55725108ae78ed41198c49bb diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 9d60062fc285b..e532421799515 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -141,8 +141,8 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.15.0-h8dda3cd_1.conda#112b71b6af28b47c624bcbeefeea685b https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.1-py311h164a683_0.conda#b59452fef1470e7e5c34a7c5deefe853 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.7-default_he95a3c9_3.conda#71a8b7c6439119fcb9a555127d149a1a -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.7-default_h94a09a5_3.conda#b60f2316d922a558baa84ad24306bfc4 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_1.conda#3c89c40c8bc018db02008a0a7d1981de +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.8-default_h94a09a5_1.conda#9a517122495f4ba889cac130dd8ce267 https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-5_hb558247_openblas.conda#8046d5ae90150f00c8b40455d9b2e180 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.1-hf8816c8_3.conda#e0d7a6cbc0b8a6d05002cb9bd061a4af https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.328.1-h8b8848b_0.conda#e5a3ff3a266b68398bd28ed1d4363e65 diff --git a/build_tools/update_environments_and_lock_files.py b/build_tools/update_environments_and_lock_files.py index e2e9e1e722b2d..77954dee43239 100644 --- a/build_tools/update_environments_and_lock_files.py +++ b/build_tools/update_environments_and_lock_files.py @@ -84,9 +84,6 @@ docstring_test_dependencies = ["sphinx", "numpydoc"] default_package_constraints = { - # TODO: remove once https://github.com/numpy/numpydoc/issues/638 is fixed - # and released. - "numpydoc": "<1.9.0", # TODO: remove once when we're using the new way to enable coverage in subprocess # introduced in 7.0.0, see https://github.com/pytest-dev/pytest-cov?tab=readme-ov-file#upgrading-from-pytest-cov-63 "pytest-cov": "<=6.3.0", From ae4f120a87d3a1b25c4044a479138d4d2f6bb33d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Jan 2026 17:36:05 +0100 Subject: [PATCH 111/462] Bump the actions group with 7 updates (#32981) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/autoclose-schedule.yml | 4 ++-- .github/workflows/bot-lint-comment.yml | 4 ++-- .github/workflows/check-changelog.yml | 2 +- .github/workflows/check-sdist.yml | 2 +- .github/workflows/codeql.yml | 2 +- .github/workflows/codespell.yml | 2 +- .github/workflows/cuda-ci.yml | 10 +++++----- .github/workflows/emscripten.yml | 12 ++++++------ .github/workflows/labeler-title-regex.yml | 2 +- .github/workflows/lint.yml | 4 ++-- .github/workflows/publish_pypi.yml | 2 +- .github/workflows/unit-tests.yml | 8 ++++---- .github/workflows/update-lock-files.yml | 4 ++-- .github/workflows/update_tracking_issue.yml | 2 +- .github/workflows/wheels.yml | 14 +++++++------- 15 files changed, 37 insertions(+), 37 deletions(-) diff --git a/.github/workflows/autoclose-schedule.yml b/.github/workflows/autoclose-schedule.yml index 086118e15e84b..77a8eeebfc168 100644 --- a/.github/workflows/autoclose-schedule.yml +++ b/.github/workflows/autoclose-schedule.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'scikit-learn/scikit-learn' steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.13' @@ -28,7 +28,7 @@ jobs: run: pip install -Uq PyGithub - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Close PRs labeled more than 14 days ago run: | diff --git a/.github/workflows/bot-lint-comment.yml b/.github/workflows/bot-lint-comment.yml index 8832d583ca7d2..2254fcdc9c5a3 100644 --- a/.github/workflows/bot-lint-comment.yml +++ b/.github/workflows/bot-lint-comment.yml @@ -23,7 +23,7 @@ jobs: run: mkdir -p "$ARTIFACTS_DIR" - name: Download artifact - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: name: lint-log path: ${{ runner.temp }}/artifacts @@ -48,7 +48,7 @@ jobs: --jq '"PR_NUMBER=\(.number)"' \ >> $GITHUB_ENV - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: sparse-checkout: build_tools/get_comment.py diff --git a/.github/workflows/check-changelog.yml b/.github/workflows/check-changelog.yml index 7ba1bb5af2fa9..ae35483a9a614 100644 --- a/.github/workflows/check-changelog.yml +++ b/.github/workflows/check-changelog.yml @@ -14,7 +14,7 @@ jobs: name: A reviewer will let you know if it is required or can be bypassed runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: '0' - name: Check if tests have changed diff --git a/.github/workflows/check-sdist.yml b/.github/workflows/check-sdist.yml index ca886ea9aca2b..2990611cce4ef 100644 --- a/.github/workflows/check-sdist.yml +++ b/.github/workflows/check-sdist.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.11' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 1981d3138e48b..c180fb3e10942 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -37,7 +37,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index fc927c4cc3cc9..55fe4fceb5f79 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Annotate locations with typos uses: codespell-project/codespell-problem-matcher@v1 - name: Codespell diff --git a/.github/workflows/cuda-ci.yml b/.github/workflows/cuda-ci.yml index 4f87cbff95737..f67b774ecbe7c 100644 --- a/.github/workflows/cuda-ci.yml +++ b/.github/workflows/cuda-ci.yml @@ -15,17 +15,17 @@ jobs: runs-on: "ubuntu-latest" name: Build wheel for Pull Request steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Build wheels - uses: pypa/cibuildwheel@9c00cb4f6b517705a3794b22395aedc36257242c # v3.2.1 + uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 env: CIBW_BUILD: cp313-manylinux_x86_64 CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 CIBW_BUILD_VERBOSITY: 1 CIBW_ARCHS: x86_64 - - uses: actions/upload-artifact@v5 + - uses: actions/upload-artifact@v6 with: name: cibw-wheels path: ./wheelhouse/*.whl @@ -40,7 +40,7 @@ jobs: timeout-minutes: 20 name: Run Array API unit tests steps: - - uses: actions/download-artifact@v6 + - uses: actions/download-artifact@v7 with: pattern: cibw-wheels path: ~/dist @@ -51,7 +51,7 @@ jobs: # https://github.com/actions/setup-python/issues/886 python-version: '3.12.3' - name: Checkout main repository - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Install miniforge run: bash build_tools/github/create_gpu_environment.sh - name: Install scikit-learn diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index 2349f44b18135..590aed14afcde 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -35,7 +35,7 @@ jobs: build: ${{ steps.check_build_trigger.outputs.build }} steps: - name: Checkout scikit-learn - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }} persist-credentials: false @@ -63,11 +63,11 @@ jobs: if: needs.check_build_trigger.outputs.build steps: - name: Checkout scikit-learn - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: persist-credentials: false - - uses: pypa/cibuildwheel@9c00cb4f6b517705a3794b22395aedc36257242c # v3.2.1 + - uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 env: CIBW_PLATFORM: pyodide SKLEARN_SKIP_OPENMP_TEST: "true" @@ -77,7 +77,7 @@ jobs: CIBW_TEST_COMMAND: "python -m pytest -sra --pyargs sklearn --durations 20 --showlocals" - name: Upload wheel artifact - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: pyodide_wheel path: ./wheelhouse/*.whl @@ -94,13 +94,13 @@ jobs: if: github.repository == 'scikit-learn/scikit-learn' && github.event_name != 'pull_request' steps: - name: Download wheel artifact - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: path: wheelhouse/ merge-multiple: true - name: Push to Anaconda PyPI index - uses: scientific-python/upload-nightly-action@b36e8c0c10dbcfd2e05bf95f17ef8c14fd708dbf # 0.6.2 + uses: scientific-python/upload-nightly-action@5748273c71e2d8d3a61f3a11a16421c8954f9ecf # 0.6.3 with: artifacts_path: wheelhouse/ anaconda_nightly_upload_token: ${{ secrets.SCIKIT_LEARN_NIGHTLY_UPLOAD_TOKEN }} diff --git a/.github/workflows/labeler-title-regex.yml b/.github/workflows/labeler-title-regex.yml index 798a9ea4a493a..b589e0de70c06 100644 --- a/.github/workflows/labeler-title-regex.yml +++ b/.github/workflows/labeler-title-regex.yml @@ -15,7 +15,7 @@ jobs: labeler: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.9' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0d7de560ace6c..2c29a4d0923d4 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }} @@ -48,7 +48,7 @@ jobs: - name: Upload Artifact if: always() - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: lint-log path: | diff --git a/.github/workflows/publish_pypi.yml b/.github/workflows/publish_pypi.yml index b65bd4a67ef54..07db8cfe47c66 100644 --- a/.github/workflows/publish_pypi.yml +++ b/.github/workflows/publish_pypi.yml @@ -18,7 +18,7 @@ jobs: # IMPORTANT: this permission is mandatory for trusted publishing id-token: write steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.8' diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 5d91ee3ad2217..53a1064c159e6 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.12' @@ -53,7 +53,7 @@ jobs: outputs: message: ${{ steps.git-log.outputs.message }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }} - id: git-log @@ -155,10 +155,10 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Create cache for ccache - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ${{ env.CCACHE_DIR }} key: ccache-v1-${{ matrix.name }}-${{ hashFiles('**/*.pyx*', '**/*.pxd*', '**/*.pxi*', '**/*.h', '**/*.c', '**/*.cpp', format('{0}', matrix.LOCK_FILE)) }} diff --git a/.github/workflows/update-lock-files.yml b/.github/workflows/update-lock-files.yml index b6e916851f586..c11d7a03a52f8 100644 --- a/.github/workflows/update-lock-files.yml +++ b/.github/workflows/update-lock-files.yml @@ -31,7 +31,7 @@ jobs: update_script_args: "--select-tag cuda" steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Generate lock files run: | source build_tools/shared.sh @@ -45,7 +45,7 @@ jobs: - name: Create Pull Request id: cpr - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@v8 with: token: ${{ secrets.BOT_GITHUB_TOKEN }} push-to-fork: scikit-learn-bot/scikit-learn diff --git a/.github/workflows/update_tracking_issue.yml b/.github/workflows/update_tracking_issue.yml index e130f3847864d..207446143a278 100644 --- a/.github/workflows/update_tracking_issue.yml +++ b/.github/workflows/update_tracking_issue.yml @@ -29,7 +29,7 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'scikit-learn/scikit-learn' && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.9' diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index db0bc4da3f2cb..5c08cc860415b 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -34,7 +34,7 @@ jobs: steps: - name: Checkout scikit-learn - uses: actions/checkout@v5 + uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha }} @@ -199,7 +199,7 @@ jobs: steps: - name: Checkout scikit-learn - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup Python uses: actions/setup-python@v6 @@ -243,7 +243,7 @@ jobs: run: bash build_tools/wheels/build_wheels.sh - name: Store artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: cibw-wheels-cp${{ matrix.python }}-${{ matrix.platform_id }} path: wheelhouse/*.whl @@ -266,7 +266,7 @@ jobs: steps: - name: Checkout scikit-learn - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup Python uses: actions/setup-python@v6 @@ -282,7 +282,7 @@ jobs: SKLEARN_SKIP_NETWORK_TESTS: 1 - name: Store artifacts - uses: actions/upload-artifact@v5 + uses: actions/upload-artifact@v6 with: name: cibw-sdist path: dist/*.tar.gz @@ -298,10 +298,10 @@ jobs: steps: - name: Checkout scikit-learn - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Download artifacts - uses: actions/download-artifact@v6 + uses: actions/download-artifact@v7 with: pattern: cibw-* path: dist From 66fbe2dcf91d8f9ff3e827856fb2e4f90b57ddc2 Mon Sep 17 00:00:00 2001 From: John Hendricks Date: Thu, 8 Jan 2026 12:20:36 -0500 Subject: [PATCH 112/462] MNT Add option to raise when all sample weights are 0 in `_check_sample_weight` (#32212) Co-authored-by: John Hendricks Co-authored-by: Olivier Grisel --- .../many-modules/32212.fix.rst | 5 ++++ .../sklearn.svm/32212.fix.rst | 2 ++ sklearn/linear_model/_stochastic_gradient.py | 10 +++++++- sklearn/svm/src/libsvm/svm.cpp | 3 ++- sklearn/svm/tests/test_svm.py | 6 ++++- sklearn/tests/test_common.py | 16 +++++++++++++ .../utils/_test_common/instance_generator.py | 4 ++++ sklearn/utils/estimator_checks.py | 23 +++++++++++++++++++ sklearn/utils/stats.py | 3 +++ sklearn/utils/tests/test_stats.py | 6 ++--- sklearn/utils/tests/test_validation.py | 7 ++++++ sklearn/utils/validation.py | 10 ++++++++ 12 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/many-modules/32212.fix.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.svm/32212.fix.rst diff --git a/doc/whats_new/upcoming_changes/many-modules/32212.fix.rst b/doc/whats_new/upcoming_changes/many-modules/32212.fix.rst new file mode 100644 index 0000000000000..fbfaa4560aae8 --- /dev/null +++ b/doc/whats_new/upcoming_changes/many-modules/32212.fix.rst @@ -0,0 +1,5 @@ +- Raise ValueError when `sample_weight` contains only zero values to prevent + meaningless input data during fitting. This change applies to all estimators that + support the parameter `sample_weight`. This change also affects metrics that validate + sample weights. + By :user:`Lucy Liu ` and :user:`John Hendricks `. diff --git a/doc/whats_new/upcoming_changes/sklearn.svm/32212.fix.rst b/doc/whats_new/upcoming_changes/sklearn.svm/32212.fix.rst new file mode 100644 index 0000000000000..40cf076951315 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.svm/32212.fix.rst @@ -0,0 +1,2 @@ +- Raise more informative error when fitting :class:`NuSVR` with all zero sample weights. + By :user:`Lucy Liu ` and :user:`John Hendricks `. diff --git a/sklearn/linear_model/_stochastic_gradient.py b/sklearn/linear_model/_stochastic_gradient.py index 1c969dc1a141a..9be78917f299c 100644 --- a/sklearn/linear_model/_stochastic_gradient.py +++ b/sklearn/linear_model/_stochastic_gradient.py @@ -627,7 +627,15 @@ def _partial_fit( self._expanded_class_weight = compute_class_weight( self.class_weight, classes=self.classes_, y=y ) - sample_weight = _check_sample_weight(sample_weight, X, dtype=X.dtype) + + # Skip check that validation weights are not all zero when `early_stopping` is + # set to True as `_make_validation_split` will raise a more informative error. + sample_weight = _check_sample_weight( + sample_weight, + X, + dtype=X.dtype, + allow_all_zero_weights=self.early_stopping, + ) if getattr(self, "coef_", None) is None or coef_init is not None: self._allocate_parameter_mem( diff --git a/sklearn/svm/src/libsvm/svm.cpp b/sklearn/svm/src/libsvm/svm.cpp index be05e7ece5539..4072c89edba32 100644 --- a/sklearn/svm/src/libsvm/svm.cpp +++ b/sklearn/svm/src/libsvm/svm.cpp @@ -3137,7 +3137,8 @@ const char *PREFIX(check_parameter)(const PREFIX(problem) *prob, const svm_param if(svm_type == C_SVC || svm_type == EPSILON_SVR || svm_type == NU_SVR || - svm_type == ONE_CLASS) + svm_type == ONE_CLASS || + svm_type == NU_SVC) { PREFIX(problem) newprob; // filter samples with negative and null weights diff --git a/sklearn/svm/tests/test_svm.py b/sklearn/svm/tests/test_svm.py index 1da2c74d3f07d..6bb5d5b00d641 100644 --- a/sklearn/svm/tests/test_svm.py +++ b/sklearn/svm/tests/test_svm.py @@ -593,7 +593,11 @@ def test_svm_equivalence_sample_weight_C(): "Estimator, err_msg", [ (svm.SVC, "Invalid input - all samples have zero or negative weights."), - (svm.NuSVC, "(negative dimensions are not allowed|nu is infeasible)"), + ( + svm.NuSVC, + "(Invalid input - all samples have zero or negative weights.|nu is" + " infeasible)", + ), (svm.SVR, "Invalid input - all samples have zero or negative weights."), (svm.NuSVR, "Invalid input - all samples have zero or negative weights."), (svm.OneClassSVM, "Invalid input - all samples have zero or negative weights."), diff --git a/sklearn/tests/test_common.py b/sklearn/tests/test_common.py index ea0a566fefbfe..4d57a54c5e6ff 100644 --- a/sklearn/tests/test_common.py +++ b/sklearn/tests/test_common.py @@ -45,6 +45,7 @@ ignore_warnings, ) from sklearn.utils.estimator_checks import ( + check_all_zero_sample_weights_error, check_dataframe_column_names_consistency, check_estimator, check_get_feature_names_out_error, @@ -59,6 +60,7 @@ check_transformer_get_feature_names_out_pandas, parametrize_with_checks, ) +from sklearn.utils.validation import has_fit_parameter @pytest.mark.thread_unsafe # import side-effects @@ -399,3 +401,17 @@ def test_check_inplace_ensure_writeable(estimator): estimator.set_params(kernel="precomputed") check_inplace_ensure_writeable(name, estimator) + + +ESTIMATORS_ACCEPTING_SAMPLE_WEIGHTS = [ + est for est in _tested_estimators() if has_fit_parameter(est, "sample_weight") +] + + +@pytest.mark.parametrize( + "estimator", ESTIMATORS_ACCEPTING_SAMPLE_WEIGHTS, ids=_get_check_estimator_ids +) +def test_check_all_zero_sample_weights_error(estimator): + name = estimator.__class__.__name__ + + check_all_zero_sample_weights_error(name, estimator) diff --git a/sklearn/utils/_test_common/instance_generator.py b/sklearn/utils/_test_common/instance_generator.py index 176d1ab070ca6..f7b3c7b36d38b 100644 --- a/sklearn/utils/_test_common/instance_generator.py +++ b/sklearn/utils/_test_common/instance_generator.py @@ -1175,6 +1175,10 @@ def _yield_instances_for_check(check, estimator_orig): "check_sample_weight_equivalence_on_sparse_data": ( "sample_weight is not equivalent to removing/repeating samples." ), + # TODO: error raised by all zero sample weights will be addressed by PR #31529 + "check_classifiers_one_label_sample_weights": ( + "failed when fitted on one label after sample_weight trimming." + ), }, RandomForestRegressor: { # TODO: replace by a statistical test, see meta-issue #16298 diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index 3d166d875fb6c..d0e2adb089d9d 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -157,6 +157,7 @@ def _yield_checks(estimator): yield check_sample_weights_pandas_series yield check_sample_weights_not_an_array yield check_sample_weights_list + yield check_all_zero_sample_weights_error if not tags.input_tags.pairwise: # We skip pairwise because the data is not pairwise yield check_sample_weights_shape @@ -1507,6 +1508,28 @@ def check_sample_weights_list(name, estimator_orig): estimator.fit(X, y, sample_weight=sample_weight) +@ignore_warnings(category=FutureWarning) +def check_all_zero_sample_weights_error(name, estimator_orig): + """Check that estimator raises error when all sample weights are 0.""" + estimator = clone(estimator_orig) + + X, y = make_classification(random_state=42) + X = _enforce_estimator_tags_X(estimator, X) + y = _enforce_estimator_tags_y(estimator, y) + + sample_weight = np.zeros(_num_samples(X)) + + # The following estimators have custom error messages: + # - NuSVC: Invalid input - all samples have zero or negative weights. + # - Perceptron: The sample weights for validation set are all zero, consider using + # a different random state. + # - SGDClassifier: The sample weights for validation set are all zero, consider + # using a different random state. + # All other estimators: Sample weights must contain at least one non-zero number. + with raises(ValueError, match=r"(.*weight.*zero.*)|(.*zero.*weight.*)"): + estimator.fit(X, y, sample_weight=sample_weight) + + @ignore_warnings(category=FutureWarning) def check_sample_weights_shape(name, estimator_orig): # check that estimators raise an error if sample_weight diff --git a/sklearn/utils/stats.py b/sklearn/utils/stats.py index 453b0ab122c37..71fa1418e235e 100644 --- a/sklearn/utils/stats.py +++ b/sklearn/utils/stats.py @@ -97,6 +97,9 @@ def _weighted_percentile( sample_weight = xp.asarray(sample_weight, dtype=floating_dtype, device=device) percentile_rank = xp.asarray(percentile_rank, dtype=floating_dtype, device=device) + if xp.all(sample_weight == 0): + return xp.nan + n_dim = array.ndim if n_dim == 0: return array diff --git a/sklearn/utils/tests/test_stats.py b/sklearn/utils/tests/test_stats.py index 830a08295024e..60e1c2acc0945 100644 --- a/sklearn/utils/tests/test_stats.py +++ b/sklearn/utils/tests/test_stats.py @@ -99,14 +99,12 @@ def test_weighted_percentile_equal(): assert approx(score) == 0 -# XXX: is this really what we want? Shouldn't we raise instead? -# https://github.com/scikit-learn/scikit-learn/issues/31032 def test_weighted_percentile_all_zero_weights(): - """Check `weighted_percentile` with all weights equal to 0 returns last index.""" + """Check `weighted_percentile` with all weights equal to 0 returns `np.nan`.""" y = np.arange(10) sw = np.zeros(10) value = _weighted_percentile(y, sw, 50) - assert approx(value) == 9.0 + assert np.isnan(value) @pytest.mark.parametrize("average", [True, False]) diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index b029cab433eb9..19d1ca5e5f3e9 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -1628,6 +1628,13 @@ def _check_sample_weight_common(xp): with pytest.raises(ValueError, match=err_msg): _check_sample_weight(sample_weight, X, ensure_non_negative=True) + # check error raised when allow_all_zero_weights=False + X = xp.ones((5, 2)) + sample_weight = xp.zeros(_num_samples(X)) + err_msg = "Sample weights must contain at least one non-zero number." + with pytest.raises(ValueError, match=err_msg): + _check_sample_weight(sample_weight, X, allow_all_zero_weights=False) + def test_check_sample_weight(): # check array order diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index 0e59bde2c02dc..163542a2409ed 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -2085,6 +2085,7 @@ def _check_sample_weight( ensure_non_negative=False, ensure_same_device=True, copy=False, + allow_all_zero_weights=False, ): """Validate sample weights. @@ -2127,6 +2128,9 @@ def _check_sample_weight( copy : bool, default=False If True, a copy of sample_weight will be created. + allow_all_zero_weights : bool, default=False, + Whether or not to raise an error when sample weights are all zero. + Returns ------- sample_weight : ndarray of shape (n_samples,) @@ -2175,6 +2179,12 @@ def _check_sample_weight( ) ) + if not allow_all_zero_weights: + if xp.all(sample_weight == 0): + raise ValueError( + "Sample weights must contain at least one non-zero number." + ) + if ensure_non_negative: check_non_negative(sample_weight, "`sample_weight`") From 66200f149ba6c64a3a93dd73e37bdeea87bb5db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Fri, 9 Jan 2026 14:17:58 +0100 Subject: [PATCH 113/462] CI List failed tests in tracking issue for unit-tests GHA (#33027) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- .github/workflows/unit-tests.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 53a1064c159e6..1d14bc58932dd 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -20,6 +20,7 @@ env: TEST_DIR: ${{ github.workspace }}/tmp_folder CCACHE_DIR: ${{ github.workspace }}/ccache COVERAGE: 'true' + JUNITXML: 'test-data.xml' jobs: lint: @@ -209,11 +210,6 @@ jobs: if: ${{ always() && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')}} run: | set -ex - if [[ ${{ job.status }} == "success" ]]; then - TESTS_PASSED=true - else - TESTS_PASSED=false - fi pip install defusedxml PyGithub python maint_tools/update_tracking_issue.py \ @@ -221,6 +217,6 @@ jobs: "$GITHUB_WORKFLOW ${{ matrix.name }}" \ "$GITHUB_REPOSITORY" \ https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID \ - --tests-passed $TESTS_PASSED \ + --junit-file $TEST_DIR/$JUNITXML \ --auto-close false \ --job-name "${{ matrix.name }}" From 762734097daa72f6bd1b363ac989afa4717530f7 Mon Sep 17 00:00:00 2001 From: Arthur Lacote Date: Sat, 10 Jan 2026 16:50:06 +0100 Subject: [PATCH 114/462] MNT: trees/forests/GBT: deprecate `"friedman_mse"` criterion (#32708) Co-authored-by: Christian Lorentzen Co-authored-by: Olivier Grisel --- doc/modules/model_evaluation.rst | 2 +- doc/modules/tree.rst | 2 +- .../sklearn.ensemble/32708.api.rst | 6 ++ .../sklearn.ensemble/32708.fix.rst | 7 +++ .../sklearn.tree/32708.api.rst | 9 +++ .../plot_gradient_boosting_quantile.py | 10 ++-- sklearn/ensemble/_forest.py | 34 ++++++------ sklearn/ensemble/_gb.py | 51 ++++++++++------- sklearn/ensemble/tests/test_forest.py | 6 +- .../ensemble/tests/test_gradient_boosting.py | 51 ++++------------- .../tests/test_partial_dependence.py | 1 - sklearn/tree/_classes.py | 46 ++++++++++------ sklearn/tree/_criterion.pyx | 55 ------------------- sklearn/tree/_export.py | 4 +- sklearn/tree/tests/test_export.py | 29 +++++----- sklearn/tree/tests/test_tree.py | 23 ++++++++ .../utils/_test_common/instance_generator.py | 2 - 17 files changed, 156 insertions(+), 182 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.ensemble/32708.api.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.ensemble/32708.fix.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/32708.api.rst diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index 86e46d562db26..823c41ac8f664 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -2987,7 +2987,7 @@ quantile regressor via cross-validation: ... random_state=0, ... ) >>> cross_val_score(estimator, X, y, cv=5, scoring=mean_pinball_loss_95p) - array([13.6, 9.7, 23.3, 9.5, 10.4]) + array([14.3, 9.8, 23.9, 9.4, 10.8]) It is also possible to build scorer objects for hyper-parameter tuning. The sign of the loss must be switched to ensure that greater means better as diff --git a/doc/modules/tree.rst b/doc/modules/tree.rst index 756d1305c19ef..4f0d26a9dfbfb 100644 --- a/doc/modules/tree.rst +++ b/doc/modules/tree.rst @@ -649,7 +649,7 @@ non-missing values, see the :ref:`Forest section `. The criterion supported when there are missing values are `'gini'`, `'entropy'`, or `'log_loss'`, for classification or -`'squared_error'`, `'friedman_mse'`, or `'poisson'` for regression. +`'squared_error'` or `'poisson'` for regression. First we will describe how :class:`DecisionTreeClassifier`, :class:`DecisionTreeRegressor` handle missing-values in the data. diff --git a/doc/whats_new/upcoming_changes/sklearn.ensemble/32708.api.rst b/doc/whats_new/upcoming_changes/sklearn.ensemble/32708.api.rst new file mode 100644 index 0000000000000..69bac5a1ae540 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.ensemble/32708.api.rst @@ -0,0 +1,6 @@ +- The `criterion` parameter is now deprecated for classes + :class:`ensemble.GradientBoostingRegressor` + and :class:`ensemble.GradientBoostingClassifier`, as both options + (`"friedman_mse"` and `"squared_error"`) were producing the same results, + up to floating-point rounding discrepancies and a bug in `"friedman_mse"`. + By :user:`Arthur Lacote ` diff --git a/doc/whats_new/upcoming_changes/sklearn.ensemble/32708.fix.rst b/doc/whats_new/upcoming_changes/sklearn.ensemble/32708.fix.rst new file mode 100644 index 0000000000000..f80975de936b7 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.ensemble/32708.fix.rst @@ -0,0 +1,7 @@ +- Both :class:`ensemble.GradientBoostingRegressor` and + :class:`ensemble.GradientBoostingClassifier` with the default + `"friedman_mse"` criterion were computing impurity values with an incorrect scaling, + leading to unexpected trees in some cases. The implementation now uses + `"squared_error"`, which is exactly equivalent to `"friedman_mse"` up to + floating-point error discrepancies but computes correct impurity values. + By :user:`Arthur Lacote `. diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/32708.api.rst b/doc/whats_new/upcoming_changes/sklearn.tree/32708.api.rst new file mode 100644 index 0000000000000..fd18524f24b36 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.tree/32708.api.rst @@ -0,0 +1,9 @@ +- `criterion="friedman_mse"` is now deprecated. This criterion was intended for + gradient boosting but was incorrectly implemented in scikit-learn's trees and + was actually behaving identically to `criterion="squared_error"`. Use + `criterion="squared_error"` instead. This affects: + - :class:`tree.DecisionTreeRegressor` + - :class:`tree.ExtraTreeRegressor` + - :class:`ensemble.RandomForestRegressor` + - :class:`ensemble.ExtraTreesRegressor` + By :user:`Arthur Lacote ` diff --git a/examples/ensemble/plot_gradient_boosting_quantile.py b/examples/ensemble/plot_gradient_boosting_quantile.py index dbe3a99b045dd..37d897449cc97 100644 --- a/examples/ensemble/plot_gradient_boosting_quantile.py +++ b/examples/ensemble/plot_gradient_boosting_quantile.py @@ -52,13 +52,13 @@ def f(x): # Fitting non-linear quantile and least squares regressors # -------------------------------------------------------- # -# Fit gradient boosting models trained with the quantile loss and -# alpha=0.05, 0.5, 0.95. +# Fit gradient boosting models trained with the quantile loss and `alpha=0.05`, +# `alpha=0.5`, `alpha=0.95`. # -# The models obtained for alpha=0.05 and alpha=0.95 produce a 90% confidence -# interval (95% - 5% = 90%). +# The models obtained for `alpha=0.05` and `alpha=0.95` produce a 90% +# confidence interval (95% - 5% = 90%). # -# The model trained with alpha=0.5 produces a regression of the median: on +# The model trained with `alpha=0.5` produces a regression of the median: on # average, there should be the same number of target observations above and # below the predicted values. from sklearn.ensemble import GradientBoostingRegressor diff --git a/sklearn/ensemble/_forest.py b/sklearn/ensemble/_forest.py index dd72224107f37..b7b4707dcaa0e 100644 --- a/sklearn/ensemble/_forest.py +++ b/sklearn/ensemble/_forest.py @@ -1603,18 +1603,14 @@ class RandomForestRegressor(ForestRegressor): The default value of ``n_estimators`` changed from 10 to 100 in 0.22. - criterion : {"squared_error", "absolute_error", "friedman_mse", "poisson"}, \ - default="squared_error" + criterion : {"squared_error", "absolute_error", "poisson"}, default="squared_error" The function to measure the quality of a split. Supported criteria are "squared_error" for the mean squared error, which is equal to variance reduction as feature selection criterion and minimizes the L2 - loss using the mean of each terminal node, "friedman_mse", which uses - mean squared error with Friedman's improvement score for potential - splits, "absolute_error" for the mean absolute error, which minimizes - the L1 loss using the median of each terminal node, and "poisson" which - uses reduction in Poisson deviance to find splits. - Training using "absolute_error" is significantly slower - than when using "squared_error". + loss using the mean of each terminal node, "absolute_error" for the mean + absolute error, which minimizes the L1 loss using the median of each terminal + node, and "poisson" which uses reduction in Poisson deviance to find splits, + also using the mean of each terminal node. .. versionadded:: 0.18 Mean Absolute Error (MAE) criterion. @@ -1622,6 +1618,9 @@ class RandomForestRegressor(ForestRegressor): .. versionadded:: 1.0 Poisson criterion. + .. versionchanged:: 1.9 + Criterion `"friedman_mse"` was deprecated. + max_depth : int, default=None The maximum depth of the tree. If None, then nodes are expanded until all leaves are pure or until all leaves contain less than @@ -2353,22 +2352,21 @@ class ExtraTreesRegressor(ForestRegressor): The default value of ``n_estimators`` changed from 10 to 100 in 0.22. - criterion : {"squared_error", "absolute_error", "friedman_mse", "poisson"}, \ - default="squared_error" + criterion : {"squared_error", "absolute_error", "poisson"}, default="squared_error" The function to measure the quality of a split. Supported criteria are "squared_error" for the mean squared error, which is equal to variance reduction as feature selection criterion and minimizes the L2 - loss using the mean of each terminal node, "friedman_mse", which uses - mean squared error with Friedman's improvement score for potential - splits, "absolute_error" for the mean absolute error, which minimizes - the L1 loss using the median of each terminal node, and "poisson" which - uses reduction in Poisson deviance to find splits. - Training using "absolute_error" is significantly slower - than when using "squared_error". + loss using the mean of each terminal node, "absolute_error" for the mean + absolute error, which minimizes the L1 loss using the median of each terminal + node, and "poisson" which uses reduction in Poisson deviance to find splits, + also using the mean of each terminal node. .. versionadded:: 0.18 Mean Absolute Error (MAE) criterion. + .. versionchanged:: 1.9 + Criterion `"friedman_mse"` was deprecated. + max_depth : int, default=None The maximum depth of the tree. If None, then nodes are expanded until all leaves are pure or until all leaves contain less than diff --git a/sklearn/ensemble/_gb.py b/sklearn/ensemble/_gb.py index ba515b4bbcea9..9ec8030899d18 100644 --- a/sklearn/ensemble/_gb.py +++ b/sklearn/ensemble/_gb.py @@ -52,7 +52,7 @@ from sklearn.tree import DecisionTreeRegressor from sklearn.tree._tree import DOUBLE, DTYPE, TREE_LEAF from sklearn.utils import check_array, check_random_state, column_or_1d -from sklearn.utils._param_validation import HasMethods, Interval, StrOptions +from sklearn.utils._param_validation import HasMethods, Hidden, Interval, StrOptions from sklearn.utils.multiclass import check_classification_targets from sklearn.utils.stats import _weighted_percentile from sklearn.utils.validation import ( @@ -365,7 +365,10 @@ class BaseGradientBoosting(BaseEnsemble, metaclass=ABCMeta): **DecisionTreeRegressor._parameter_constraints, "learning_rate": [Interval(Real, 0.0, None, closed="left")], "n_estimators": [Interval(Integral, 1, None, closed="left")], - "criterion": [StrOptions({"friedman_mse", "squared_error"})], + "criterion": [ + StrOptions({"squared_error"}), + Hidden(StrOptions({"deprecated", "friedman_mse"})), + ], "subsample": [Interval(Real, 0.0, 1.0, closed="right")], "verbose": ["verbose"], "warm_start": ["boolean"], @@ -383,7 +386,6 @@ def __init__( loss, learning_rate, n_estimators, - criterion, min_samples_split, min_samples_leaf, min_weight_fraction_leaf, @@ -401,6 +403,7 @@ def __init__( validation_fraction=0.1, n_iter_no_change=None, tol=1e-4, + criterion="deprecated", ): self.n_estimators = n_estimators self.learning_rate = learning_rate @@ -476,7 +479,7 @@ def _fit_stage( # induce regression tree on the negative gradient tree = DecisionTreeRegressor( - criterion=self.criterion, + criterion="squared_error", splitter="best", max_depth=self.max_depth, min_samples_split=self.min_samples_split, @@ -659,6 +662,14 @@ def fit(self, X, y, sample_weight=None, monitor=None): if not self.warm_start: self._clear_state() + if self.criterion != "deprecated": + warnings.warn( + "The parameter `criterion` is deprecated and will be " + "removed in 1.11. It has no effect. Leave it to its default value to " + "avoid this warning.", + FutureWarning, + ) + # Check input # Since check_array converts both X and y to the same dtype, but the # trees use different types for X and y, checking them separately. @@ -1013,7 +1024,7 @@ def feature_importances_(self): The higher, the more important the feature. The importance of a feature is computed as the (normalized) - total reduction of the criterion brought by that feature. It is also + total reduction of the MSE brought by that feature. It is also known as the Gini importance. Warning: impurity-based feature importances can be misleading for @@ -1179,14 +1190,13 @@ class GradientBoostingClassifier(ClassifierMixin, BaseGradientBoosting): Values must be in the range `(0.0, 1.0]`. criterion : {'friedman_mse', 'squared_error'}, default='friedman_mse' - The function to measure the quality of a split. Supported criteria are - 'friedman_mse' for the mean squared error with improvement score by - Friedman, 'squared_error' for mean squared error. The default value of - 'friedman_mse' is generally the best as it can provide a better - approximation in some cases. + This parameter has no effect. .. versionadded:: 0.18 + .. deprecated:: 1.9 + `criterion` is deprecated and will be removed in 1.11. + min_samples_split : int or float, default=2 The minimum number of samples required to split an internal node: @@ -1354,7 +1364,7 @@ class GradientBoostingClassifier(ClassifierMixin, BaseGradientBoosting): The impurity-based feature importances. The higher, the more important the feature. The importance of a feature is computed as the (normalized) - total reduction of the criterion brought by that feature. It is also + total reduction of the MSE brought by that feature. It is also known as the Gini importance. Warning: impurity-based feature importances can be misleading for @@ -1432,7 +1442,7 @@ class GradientBoostingClassifier(ClassifierMixin, BaseGradientBoosting): ----- The features are always randomly permuted at each split. Therefore, the best found split may vary, even with the same training data and - ``max_features=n_features``, if the improvement of the criterion is + ``max_features=n_features``, if the improvement of the MSE is identical for several splits enumerated during the search of the best split. To obtain a deterministic behaviour during fitting, ``random_state`` has to be fixed. @@ -1478,7 +1488,7 @@ def __init__( learning_rate=0.1, n_estimators=100, subsample=1.0, - criterion="friedman_mse", + criterion="deprecated", min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, @@ -1791,14 +1801,13 @@ class GradientBoostingRegressor(RegressorMixin, BaseGradientBoosting): Values must be in the range `(0.0, 1.0]`. criterion : {'friedman_mse', 'squared_error'}, default='friedman_mse' - The function to measure the quality of a split. Supported criteria are - "friedman_mse" for the mean squared error with improvement score by - Friedman, "squared_error" for mean squared error. The default value of - "friedman_mse" is generally the best as it can provide a better - approximation in some cases. + This parameter has no effect. .. versionadded:: 0.18 + .. deprecated:: 1.9 + `criterion` is deprecated and will be removed in 1.11. + min_samples_split : int or float, default=2 The minimum number of samples required to split an internal node: @@ -1970,7 +1979,7 @@ class GradientBoostingRegressor(RegressorMixin, BaseGradientBoosting): The impurity-based feature importances. The higher, the more important the feature. The importance of a feature is computed as the (normalized) - total reduction of the criterion brought by that feature. It is also + total reduction of the MSE brought by that feature. It is also known as the Gini importance. Warning: impurity-based feature importances can be misleading for @@ -2033,7 +2042,7 @@ class GradientBoostingRegressor(RegressorMixin, BaseGradientBoosting): ----- The features are always randomly permuted at each split. Therefore, the best found split may vary, even with the same training data and - ``max_features=n_features``, if the improvement of the criterion is + ``max_features=n_features``, if the improvement of the MSE is identical for several splits enumerated during the search of the best split. To obtain a deterministic behaviour during fitting, ``random_state`` has to be fixed. @@ -2084,7 +2093,7 @@ def __init__( learning_rate=0.1, n_estimators=100, subsample=1.0, - criterion="friedman_mse", + criterion="deprecated", min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, diff --git a/sklearn/ensemble/tests/test_forest.py b/sklearn/ensemble/tests/test_forest.py index d22591d37ec9b..20a452ecb75c4 100644 --- a/sklearn/ensemble/tests/test_forest.py +++ b/sklearn/ensemble/tests/test_forest.py @@ -158,9 +158,7 @@ def test_iris_criterion(name, criterion): @pytest.mark.parametrize("name", FOREST_REGRESSORS) -@pytest.mark.parametrize( - "criterion", ("squared_error", "absolute_error", "friedman_mse") -) +@pytest.mark.parametrize("criterion", ("squared_error", "absolute_error")) def test_regression_criterion(name, criterion): # Check consistency on regression dataset. ForestRegressor = FOREST_REGRESSORS[name] @@ -294,7 +292,7 @@ def test_probability(name): "name, criterion", itertools.chain( product(FOREST_CLASSIFIERS, ["gini", "log_loss"]), - product(FOREST_REGRESSORS, ["squared_error", "friedman_mse", "absolute_error"]), + product(FOREST_REGRESSORS, ["squared_error", "absolute_error"]), ), ) def test_importances(dtype, name, criterion): diff --git a/sklearn/ensemble/tests/test_gradient_boosting.py b/sklearn/ensemble/tests/test_gradient_boosting.py index 22b455f4adbb5..5434c12b5208a 100644 --- a/sklearn/ensemble/tests/test_gradient_boosting.py +++ b/sklearn/ensemble/tests/test_gradient_boosting.py @@ -1551,12 +1551,8 @@ def test_squared_error_exact_backward_compat(): assert_allclose(gbt.train_score_[-10:], train_score, rtol=1e-3, atol=1e-11) -@skip_if_32bit -def test_huber_exact_backward_compat(): - """Test huber GBT backward compat on a simple dataset. - - The results to compare against are taken from scikit-learn v1.2.0. - """ +def test_huber_overfit(): + """Test huber GBT can completely overfit""" n_samples = 10 y = np.arange(n_samples) x1 = np.minimum(y, n_samples / 2) @@ -1564,39 +1560,9 @@ def test_huber_exact_backward_compat(): X = np.c_[x1, x2] gbt = GradientBoostingRegressor(loss="huber", n_estimators=100, alpha=0.8).fit(X, y) - assert_allclose(gbt._loss.closs.delta, 0.0001655688041282133) - - pred_result = np.array( - [ - 1.48120765e-04, - 9.99949174e-01, - 2.00116957e00, - 2.99986716e00, - 4.00012064e00, - 5.00002462e00, - 5.99998898e00, - 6.99692549e00, - 8.00006356e00, - 8.99985099e00, - ] - ) - assert_allclose(gbt.predict(X), pred_result, rtol=1e-8) - - train_score = np.array( - [ - 2.59484709e-07, - 2.19165900e-07, - 1.89644782e-07, - 1.64556454e-07, - 1.38705110e-07, - 1.20373736e-07, - 1.04746082e-07, - 9.13835687e-08, - 8.20245756e-08, - 7.17122188e-08, - ] - ) - assert_allclose(gbt.train_score_[-10:], train_score, rtol=1e-8) + assert gbt._loss.closs.delta < 2e-4 + assert_allclose(gbt.predict(X), y, atol=0.01) + assert np.all(gbt.train_score_[-10:] < 3e-7) def test_binomial_error_exact_backward_compat(): @@ -1715,3 +1681,10 @@ def test_gb_denominator_zero(global_random_seed): with warnings.catch_warnings(): warnings.simplefilter("error") clf.fit(X, y) + + +@pytest.mark.parametrize("GradientBoosting", GRADIENT_BOOSTING_ESTIMATORS) +def test_criterion_param_deprecation(GradientBoosting): + with pytest.warns(FutureWarning, match="criterion"): + reg = GradientBoosting(criterion="friedman_mse") + reg.fit(X, y) diff --git a/sklearn/inspection/tests/test_partial_dependence.py b/sklearn/inspection/tests/test_partial_dependence.py index 816fe5512edc4..914fed607d5cb 100644 --- a/sklearn/inspection/tests/test_partial_dependence.py +++ b/sklearn/inspection/tests/test_partial_dependence.py @@ -411,7 +411,6 @@ def test_recursion_decision_tree_vs_forest_and_gbdt(seed): gbdt = GradientBoostingRegressor( n_estimators=1, learning_rate=1, - criterion="squared_error", max_depth=max_depth, random_state=equiv_random_state, ) diff --git a/sklearn/tree/_classes.py b/sklearn/tree/_classes.py index 8b43680e1f5ab..98936fa5760fd 100644 --- a/sklearn/tree/_classes.py +++ b/sklearn/tree/_classes.py @@ -8,6 +8,7 @@ import copy import numbers +import warnings from abc import ABCMeta, abstractmethod from math import ceil from numbers import Integral, Real @@ -74,7 +75,6 @@ } CRITERIA_REG = { "squared_error": _criterion.MSE, - "friedman_mse": _criterion.FriedmanMSE, "absolute_error": _criterion.MAE, "poisson": _criterion.Poisson, } @@ -1118,16 +1118,14 @@ class DecisionTreeRegressor(RegressorMixin, BaseDecisionTree): Parameters ---------- - criterion : {"squared_error", "friedman_mse", "absolute_error", \ - "poisson"}, default="squared_error" + criterion : {"squared_error", "absolute_error", "poisson"}, default="squared_error" The function to measure the quality of a split. Supported criteria are "squared_error" for the mean squared error, which is equal to variance reduction as feature selection criterion and minimizes the L2 - loss using the mean of each terminal node, "friedman_mse", which uses - mean squared error with Friedman's improvement score for potential - splits, "absolute_error" for the mean absolute error, which minimizes - the L1 loss using the median of each terminal node, and "poisson" which - uses reduction in the half mean Poisson deviance to find splits. + loss using the mean of each terminal node, "absolute_error" for the mean + absolute error, which minimizes the L1 loss using the median of each terminal + node, and "poisson" which uses reduction in Poisson deviance to find splits, + also using the mean of each terminal node. .. versionadded:: 0.18 Mean Absolute Error (MAE) criterion. @@ -1135,6 +1133,9 @@ class DecisionTreeRegressor(RegressorMixin, BaseDecisionTree): .. versionadded:: 0.24 Poisson deviance criterion. + .. versionchanged:: 1.9 + Criterion `"friedman_mse"` was deprecated. + splitter : {"best", "random"}, default="best" The strategy used to choose the split at each node. Supported strategies are "best" to choose the best split and "random" to choose @@ -1338,7 +1339,7 @@ class DecisionTreeRegressor(RegressorMixin, BaseDecisionTree): _parameter_constraints: dict = { **BaseDecisionTree._parameter_constraints, "criterion": [ - StrOptions({"squared_error", "friedman_mse", "absolute_error", "poisson"}), + StrOptions({"squared_error", "absolute_error", "poisson"}), Hidden(Criterion), ], } @@ -1359,6 +1360,16 @@ def __init__( ccp_alpha=0.0, monotonic_cst=None, ): + if isinstance(criterion, str) and criterion == "friedman_mse": + # TODO(1.11): remove support of "friedman_mse" criterion. + criterion = "squared_error" + warnings.warn( + 'Value `"friedman_mse"` for `criterion` is deprecated and will be ' + 'removed in 1.11. It maps to `"squared_error"` as both ' + 'were always equivalent. Use `criterion="squared_error"` ' + "to remove this warning.", + FutureWarning, + ) super().__init__( criterion=criterion, splitter=splitter, @@ -1446,7 +1457,6 @@ def __sklearn_tags__(self): # common test to pass, specifically: check_estimators_nan_inf allow_nan = self.splitter in ("best", "random") and self.criterion in { "squared_error", - "friedman_mse", "poisson", } tags.input_tags.allow_nan = allow_nan @@ -1758,16 +1768,14 @@ class ExtraTreeRegressor(DecisionTreeRegressor): Parameters ---------- - criterion : {"squared_error", "friedman_mse", "absolute_error", "poisson"}, \ - default="squared_error" + criterion : {"squared_error", "absolute_error", "poisson"}, default="squared_error" The function to measure the quality of a split. Supported criteria are "squared_error" for the mean squared error, which is equal to variance reduction as feature selection criterion and minimizes the L2 - loss using the mean of each terminal node, "friedman_mse", which uses - mean squared error with Friedman's improvement score for potential - splits, "absolute_error" for the mean absolute error, which minimizes - the L1 loss using the median of each terminal node, and "poisson" which - uses reduction in Poisson deviance to find splits. + loss using the mean of each terminal node, "absolute_error" for the mean + absolute error, which minimizes the L1 loss using the median of each terminal + node, and "poisson" which uses reduction in Poisson deviance to find splits, + also using the mean of each terminal node. .. versionadded:: 0.18 Mean Absolute Error (MAE) criterion. @@ -1775,6 +1783,9 @@ class ExtraTreeRegressor(DecisionTreeRegressor): .. versionadded:: 0.24 Poisson deviance criterion. + .. versionchanged:: 1.9 + Criterion `"friedman_mse"` was deprecated. + splitter : {"random", "best"}, default="random" The strategy used to choose the split at each node. Supported strategies are "best" to choose the best split and "random" to choose @@ -1993,7 +2004,6 @@ def __sklearn_tags__(self): # common test to pass, specifically: check_estimators_nan_inf allow_nan = self.splitter == "random" and self.criterion in { "squared_error", - "friedman_mse", "poisson", } tags.input_tags.allow_nan = allow_nan diff --git a/sklearn/tree/_criterion.pyx b/sklearn/tree/_criterion.pyx index 4124ee2c4e374..19c0d9b03c743 100644 --- a/sklearn/tree/_criterion.pyx +++ b/sklearn/tree/_criterion.pyx @@ -1687,61 +1687,6 @@ cdef class MAE(Criterion): dest[0] = upper_bound -cdef class FriedmanMSE(MSE): - """Mean squared error impurity criterion with improvement score by Friedman. - - Uses the formula (35) in Friedman's original Gradient Boosting paper: - - diff = mean_left - mean_right - improvement = n_left * n_right * diff^2 / (n_left + n_right) - """ - - cdef float64_t proxy_impurity_improvement(self) noexcept nogil: - """Compute a proxy of the impurity reduction. - - This method is used to speed up the search for the best split. - It is a proxy quantity such that the split that maximizes this value - also maximizes the impurity improvement. It neglects all constant terms - of the impurity decrease for a given split. - - The absolute impurity improvement is only computed by the - impurity_improvement method once the best split has been found. - """ - cdef float64_t total_sum_left = 0.0 - cdef float64_t total_sum_right = 0.0 - - cdef intp_t k - cdef float64_t diff = 0.0 - - for k in range(self.n_outputs): - total_sum_left += self.sum_left[k] - total_sum_right += self.sum_right[k] - - diff = (self.weighted_n_right * total_sum_left - - self.weighted_n_left * total_sum_right) - - return diff * diff / (self.weighted_n_left * self.weighted_n_right) - - cdef float64_t impurity_improvement(self, float64_t impurity_parent, float64_t - impurity_left, float64_t impurity_right) noexcept nogil: - # Note: none of the arguments are used here - cdef float64_t total_sum_left = 0.0 - cdef float64_t total_sum_right = 0.0 - - cdef intp_t k - cdef float64_t diff = 0.0 - - for k in range(self.n_outputs): - total_sum_left += self.sum_left[k] - total_sum_right += self.sum_right[k] - - diff = (self.weighted_n_right * total_sum_left - - self.weighted_n_left * total_sum_right) / self.n_outputs - - return (diff * diff / (self.weighted_n_left * self.weighted_n_right * - self.weighted_n_node_samples)) - - cdef class Poisson(RegressionCriterion): """Half Poisson deviance as impurity criterion. diff --git a/sklearn/tree/_export.py b/sklearn/tree/_export.py index fef12fd194879..a971fe151697c 100644 --- a/sklearn/tree/_export.py +++ b/sklearn/tree/_export.py @@ -334,9 +334,7 @@ def node_to_str(self, tree, node_id, criterion): # Write impurity if self.impurity: - if isinstance(criterion, _criterion.FriedmanMSE): - criterion = "friedman_mse" - elif isinstance(criterion, _criterion.MSE) or criterion == "squared_error": + if isinstance(criterion, _criterion.MSE) or criterion == "squared_error": criterion = "squared_error" elif not isinstance(criterion, str): criterion = "impurity" diff --git a/sklearn/tree/tests/test_export.py b/sklearn/tree/tests/test_export.py index ed1f171c7b7bf..f3d0a8e2e3817 100644 --- a/sklearn/tree/tests/test_export.py +++ b/sklearn/tree/tests/test_export.py @@ -11,7 +11,6 @@ from numpy.random import RandomState from sklearn.base import is_classifier -from sklearn.ensemble import GradientBoostingClassifier from sklearn.exceptions import NotFittedError from sklearn.tree import ( DecisionTreeClassifier, @@ -21,6 +20,9 @@ plot_tree, ) +CLF_CRITERIONS = ("gini", "log_loss") +REG_CRITERIONS = ("squared_error", "absolute_error", "poisson") + # toy sample X = [[-2, -1], [-1, -1], [-1, -2], [1, 1], [1, 2], [2, 1]] y = [-1, -1, -1, 1, 1, 1] @@ -389,19 +391,20 @@ def test_graphviz_errors(): export_graphviz(clf, out, class_names=[]) -def test_friedman_mse_in_graphviz(): - clf = DecisionTreeRegressor(criterion="friedman_mse", random_state=0) - clf.fit(X, y) +@pytest.mark.parametrize("criterion", CLF_CRITERIONS + REG_CRITERIONS) +def test_criterion_in_gradient_boosting_graphviz(criterion): dot_data = StringIO() - export_graphviz(clf, out_file=dot_data) - clf = GradientBoostingClassifier(n_estimators=2, random_state=0) - clf.fit(X, y) - for estimator in clf.estimators_: - export_graphviz(estimator[0], out_file=dot_data) + is_reg = criterion in REG_CRITERIONS + Tree = DecisionTreeRegressor if is_reg else DecisionTreeClassifier + clf = Tree(random_state=0, criterion=criterion) + # positive values for poisson criterion: + y_ = [yi + 2 for yi in y] if is_reg else y + clf.fit(X, y_) + export_graphviz(clf, out_file=dot_data) for finding in finditer(r"\[.*?samples.*?\]", dot_data.getvalue()): - assert "friedman_mse" in finding.group() + assert criterion in finding.group() def test_precision(): @@ -411,9 +414,7 @@ def test_precision(): (rng_reg.random_sample((5, 2)), rng_clf.random_sample((1000, 4))), (rng_reg.random_sample((5,)), rng_clf.randint(2, size=(1000,))), ( - DecisionTreeRegressor( - criterion="friedman_mse", random_state=0, max_depth=1 - ), + DecisionTreeRegressor(random_state=0, max_depth=1), DecisionTreeClassifier(max_depth=1, random_state=0), ), ): @@ -436,7 +437,7 @@ def test_precision(): if is_classifier(clf): pattern = r"gini = \d+\.\d+" else: - pattern = r"friedman_mse = \d+\.\d+" + pattern = r"squared_error = \d+\.\d+" # check impurity for finding in finditer(pattern, dot_data): diff --git a/sklearn/tree/tests/test_tree.py b/sklearn/tree/tests/test_tree.py index fc1094d2555b9..eafdf7febab28 100644 --- a/sklearn/tree/tests/test_tree.py +++ b/sklearn/tree/tests/test_tree.py @@ -267,6 +267,8 @@ def test_weighted_classification_toy(): assert_array_equal(clf.predict(T), true_result, "Failed with {0}".format(name)) +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize("Tree", REG_TREES.values()) @pytest.mark.parametrize("criterion", REG_CRITERIONS) def test_regression_toy(Tree, criterion): @@ -329,6 +331,8 @@ def test_iris(): ) +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize("name, Tree", REG_TREES.items()) @pytest.mark.parametrize("criterion", REG_CRITERIONS) def test_diabetes_overfit(name, Tree, criterion): @@ -342,6 +346,8 @@ def test_diabetes_overfit(name, Tree, criterion): ) +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize("Tree", REG_TREES.values()) @pytest.mark.parametrize( "criterion, metric", @@ -946,6 +952,8 @@ def test_pickle(): ) +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize( "Tree, criterion", [ @@ -1490,6 +1498,8 @@ def test_sparse_parameters(tree_type, dataset, csc_container): assert_array_almost_equal(s.predict(X), d.predict(X)) +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize( "tree_type, criterion", list(product([tree for tree in SPARSE_TREES if tree in REG_TREES], REG_CRITERIONS)) @@ -2034,6 +2044,8 @@ def test_apply_path_readonly_all_trees(name, splitter, sparse_container): ) +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize("criterion", ["squared_error", "friedman_mse", "poisson"]) @pytest.mark.parametrize("Tree", REG_TREES.values()) def test_balance_property(criterion, Tree): @@ -2456,6 +2468,8 @@ def test_min_sample_split_1_error(Tree): tree.fit(X, y) +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize("criterion", ["squared_error", "friedman_mse"]) def test_missing_values_best_splitter_on_equal_nodes_no_missing(criterion): """Check missing values goes to correct node during predictions.""" @@ -2482,6 +2496,8 @@ def test_missing_values_best_splitter_on_equal_nodes_no_missing(criterion): assert_allclose(y_pred, [np.mean(y_equal[-4:])]) +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize("seed", range(3)) @pytest.mark.parametrize("criterion", ["squared_error", "friedman_mse"]) def test_missing_values_random_splitter_on_equal_nodes_no_missing(criterion, seed): @@ -2757,6 +2773,8 @@ def test_deterministic_pickle(): assert pickle1 == pickle2 +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize("Tree", [DecisionTreeRegressor, ExtraTreeRegressor]) @pytest.mark.parametrize( "X", @@ -3047,3 +3065,8 @@ def test_missing_values_and_constant_toy(): assert_array_equal(tree.predict(X), y) # with just one split (-> three nodes: the root + 2 leaves) assert tree.tree_.node_count == 3 + + +def test_friedman_mse_deprecation(): + with pytest.warns(FutureWarning, match="friedman_mse"): + _ = DecisionTreeRegressor(criterion="friedman_mse") diff --git a/sklearn/utils/_test_common/instance_generator.py b/sklearn/utils/_test_common/instance_generator.py index f7b3c7b36d38b..76ddbc94342da 100644 --- a/sklearn/utils/_test_common/instance_generator.py +++ b/sklearn/utils/_test_common/instance_generator.py @@ -515,13 +515,11 @@ "check_sample_weight_equivalence_on_dense_data": [ dict(criterion="squared_error"), dict(criterion="absolute_error"), - dict(criterion="friedman_mse"), dict(criterion="poisson"), ], "check_sample_weight_equivalence_on_sparse_data": [ dict(criterion="squared_error"), dict(criterion="absolute_error"), - dict(criterion="friedman_mse"), dict(criterion="poisson"), ], }, From 2e03d830a7d703558d022aae0644b66e64f04fab Mon Sep 17 00:00:00 2001 From: Bharat Raghunathan Date: Sun, 11 Jan 2026 09:35:58 -0600 Subject: [PATCH 115/462] FEA Add Array API support to `paired_manhattan_distances` (#32979) --- doc/modules/array_api.rst | 1 + doc/whats_new/upcoming_changes/array-api/32979.feature.rst | 2 ++ sklearn/metrics/pairwise.py | 3 ++- sklearn/metrics/tests/test_common.py | 2 ++ 4 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/32979.feature.rst diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index 11d7d8c37cc0d..ba8abb1056342 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -199,6 +199,7 @@ Metrics - :func:`sklearn.metrics.pairwise.manhattan_distances` - :func:`sklearn.metrics.pairwise.paired_cosine_distances` - :func:`sklearn.metrics.pairwise.paired_euclidean_distances` +- :func:`sklearn.metrics.pairwise.paired_manhattan_distances` - :func:`sklearn.metrics.pairwise.pairwise_kernels` - :func:`sklearn.metrics.pairwise.polynomial_kernel` - :func:`sklearn.metrics.pairwise.rbf_kernel` (see :ref:`device_support_for_float64`) diff --git a/doc/whats_new/upcoming_changes/array-api/32979.feature.rst b/doc/whats_new/upcoming_changes/array-api/32979.feature.rst new file mode 100644 index 0000000000000..9a719e514056a --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/32979.feature.rst @@ -0,0 +1,2 @@ +- :func:`sklearn.metrics.pairwise.paired_manhattan_distances` now supports array API + compatible inputs. By :user:`Bharat Raghunathan `. diff --git a/sklearn/metrics/pairwise.py b/sklearn/metrics/pairwise.py index 458fce2e284bb..79b1c81b9129f 100644 --- a/sklearn/metrics/pairwise.py +++ b/sklearn/metrics/pairwise.py @@ -1252,12 +1252,13 @@ def paired_manhattan_distances(X, Y): array([1., 2., 1.]) """ X, Y = check_paired_arrays(X, Y) + xp, _ = get_namespace(X, Y) diff = X - Y if issparse(diff): diff.data = np.abs(diff.data) return np.squeeze(np.array(diff.sum(axis=1))) else: - return np.abs(diff).sum(axis=-1) + return xp.sum(xp.abs(diff), axis=-1) @validate_params( diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index b64d200a01522..353dfebf93bcf 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -72,6 +72,7 @@ manhattan_distances, paired_cosine_distances, paired_euclidean_distances, + paired_manhattan_distances, pairwise_distances, pairwise_kernels, polynomial_kernel, @@ -2414,6 +2415,7 @@ def check_array_api_metric_pairwise(metric, array_namespace, device, dtype_name) ], chi2_kernel: [check_array_api_metric_pairwise], paired_euclidean_distances: [check_array_api_metric_pairwise], + paired_manhattan_distances: [check_array_api_metric_pairwise], cosine_distances: [check_array_api_metric_pairwise], euclidean_distances: [check_array_api_metric_pairwise], manhattan_distances: [check_array_api_metric_pairwise], From 4c7b08f2abf49d3bac752f995d927557ccee94e3 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 12 Jan 2026 10:18:02 +0100 Subject: [PATCH 116/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33052) Co-authored-by: Lock file bot --- ...latest_conda_forge_mkl_linux-64_conda.lock | 32 ++++++++--------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 19 +++++------ .../pylatest_conda_forge_osx-arm64_conda.lock | 34 +++++++++---------- ...st_pip_openblas_pandas_linux-64_conda.lock | 8 ++--- ...nblas_min_dependencies_linux-64_conda.lock | 8 ++--- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 12 +++---- ...min_conda_forge_openblas_win-64_conda.lock | 12 +++---- build_tools/circle/doc_linux-64_conda.lock | 18 +++++----- .../doc_min_dependencies_linux-64_conda.lock | 18 +++++----- ...n_conda_forge_arm_linux-aarch64_conda.lock | 12 +++---- 10 files changed, 86 insertions(+), 87 deletions(-) diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index 072b0b77ed5d6..b9faef0b2bb70 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -21,7 +21,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.2-hb03c661_0.conda#ada39f5726bc5481e9dce293709dfabc https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 @@ -55,7 +55,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h8b1a151 https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h8b1a151_4.conda#c7e3e08b7b1b285524ab9d74162ce40b https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h8b1a151_5.conda#68da5b56dde41e172b7b24f071c4b392 https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717_0.conda#dbe3ec0f120af456b3477743ffd99b74 -https://conda.anaconda.org/conda-forge/linux-64/fmt-12.0.0-h2b0788b_0.conda#d90bf58b03d9a958cb4f9d3de539af17 +https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda#f7d7a4104082b39e3b3473fbd4a38229 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 @@ -68,7 +68,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_1.conda#ad1fd565aff83b543d726382c0ab0af2 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -114,7 +114,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-ha8fc4e3_5.con https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 @@ -145,9 +145,9 @@ https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100. https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.2-pyhd8ed1ab_0.conda#7e7cf4d6c2be6991e6ae2b3f4331701c +https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda#2cfaaccf085c133a477f0a7a8657afe9 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.12.0-pyhd8ed1ab_0.conda#a3b9510e2491c20c7fc0f5e730227fbb +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.1.0-pyhd8ed1ab_0.conda#1daaf94a304a27ba3446a306235a37ea https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.0-py313h7033f15_0.conda#2b1cf80423628afd34b4c66b767d7f6b https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac @@ -181,7 +181,7 @@ https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339 https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda#23b4ba5619c4752976eb7ba1f5acb7e8 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py313h07c4f96_0.conda#82da2dcf1ea3e298f2557b50459809e0 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 @@ -203,7 +203,7 @@ https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc4 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_hafda6a7_1003.conda#4fe840c6d6b3719b4231ed89d389bb17 +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb @@ -230,20 +230,20 @@ https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.co https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.57.0-pyhcf101f3_0.conda#a61bfabd06f24469454086deb7f8166e https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd +https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10.conda#937d1d4c233adc6eeb2ac3d6e9a73e53 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.13.0-hf38f1be_1.conda#f10b9303c7239fbce3580a60a92bcf97 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda#af35229f34c80dcfab5a40414440df23 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.0-py310hffdcd12_0.conda#5b2fbd248429505337095d2a84956655 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-hb6ed5f4_6_cpu.conda#fbaa3742ccca0f7096216c0832137b72 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad -https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda#160b41862a43936cbe509d1879d67f54 +https://conda.anaconda.org/conda-forge/noarch/polars-1.37.0-pyh6a1acc5_0.conda#45be32f1fff99fd27aae7b6eaf388a1f https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-h6f76662_3.conda#f134a496ef494f2b6c5a26e5d739acc6 https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-22.0.0-h8c2c5c3_6_cpu.conda#d2cd924b5f451a7c258001cb1c14155d @@ -254,21 +254,21 @@ https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py313h85046ba_0.c https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-22.0.0-h635bf11_6_cpu.conda#5a8f878ca313083960ab819a009848b3 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.9.1-cpu_mkl_hf3ca1bf_101.conda#5ef08e134f6dfcf431732cb0db6f877d -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py313hf6604e3_0.conda#07963f5dbb5351201035e1f8815ed8da +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.9.1-cpu_mkl_hfee2a32_102.conda#9f6f123bb5da9de569fe7e34a5913867 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py313hf6604e3_0.conda#7d51e3bef1a4b00bde1861d85ba2f874 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-22.0.0-py313he109ebe_0_cpu.conda#0b4a0a9ab270b275eb6da8671edb9458 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda#6186382cb34a9953bf2a18fc763dc346 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-22.0.0-h635bf11_6_cpu.conda#579bdb829ab093d048e49a289d3c9883 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_2.conda#8a69ea71fdd37bfe42a28f0967dbb75a -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.9.1-cpu_mkl_py313_h5a1586b_101.conda#48b128d28e7849060753d14a5f249f27 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.9.1-cpu_mkl_py313_hf5c6997_102.conda#8327cda07d244ae7825736ed1515b55e +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py313h4b8bb8b_0.conda#6cf603754566f66ff2be27f7f038b83a https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.0.1-pyhe01879c_0.conda#303ec962addf1b6016afd536e9db6bc6 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-22.0.0-h3f74fd7_6_cpu.conda#cfc7d2c5a81eb6de3100661a69de5f3d https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed -https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.9.1-cpu_mkl_hd61e0f4_101.conda#d053f5fbadaf26fcb23a7acb2b0e21e6 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.9.1-cpu_mkl_hd61e0f4_102.conda#81cbeaa402d3aacc8244deb09be6bb90 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b https://conda.anaconda.org/conda-forge/linux-64/pyarrow-22.0.0-py313h78bf25f_0.conda#dfe7289ae9ad7aa091979a7c5e6a55c7 diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index ad90866891c34..4612b5c0c0090 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -7,7 +7,6 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda#97c4b3bd8a90722104798175a1bdddbf https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/osx-64/icu-78.1-h14c5de8_0.conda#1e648e0c6657a29dc44102d6e3b10ebc https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.8-h3d58e20_0.conda#9f8a60a77ecafb7966ca961c94f33bd1 https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 @@ -29,9 +28,9 @@ https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda#21f765 https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda#63186ac7a8a24b3528b4b14f21c03f54 https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.53-h380d223_0.conda#0cdbbd56f660997cfe5d33e516afac2f -https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.1-hd09e2f1_1.conda#75ba9aba95c277f12e23cdb0856fd9cd +https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda#d910105ce2b14dfb2b32e92ec7653420 https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc -https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-he456531_1.conda#6cd21078a491bdf3fdb7482e1680ef63 +https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-hd57b93d_1.conda#060f6892620dc862f3b54b9b2da8f177 https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda#afda563484aa0017278866707807a335 https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda#3f50cdf9a97d0280655758b735781096 https://conda.anaconda.org/conda-forge/osx-64/qhull-2020.2-h3c5361c_5.conda#dd1ea9ff27c93db7c01a7b7656bd4ad4 @@ -43,7 +42,7 @@ https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda# https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.conda#dfbdc8fd781dc3111541e4234c19fdbd https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_15.conda#c816665789d1e47cdfd6da8a81e1af64 https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 -https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h24ca049_1.conda#c58fc83257ad06634b9c935099ef2680 +https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h745d5cb_1.conda#1fd2c75a8a9adc629983ed629dec42e1 https://conda.anaconda.org/conda-forge/osx-64/python-3.14.2-hf88997e_100_cp314.conda#48921d5efb314c3e628089fc6e27e54a https://conda.anaconda.org/conda-forge/osx-64/brotli-1.2.0-hf139dec_1.conda#149d8ee7d6541a02a6117d8814fd9413 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 @@ -52,10 +51,10 @@ https://conda.anaconda.org/conda-forge/osx-64/cython-3.2.4-py314hf0dd12f_0.conda https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.9-py314hf3ac25a_2.conda#28a77c52c425fa9c6d914c609c626b1a -https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.17-h72f5680_0.conda#bf210d0c63f2afb9e414a858b79f0eaa +https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.18-h90db99b_0.conda#753acc10c7277f953f168890e5397c80 https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.1-h694c41f_0.conda#e0e2edaf5e0c71b843e25a7ecc451cc9 https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_15.conda#c2a6149bf7f82774a0118b9efef966dd -https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.1-default_h273dbb7_1003.conda#5a87dfe5dcdc54ca4dc839e1d3577785 +https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h87e8dc5_0.conda#a67d3517ebbf615b91ef9fdc99934e0c @@ -70,7 +69,7 @@ https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.con https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.4-py314h3d180e3_0.conda#e9dfcd5b883e35aebe6dbe2c197dddbe https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.0-py314h6482030_1.conda#d69097de15cbad36f1eaafda0bad598a @@ -83,7 +82,7 @@ https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_15.con https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.0-py314hf9dbaa9_0.conda#ca55b2df1530e093f26d25ed503aafe8 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.13.0-hf0c99ee_4.conda#411c95470bff187ae555120702f28c0e +https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.13.0-h06b67a2_5.conda#f3e5cd2b56a3c866214b1d2529a54730 https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.0.2-h2beb688_0.tar.bz2#524282b2c46c9dedf051b3bc2ae05494 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/osx-64/mkl-2023.2.0-h694c41f_50502.conda#0bdfc939c8542e0bc6041cbd9a900219 @@ -96,11 +95,11 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.co https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-20_osx64_mkl.conda#51089a4865eb4aec2bc5c7468bd07f9f https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-20_osx64_mkl.conda#58f08e12ad487fac4a08f90ff0b87aec https://conda.anaconda.org/conda-forge/osx-64/liblapacke-3.9.0-20_osx64_mkl.conda#124ae8e384268a8da66f1d64114a1eda -https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.0-py314hfc4c462_0.conda#5e45547a4a84dc6f6da82aa4bee9fe7c +https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.1-py314hfc4c462_0.conda#73bc04c55ef4911075790db9fcce921b https://conda.anaconda.org/conda-forge/osx-64/blas-devel-3.9.0-20_osx64_mkl.conda#cc3260179093918b801e373c6e888e02 https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h00ed6fe_3.conda#761aa19f97a0dd5dedb9a0a6003707c1 https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.3-py314hc4308db_2.conda#b082e18eb2696625aa09c80e0fbd1997 -https://conda.anaconda.org/conda-forge/osx-64/scipy-1.16.3-py314hbb40827_2.conda#306e89b8db5482c47324978efcf59f7d +https://conda.anaconda.org/conda-forge/osx-64/scipy-1.17.0-py314h6328ba2_0.conda#7e11a5f8d57512cbf80c45d146b72640 https://conda.anaconda.org/conda-forge/osx-64/blas-2.120-mkl.conda#b041a7677a412f3d925d8208936cb1e2 https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.8-py314hd47142c_0.conda#91d76a5937b47f7f0894857ce88feb9f https://conda.anaconda.org/conda-forge/osx-64/pyamg-5.3.0-py314h81027db_1.conda#47390f4299f43bcdae539d454178596e diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock index c88b5307b30b1..de6b5421b9335 100644 --- a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock @@ -10,7 +10,7 @@ https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-hc6f873 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda#58fd217444c2a5701a44244faf518206 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.1-h38cb7af_0.conda#5446161926f45f3a14f7ca9db4d53e3b +https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-h38cb7af_0.conda#1e93aca311da0210e660d2247812fa02 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-hf598326_0.conda#780f0251b757564e062187044232c2b7 https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 @@ -30,7 +30,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda#78b548eed8227a689f93775d5d23ae09 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxdmcp-1.1.5-hc919400_1.conda#9d1299ace1924aa8f4e0bc8e71dd0cf7 https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda#a44032f282e7d2acdeb1c240308052dd -https://conda.anaconda.org/conda-forge/osx-arm64/fmt-12.0.0-h669d743_0.conda#364025d9b6f6305a73f8a5e84a2310d5 +https://conda.anaconda.org/conda-forge/osx-arm64/fmt-12.1.0-h403dcb5_0.conda#ae2f556fbb43e5a75cc80a47ac942a8e https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-h7bae524_2.conda#eed7278dfbab727b56f2c0b64330814b https://conda.anaconda.org/conda-forge/osx-arm64/isl-0.26-imath32_h347afa1_101.conda#e80e44a3f4862b1da870dc0557f8cf3b https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda#a74332d9b60b62905e3d30709df08bf1 @@ -39,7 +39,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.c https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.53-hfab5511_0.conda#62b6111feeffe607c3ecc8ca5bd1514b -https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.1-h1b79a29_1.conda#8c3951797658e10b610929c3e57e9ad9 +https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda#4b0bf313c53c3e89692f020fb55d5f2c https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h5ef1a60_1.conda#7eed1026708e26ee512f43a04d9d0027 https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda#175809cc57b2c67f27a0f238bd7f069d @@ -67,11 +67,11 @@ https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100. https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py313hf5aebd8_0.conda#6dc684ec14e88ff9485928f81286c7a5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.2-pyhd8ed1ab_0.conda#7e7cf4d6c2be6991e6ae2b3f4331701c -https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.12.0-pyhd8ed1ab_0.conda#a3b9510e2491c20c7fc0f5e730227fbb +https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda#2cfaaccf085c133a477f0a7a8657afe9 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.1.0-pyhd8ed1ab_0.conda#1daaf94a304a27ba3446a306235a37ea https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py313h7add70c_2.conda#9583687276aaa393e723f3b7970be69f -https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.17-h7eeda09_0.conda#92a61fd30b19ebd5c1621a5bfe6d8b5f +https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.18-hdfa7624_0.conda#6631a7bd2335bb9699b1dbc234b19784 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda#f35fb38e89e2776994131fbf961fa44b https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_16.conda#265a9d03461da24884ecc8eb58396d57 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 @@ -95,7 +95,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py313h6535dbc_0.conda#67a85c1b5c17124eaf9194206afd5159 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.1-py313h65a2061_0.conda#3283d95f985c7f293cb13bb7e33500a5 @@ -106,7 +106,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.2.1-py313hc1c22ca_2.con https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_h6922315_3.conda#a9527064ed0ed4514de7a7d35ab28c97 -https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_6.conda#509700140f1de6d0b31e7d3181b3d8b2 +https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_7.conda#5600ae1b88144099572939e773f4b20b https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_16.conda#11e09edf0dde4c288508501fe621bab4 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.1.0-py313h45e5a15_0.conda#78a39731fd50dbd511de305934fe7e62 @@ -114,7 +114,7 @@ https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda# https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_6.conda#f7b47b7a0c20180be00833b6c68a8668 +https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_7.conda#3b992d143f0008588ca26df8a324eee9 https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_3.conda#fac8bcc3f72041318061b92c1f269aa4 https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h8d724d3_accelerate.conda#c32b3b0d73d5cb1ab2a095a69bf3a7bd https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.0.2-hbec66e7_0.tar.bz2#37ca71a16015b17397da4a5e6883f66f @@ -132,27 +132,27 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.co https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_3.conda#7b0ea95f0288f1a25f692800b407daf2 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_3.conda#d197a4b2169c054aa91252e1f95d7b08 https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-5_hbdd07e9_accelerate.conda#29c7d09cbe6d342ced64b0447e1f3792 -https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.9.1-cpu_generic_h040b7fb_1.conda#4d3dbf224d7d41e146777ae04c05ecc0 -https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.0-py313h16eae64_0.conda#c87aab85fa09a22ef300bd50ffcf4691 +https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.9.1-cpu_generic_h812a54d_2.conda#7aa9f7ae0c71c7c51b1d8510e97addb6 +https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.1-py313h16eae64_0.conda#527abeb3c3f65345d9c337fb49e32d51 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-5_h55bc449_accelerate.conda#6696b095e91860523bcc97303e11d30d https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313ha61f8ec_3.conda#5643cff3e9ab77999fba139465156e35 https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.3-py313h7d16b84_2.conda#03771a1c710d15974372ae791811bcde -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.9.1-cpu_generic_py313_h6bf06e3_1.conda#b47dd1b58e9c6aa7b45239f7902b1243 -https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.16.3-py313h29d7d31_2.conda#a3324bd937a39cbbf1cbe0940160e19e +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.9.1-cpu_generic_py313_hf9b77c4_2.conda#fe9b1a3fe70b571ef23580c77d173930 +https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.0-py313hc753a45_0.conda#9820f8f7d2f7b973e0b71c00adb32172 https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.305-accelerate.conda#5f941c90faaca70599ef8302d0c2738f https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py313h58042b9_0.conda#745c18472bc6d3dc9146c3dec18bb740 https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py313h28ea3aa_1.conda#51a353d043e612a8f520627cf0e73653 -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.9.1-cpu_generic_hcc7c195_1.conda#139bf77a4b1174e2e30c7d884fb160c8 +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.9.1-cpu_generic_hcc7c195_2.conda#97de67427e3786a0aa68c091bb2bbda8 https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py313h39782a4_0.conda#bae471007cbebf097a19e851c219d56a https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda#148516e0c9edf4e9331a4d53ae806a9b -https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_6.conda#25c9924db91c665423e0630a2f51ca22 +https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_7.conda#13150cdd8e6bc61aa68b55d1a2a69083 https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda#8d99c82e0f5fed6cc36fcf66a11e03f0 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_impl_osx-arm64-14.3.0-h6d03799_1.conda#1e9ec88ecc684d92644a45c6df2399d0 https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 -https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_6.conda#7d5b8960ca867ad1287aba1ed9ef45cf +https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_7.conda#bde6fcb6b1fcefb687a7fb95675c6ec8 https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_29.conda#e1cbe6c2279228ca3a0ee32a80e89c89 -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_6.conda#0ca27aa5b6a8752b6e4183c1b8712e12 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_7.conda#4fa4a9227c428372847c534a9bffd698 https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_29.conda#8dcfeec0143f62fc8beffc8065995105 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_osx-arm64-14.3.0-h3c33bd0_0.conda#8db8c0061c0f3701444b7b9cc9966511 https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda#043afed05ca5a0f2c18252ae4378bdee diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index 3ebc9c06187a1..b1ee2dcb2e5fb 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -21,7 +21,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda#518e9bbbc3e3486d6a4519192ba690f8 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec @@ -29,7 +29,7 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.con https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a @@ -52,7 +52,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 # pip meson @ https://files.pythonhosted.org/packages/32/4f/c398c6f06ece1c6c246e008d5dac3824c98f54d3eb3d8014f4910afd6d48/meson-1.10.0-py3-none-any.whl#sha256=4b27aafce281e652dcb437b28007457411245d975c48b5db3a797d3e93ae1585 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa -# pip numpy @ https://files.pythonhosted.org/packages/99/98/9d4ad53b0e9ef901c2ef1d550d2136f5ac42d3fd2988390a6def32e23e48/numpy-2.4.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=8cfa5f29a695cb7438965e6c3e8d06e0416060cf0d709c1b1c1653a939bf5c2a +# pip numpy @ https://files.pythonhosted.org/packages/ba/87/d341e519956273b39d8d47969dd1eaa1af740615394fe67d06f1efa68773/numpy-2.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8 # pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 # pip pillow @ https://files.pythonhosted.org/packages/01/9a/632e58ec89a32738cabfd9ec418f0e9898a2b4719afc581f07c04a05e3c9/pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 @@ -78,7 +78,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 -# pip scipy @ https://files.pythonhosted.org/packages/21/f6/4bfb5695d8941e5c570a04d9fcd0d36bce7511b7d78e6e75c8f9791f82d0/scipy-1.16.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=7dc1360c06535ea6116a2220f760ae572db9f661aba2d88074fe30ec2aa1ff88 +# pip scipy @ https://files.pythonhosted.org/packages/63/1e/12fbf2a3bb240161651c94bb5cdd0eae5d4e8cc6eaeceb74ab07b12a753d/scipy-1.17.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=6680f2dfd4f6182e7d6db161344537da644d1cf85cf293f015c60a17ecf08752 # pip lightgbm @ https://files.pythonhosted.org/packages/42/86/dabda8fbcb1b00bcfb0003c3776e8ade1aa7b413dff0a2c08f457dace22f/lightgbm-4.6.0-py3-none-manylinux_2_28_x86_64.whl#sha256=cb19b5afea55b5b61cbb2131095f50538bd608a00655f23ad5d25ae3e3bf1c8d # pip matplotlib @ https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486 # pip meson-python @ https://files.pythonhosted.org/packages/28/58/66db620a8a7ccb32633de9f403fe49f1b63c68ca94e5c340ec5cceeb9821/meson_python-0.18.0-py3-none-any.whl#sha256=3b0fe051551cc238f5febb873247c0949cd60ded556efa130aa57021804868e2 diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index f912c238c8857..97642e50abbd7 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -17,7 +17,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.2-hb03c661_0.conda#ada39f5726bc5481e9dce293709dfabc https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 @@ -62,7 +62,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_1.conda#ad1fd565aff83b543d726382c0ab0af2 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c @@ -116,7 +116,7 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.cond https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_0.conda#fd6acbf37b40cbe919450fa58309fbe1 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 @@ -173,7 +173,7 @@ https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.con https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda#978d03388b62173b8e6f79162cf52b86 https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index b2bf3f4a0e85c..0e2f50c4b26ce 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -27,7 +27,7 @@ https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f -https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda#518e9bbbc3e3486d6a4519192ba690f8 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 @@ -43,9 +43,9 @@ https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hb https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a @@ -84,7 +84,7 @@ https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 @@ -93,7 +93,7 @@ https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc4 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py311h2e04523_0.conda#c6c7e0db448312b204667a13d7f7346d +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py311h2e04523_0.conda#716357afd11c16214cdac522da447704 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -101,7 +101,7 @@ https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_ope https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311hbe70eeb_2.conda#1f9587850322d7d77ea14d4fee3d16d8 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_0.conda#a1698614a27f4bd96815bac2ab22e1fc https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock index 20410b5526bf6..1867bf0babeb0 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock @@ -21,7 +21,7 @@ https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda#1e610f24 https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda#1077e9333c41ff0be8edd1a5ec0ddace https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_0.conda#3d3caf4ccc6415023640af4b1b33060a https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda#b785694dd3ec77a011ccf0c24725382b -https://conda.anaconda.org/conda-forge/win-64/icu-78.1-h637d24d_0.conda#cb8048bed35ef01431184d6a88e46b3e +https://conda.anaconda.org/conda-forge/win-64/icu-78.2-h637d24d_0.conda#0ee3bb487600d5e71ab7d28951b2016a https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda#c1b81da6d29a14b542da14a36c9fbf3f https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda#444b0a45bbd1cb24f82eedb56721b9c4 https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e @@ -32,7 +32,7 @@ https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#645 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda#56a686f92ac0273c0f6af58858a3f013 https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda#c15148b2e18da456f5108ccb5e411446 https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.30-pthreads_h877e47f_4.conda#f551f8ae0ae6535be1ffde181f9377f3 -https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.1-hf5d6505_1.conda#be65be5f758709fc01b01626152e96b0 +https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda#903979414b47d777d548e5f0165e6cd8 https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.328.1-h477610d_0.conda#4403eae6c81f448d63a7f66c0b330536 https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda#f9bbae5e2537e3b06e0f7310ba76c893 https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda#41fbfac52c601159df6c01f875de31b9 @@ -81,7 +81,7 @@ https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.con https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py311h3485c13_0.conda#6e8d1faf5c0c08641c151e0fb79cb4db https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.0-py311h3485c13_1.conda#a30a6a70ab7754dbf0b06fe1a96af9cb @@ -90,11 +90,11 @@ https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda#bc58 https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.1-py311h3f79411_0.conda#2bc1a645fd4c574855277c6ab0061f49 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/win-64/lcms2-2.17-hbcf6048_0.conda#3538827f77b82a837fa681a4579e37a1 +https://conda.anaconda.org/conda-forge/win-64/lcms2-2.18-hf2c6c5f_0.conda#b6c68d6b829b044cd17a41e0a8a23ca1 https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda#3235024fe48d4087721797ebd6c9d28c https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-5_hbb0e6ff_openblas.conda#b96fdd694dc8b7a5869613121c40d086 https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 -https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.0-py311h80b3fa1_0.conda#341bab3c29a3b81d5ef81eac749b51ce +https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.1-py311h80b3fa1_0.conda#387094bb33448f55432ea38cf9b62f1f https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h24db6dd_0.conda#5af852046226bb3cb15c7f61c2ac020a https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 @@ -106,7 +106,7 @@ https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda#d https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.0-py311h17b8079_0.conda#da30e4de83b61f936f73660eb4fa3cd5 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/win-64/scipy-1.16.3-py311h9c22a71_2.conda#4b663de0f0c8ac0fbb4a4d9ee8536b0f +https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.0-py311h9c22a71_0.conda#5a37e6e0b88c9fcfd1050ded185d07a1 https://conda.anaconda.org/conda-forge/win-64/blas-2.305-openblas.conda#19bbf270f61bbef238e16a9509377a52 https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.15.0-h765892d_1.conda#9bb0026a2131b09404c59c4290c697cd https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 61e51ae3983d9..22705df8fce74 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -22,7 +22,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.2-hb03c661_0.conda#ada39f5726bc5481e9dce293709dfabc https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed @@ -53,7 +53,7 @@ https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418 https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717_0.conda#dbe3ec0f120af456b3477743ffd99b74 https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d -https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda#518e9bbbc3e3486d6a4519192ba690f8 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.4-h3f801dc_0.conda#01ba04e414e47f95c03d6ddd81fd37be @@ -92,9 +92,9 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee -https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_5.conda#82954a6f42e3fba59628741dca105c98 +https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_6.conda#08ed2d4223458aac1f07d855361bb476 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 @@ -108,7 +108,7 @@ https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-defa https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h6395336_2.conda#c09c4ac973f7992ba0c6bb1aafd77bd4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e @@ -196,7 +196,7 @@ https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.1-pyhd8ed1ab_0.conda#7de28c27fe620a4f7dbfaea137c6232b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda#019a7385be9af33791c989871317e1ed https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d @@ -242,7 +242,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b11e360fc4de2b0035fc8aaa74f17fd6 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py311h2e04523_0.conda#c6c7e0db448312b204667a13d7f7346d +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py311h2e04523_0.conda#716357afd11c16214cdac522da447704 https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.1-pyhd8ed1ab_0.conda#0a8b38871cab04059c1cc04853b415a2 @@ -275,7 +275,7 @@ https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.1-py311h273f7 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a -https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.7.0-pyhcf101f3_0.conda#1b0397a7b1fbffa031feb690b5fd0277 +https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_1.conda#2d983ff1b82a1ccb6f2e9d8784bdd6bd https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e @@ -283,7 +283,7 @@ https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.c https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py311hbe70eeb_2.conda#1f9587850322d7d77ea14d4fee3d16d8 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_0.conda#a1698614a27f4bd96815bac2ab22e1fc https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 25918194c1f62..3b39b271b2931 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -23,7 +23,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.2-hb03c661_0.conda#ada39f5726bc5481e9dce293709dfabc https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 @@ -71,7 +71,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.c https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_16.conda#0617b134e4dc4474c1038707499f7eed -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_1.conda#ad1fd565aff83b543d726382c0ab0af2 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -102,7 +102,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hb https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee -https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_5.conda#82954a6f42e3fba59628741dca105c98 +https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_6.conda#08ed2d4223458aac1f07d855361bb476 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_3.conda#70d1de6301b58ed99fea01490a9802a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 @@ -118,7 +118,7 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8c https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_0.conda#fd6acbf37b40cbe919450fa58309fbe1 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h6395336_2.conda#c09c4ac973f7992ba0c6bb1aafd77bd4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 @@ -171,7 +171,7 @@ https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 -https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 +https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda#3eeeeb9e4827ace8c0c1419c85d590ad https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 @@ -180,7 +180,7 @@ https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.2-pyhd8ed1ab_0.conda#5d99943f2ae3cc69e1ada12ce9d4d701 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 @@ -204,7 +204,7 @@ https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_hafda6a7_1003.conda#4fe840c6d6b3719b4231ed89d389bb17 +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 @@ -228,7 +228,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c5 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-h8d10470_1.conda#e3259be3341da4bc06c5b7a78c8bf1bd +https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_16.conda#f5b82e3d5f4d345e8e1a227636eeb64f @@ -256,7 +256,7 @@ https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.1-py311h273f733_0.conda#1e2ccd20e277220a515d2afe5a810917 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.2-py311h14de704_1.conda#84e2dd379d4edec4dd6382861486104d +https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.conda#643f8cb35133eb1be4919fb953f0a25f https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.8.0-py311h9f3472d_0.conda#17334e5c12abdf2db6b25bd4187cd3e4 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index e532421799515..f4a1da2471f16 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -17,7 +17,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.con https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_16.conda#cf9cd6739a3b694dcf551d898e112331 -https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.1-he30d5cf_0.conda#50a88426e78ae8eb7d52072ba2e8db21 +https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.2-he30d5cf_0.conda#c7b811feff0255c3d00c2a080261856b https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_8.conda#2921ac0b541bf37c69e66bd6d9a43bca https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda#e7df0aab10b9cbb73ab2a467ebfaf8c7 https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d5cf_1.conda#8ec1d03f3000108899d1799d9964f281 @@ -43,7 +43,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda#bff06dcde4a707339d66d45d96ceb2e2 https://conda.anaconda.org/conda-forge/linux-aarch64/double-conversion-3.4.0-hfae3067_0.conda#9fd794eaf983eabf975ead524540b4be https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda#4aa540e9541cc9d6581ab23ff2043f13 -https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.1-hb1525cb_0.conda#5eba836ceb0cccf969d9518ca884de2a +https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.2-hb1525cb_0.conda#15b35dc33e185e7d2aac1cfcd6778627 https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.0.0-hfdc4d58_1.conda#60dceb7e876f4d74a9cbd42bbbc6b9cf https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf_1.conda#47e5b71b77bb8b47b4ecf9659492977f https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda#6553a5d017fe14859ea8a4e6ea5def8f @@ -71,7 +71,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.1-hdae7a3 https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-ng-15.2.0-he9431aa_16.conda#3b55579065fac309af0129098fa1657b https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.3-hf53f6bf_0.conda#f226b9798c6c176d2a94eea1350b3b6b https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e -https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.1-h10b116e_1.conda#9fd37e702b4e7c85462fe79baf13974d +https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.2-h10b116e_0.conda#4e3ba0d5d192f99217b85f07a0761e64 https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.1-h79dcc73_1.conda#e42758e7b065c34fd1b0e5143752f970 https://conda.anaconda.org/conda-forge/linux-aarch64/qhull-2020.2-h70be974_5.conda#bb138086d938e2b64f5f364945793ebf @@ -83,7 +83,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.12-hca56bd8 https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-hd651790_1.conda#5c933384d588a06cd8dac78ca2864aab https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.28-h6c5dea3_0.conda#b6d06b46e791add99cc39fbbc34530d5 https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda#a4b6b82427d15f0489cef0df2d82f926 -https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.17-hc88f144_0.conda#b87b1abd2542cf65a00ad2e2461a3083 +https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda#bb960f01525b5e001608afef9d47b79c https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda#5afcea37a46f76ec1322943b3c4dfdc0 https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h5cdc715_5.conda#ac0333d338076ef19170938bbaf97582 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.1-h8af1aa0_0.conda#1e61fb236ccd3d6ccaf9e91cb2d7e12d @@ -124,7 +124,7 @@ https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.con https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.3-py311hb9158a3_0.conda#e3afe76a49a1a9f85e0c5cd42a408e68 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-aarch64/unicodedata2-17.0.0-py311h19352d5_1.conda#4a55814831e0ec9be84ccef6aed798c1 @@ -146,7 +146,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.8-default_h https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-5_hb558247_openblas.conda#8046d5ae90150f00c8b40455d9b2e180 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.1-hf8816c8_3.conda#e0d7a6cbc0b8a6d05002cb9bd061a4af https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.328.1-h8b8848b_0.conda#e5a3ff3a266b68398bd28ed1d4363e65 -https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.0-py311h669026d_0.conda#3ad0028f1f187e612f858009ec688227 +https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.1-py311h669026d_0.conda#e6f40fe186c60f1a6c54a8697213c5cd https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 From 8fb457f718e7946623a184460c559ca311a75bee Mon Sep 17 00:00:00 2001 From: TejasAnalyst Date: Tue, 13 Jan 2026 15:50:00 +0530 Subject: [PATCH 117/462] DOC: Fix typo "hyperparamters" in feature_extraction.rst (#33060) --- doc/modules/feature_extraction.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/modules/feature_extraction.rst b/doc/modules/feature_extraction.rst index bbe3ed8ec1742..e3b4a9bfb75b6 100644 --- a/doc/modules/feature_extraction.rst +++ b/doc/modules/feature_extraction.rst @@ -622,7 +622,7 @@ Again please see the :ref:`reference documentation and comparison with :class:`HashingVectorizer`. * :ref:`sphx_glr_auto_examples_model_selection_plot_grid_search_text_feature_extraction.py`: - Tuning hyperparamters of :class:`TfidfVectorizer` as part of a pipeline. + Tuning hyperparameters of :class:`TfidfVectorizer` as part of a pipeline. Decoding text files From 17e8c90bbdcbbc5ae07f8e7f4eb924c20e455048 Mon Sep 17 00:00:00 2001 From: Auguste Baum <52001167+augustebaum@users.noreply.github.com> Date: Tue, 13 Jan 2026 12:07:04 +0100 Subject: [PATCH 118/462] CI Port windows test job from Azure to GHA (#33062) --- .github/workflows/unit-tests.yml | 18 +++++++ azure-pipelines.yml | 29 ----------- build_tools/azure/windows.yml | 86 -------------------------------- 3 files changed, 18 insertions(+), 115 deletions(-) delete mode 100644 build_tools/azure/windows.yml diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 1d14bc58932dd..bb0790fcf6e84 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -152,6 +152,24 @@ jobs: PYTORCH_ENABLE_MPS_FALLBACK: 1 CHECK_PYTEST_SOFT_DEPENDENCY: true + - name: Windows pymin_conda_forge_openblas + os: windows-latest + DISTRIB: conda + LOCK_FILE: build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock + SKLEARN_WARNINGS_AS_ERRORS: 1 + # The Windows runner is typically much slower than other CI runners + # due to the lack of compiler cache. Running the tests with coverage + # enabled makes them run extra slow. Since very few parts of the + # code should have windows-specific code branches, code coverage + # collection is only done for the non-windows runners. + COVERAGE: false + # Enable debug Cython directives to capture IndexError exceptions in + # combination with the -Werror::pytest.PytestUnraisableExceptionWarning + # flag for pytest. + # https://github.com/scikit-learn/scikit-learn/pull/24438 + SKLEARN_ENABLE_DEBUG_CYTHON_DIRECTIVES: 1 + SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 7 # non-default seed + env: ${{ matrix }} steps: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 95d0d104036af..184d46205c25a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -220,32 +220,3 @@ jobs: SKLEARN_TEST_NO_OPENMP: 'true' SKLEARN_SKIP_OPENMP_TEST: 'true' SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '6' # non-default seed - -- template: build_tools/azure/windows.yml - parameters: - name: Windows - vmImage: windows-latest - dependsOn: [linting, git_commit, Ubuntu_Jammy_Jellyfish] - # Runs when dependencies succeeded or skipped - condition: | - and( - not(or(failed(), canceled())), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[ci skip]')) - ) - matrix: - pymin_conda_forge_openblas: - DISTRIB: 'conda' - LOCK_FILE: ./build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock - SKLEARN_WARNINGS_AS_ERRORS: '1' - # The Azure Windows runner is typically much slower than other CI - # runners due to the lack of compiler cache. Running the tests with - # coverage enabled make them run extra slower. Since very few parts of - # code should have windows-specific code branches, it should be enable - # to restrict the code coverage collection to the non-windows runners. - COVERAGE: 'false' - # Enable debug Cython directives to capture IndexError exceptions in - # combination with the -Werror::pytest.PytestUnraisableExceptionWarning - # flag for pytest. - # https://github.com/scikit-learn/scikit-learn/pull/24438 - SKLEARN_ENABLE_DEBUG_CYTHON_DIRECTIVES: '1' - SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '7' # non-default seed diff --git a/build_tools/azure/windows.yml b/build_tools/azure/windows.yml deleted file mode 100644 index b1c512c345a4c..0000000000000 --- a/build_tools/azure/windows.yml +++ /dev/null @@ -1,86 +0,0 @@ - -parameters: - name: '' - vmImage: '' - matrix: [] - dependsOn: [] - condition: ne(variables['Build.Reason'], 'Schedule') - -jobs: -- job: ${{ parameters.name }} - dependsOn: ${{ parameters.dependsOn }} - condition: ${{ parameters.condition }} - pool: - vmImage: ${{ parameters.vmImage }} - variables: - VIRTUALENV: 'testvenv' - JUNITXML: 'test-data.xml' - SKLEARN_SKIP_NETWORK_TESTS: '1' - PYTEST_XDIST_VERSION: 'latest' - TEST_DIR: '$(Agent.WorkFolder)/tmp_folder' - SHOW_SHORT_SUMMARY: 'false' - strategy: - matrix: - ${{ insert }}: ${{ parameters.matrix }} - - steps: - - bash: python build_tools/azure/get_selected_tests.py - displayName: Check selected tests for all random seeds - condition: eq(variables['Build.Reason'], 'PullRequest') - - bash: build_tools/azure/install_setup_conda.sh - displayName: Install conda if necessary and set it up - condition: startsWith(variables['DISTRIB'], 'conda') - - task: UsePythonVersion@0 - inputs: - versionSpec: '$(PYTHON_VERSION)' - addToPath: true - architecture: 'x86' - displayName: Use 32 bit System Python - condition: and(succeeded(), eq(variables['PYTHON_ARCH'], '32')) - - bash: ./build_tools/azure/install.sh - displayName: 'Install' - - bash: ./build_tools/azure/test_script.sh - displayName: 'Test Library' - - bash: ./build_tools/azure/combine_coverage_reports.sh - condition: and(succeeded(), eq(variables['COVERAGE'], 'true'), - eq(variables['SELECTED_TESTS'], '')) - displayName: 'Combine coverage' - - task: PublishTestResults@2 - inputs: - testResultsFiles: '$(TEST_DIR)/$(JUNITXML)' - testRunTitle: ${{ format('{0}-$(Agent.JobName)', parameters.name) }} - displayName: 'Publish Test Results' - condition: succeededOrFailed() - - bash: | - set -ex - if [[ $(BOT_GITHUB_TOKEN) == "" ]]; then - echo "GitHub Token is not set. Issue tracker will not be updated." - exit - fi - - LINK_TO_RUN="https://dev.azure.com/$BUILD_REPOSITORY_NAME/_build/results?buildId=$BUILD_BUILDID&view=logs&j=$SYSTEM_JOBID" - CI_NAME="$SYSTEM_JOBIDENTIFIER" - ISSUE_REPO="$BUILD_REPOSITORY_NAME" - - $(pyTools.pythonLocation)/bin/pip install defusedxml PyGithub - $(pyTools.pythonLocation)/bin/python maint_tools/update_tracking_issue.py \ - $(BOT_GITHUB_TOKEN) \ - $CI_NAME \ - $ISSUE_REPO \ - $LINK_TO_RUN \ - --junit-file $JUNIT_FILE \ - --auto-close false - displayName: 'Update issue tracker' - env: - JUNIT_FILE: $(TEST_DIR)/$(JUNITXML) - condition: and(succeededOrFailed(), eq(variables['CREATE_ISSUE_ON_TRACKER'], 'true'), - eq(variables['Build.Reason'], 'Schedule')) - - bash: ./build_tools/azure/upload_codecov.sh - condition: and(succeeded(), - eq(variables['COVERAGE'], 'true'), - eq(variables['SELECTED_TESTS'], '')) - displayName: 'Upload To Codecov' - retryCountOnTaskFailure: 5 - env: - CODECOV_TOKEN: $(CODECOV_TOKEN) - JUNIT_FILE: $(TEST_DIR)/$(JUNITXML) From bb4b88c090b76678f6670feaa90f13d2b536acc0 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Wed, 14 Jan 2026 00:01:18 +1100 Subject: [PATCH 119/462] DOC Fix and amend `hinge_loss` docstring (#33054) --- sklearn/metrics/_classification.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 8540dd53640b3..01d8b93a510d7 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -3407,15 +3407,15 @@ def _log_loss(transformed_labels, y_pred, *, normalize=True, sample_weight=None) def hinge_loss(y_true, pred_decision, *, labels=None, sample_weight=None): """Average hinge loss (non-regularized). - In binary class case, assuming labels in y_true are encoded with +1 and -1, - when a prediction mistake is made, ``margin = y_true * pred_decision`` is - always negative (since the signs disagree), implying ``1 - margin`` is + In :term:`binary` class case, assuming labels in `y_true` are encoded with +1 + and -1, when a prediction mistake is made, `margin = y_true * pred_decision` is + always negative (since the signs are opposite), implying `1 - margin` is always greater than 1. The cumulated hinge loss is therefore an upper bound of the number of mistakes made by the classifier. - In multiclass case, the function expects that either all the labels are - included in y_true or an optional labels argument is provided which - contains all the labels. The multilabel margin is calculated according + In :term:`multiclass` case, the function expects that either all the labels are + present in `y_true` or an optional `labels` argument is provided which + contains all the labels. The multiclass margin is calculated according to Crammer-Singer's method. As in the binary case, the cumulated hinge loss is an upper bound of the number of mistakes made by the classifier. @@ -3424,11 +3424,13 @@ def hinge_loss(y_true, pred_decision, *, labels=None, sample_weight=None): Parameters ---------- y_true : array-like of shape (n_samples,) - True target, consisting of integers of two values. The positive label - must be greater than the negative label. + True target. For :term:`binary` data, it should only contain two unique + values, with the positive label being greater than the negative label. + For :term:`multiclass` data, all labels should be present, or provided + via `labels`. pred_decision : array-like of shape (n_samples,) or (n_samples, n_classes) - Predicted decisions, as output by decision_function (floats). + Predicted decisions, as output by :term:`decision_function` (floats). labels : array-like, default=None Contains all the labels for the problem. Used in multiclass hinge loss. From 38a2348bf553d4248dd062b64cce6d72b1568f72 Mon Sep 17 00:00:00 2001 From: Auguste Baum <52001167+augustebaum@users.noreply.github.com> Date: Tue, 13 Jan 2026 15:54:41 +0100 Subject: [PATCH 120/462] CI Port Linux ubuntu_atlas test job from Azure to GHA (#33064) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- .github/workflows/unit-tests.yml | 11 +++++++++++ azure-pipelines.yml | 21 --------------------- 2 files changed, 11 insertions(+), 21 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index bb0790fcf6e84..a651f21b4f519 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -143,6 +143,16 @@ jobs: PYTEST_XDIST_VERSION: none PIP_BUILD_ISOLATION: true + # Linux environment to test that scikit-learn can be built against + # versions of numpy, scipy with ATLAS that comes with Ubuntu 24.04 + # Noble Numbat i.e. numpy 1.26.4 and scipy 1.11.4 + - name: Linux x86-64 ubuntu_atlas + os: ubuntu-24.04 + DISTRIB: ubuntu + LOCK_FILE: build_tools/azure/ubuntu_atlas_lock.txt + COVERAGE: false + SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 1 # non-default seed + - name: macOS pylatest_conda_forge_arm os: macOS-15 DISTRIB: conda @@ -185,6 +195,7 @@ jobs: - name: Set up conda uses: conda-incubator/setup-miniconda@v3 + if: ${{ startsWith(env.DISTRIB, 'conda') }} with: miniforge-version: latest auto-activate-base: true diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 184d46205c25a..6476160494294 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -138,27 +138,6 @@ jobs: COVERAGE: 'false' SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '0' # non-default seed -- template: build_tools/azure/posix.yml - parameters: - name: Ubuntu_Atlas - vmImage: ubuntu-24.04 - dependsOn: [linting, git_commit, Ubuntu_Jammy_Jellyfish] - # Runs when dependencies succeeded or skipped - condition: | - and( - not(or(failed(), canceled())), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[ci skip]')) - ) - matrix: - # Linux environment to test that scikit-learn can be built against - # versions of numpy, scipy with ATLAS that comes with Ubuntu 24.04 Noble Numbat - # i.e. numpy 1.26.4 and scipy 1.11.4 - ubuntu_atlas: - DISTRIB: 'ubuntu' - LOCK_FILE: './build_tools/azure/ubuntu_atlas_lock.txt' - COVERAGE: 'false' - SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '1' # non-default seed - - template: build_tools/azure/posix.yml parameters: name: Linux From bb083c4c75b125ef968342b7c0c496916b9d6166 Mon Sep 17 00:00:00 2001 From: Auguste Baum <52001167+augustebaum@users.noreply.github.com> Date: Tue, 13 Jan 2026 16:06:06 +0100 Subject: [PATCH 121/462] CI Add architecture to Windows test name (#33069) --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index a651f21b4f519..916cafff3aad7 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -162,7 +162,7 @@ jobs: PYTORCH_ENABLE_MPS_FALLBACK: 1 CHECK_PYTEST_SOFT_DEPENDENCY: true - - name: Windows pymin_conda_forge_openblas + - name: Windows x64 pymin_conda_forge_openblas os: windows-latest DISTRIB: conda LOCK_FILE: build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock From 3db6b3c7ac32d21f2b0e96d646aaff7f059d929c Mon Sep 17 00:00:00 2001 From: Auguste Baum <52001167+augustebaum@users.noreply.github.com> Date: Tue, 13 Jan 2026 16:50:59 +0100 Subject: [PATCH 122/462] CI Port Linux min_dependencies test job from Azure to GHA (#33068) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- .github/workflows/unit-tests.yml | 13 +++++++++++++ azure-pipelines.yml | 24 ------------------------ 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 916cafff3aad7..7429e79fce61a 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -127,6 +127,19 @@ jobs: DISTRIB: conda LOCK_FILE: build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock + # Linux build with minimum supported version of dependencies + - name: Linux x86-64 pymin_conda_forge_openblas_min_dependencies + os: ubuntu-22.04 + DISTRIB: conda + LOCK_FILE: build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock + # Enable debug Cython directives to capture IndexError exceptions in + # combination with the -Werror::pytest.PytestUnraisableExceptionWarning + # flag for pytest. + # https://github.com/scikit-learn/scikit-learn/pull/24438 + SKLEARN_ENABLE_DEBUG_CYTHON_DIRECTIVES: 1 + SKLEARN_RUN_FLOAT32_TESTS: 1 + SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 2 # non-default seed + # Linux environment to test the latest available dependencies. # It runs tests requiring lightgbm, pandas and PyAMG. - name: Linux pylatest_pip_openblas_pandas diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6476160494294..5429d45a7e013 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -138,30 +138,6 @@ jobs: COVERAGE: 'false' SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '0' # non-default seed -- template: build_tools/azure/posix.yml - parameters: - name: Linux - vmImage: ubuntu-22.04 - dependsOn: [linting, git_commit, Ubuntu_Jammy_Jellyfish] - # Runs when dependencies succeeded or skipped - condition: | - and( - not(or(failed(), canceled())), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[ci skip]')) - ) - matrix: - # Linux build with minimum supported version of dependencies - pymin_conda_forge_openblas_min_dependencies: - DISTRIB: 'conda' - LOCK_FILE: './build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock' - # Enable debug Cython directives to capture IndexError exceptions in - # combination with the -Werror::pytest.PytestUnraisableExceptionWarning - # flag for pytest. - # https://github.com/scikit-learn/scikit-learn/pull/24438 - SKLEARN_ENABLE_DEBUG_CYTHON_DIRECTIVES: '1' - SKLEARN_RUN_FLOAT32_TESTS: '1' - SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '2' # non-default seed - - template: build_tools/azure/posix-docker.yml parameters: name: Linux_Docker From a1c64ee3ebf17ced541b64192094ce73684541a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Wed, 14 Jan 2026 08:43:43 +0100 Subject: [PATCH 123/462] TST Avoid segmentation fault with free-threaded and pytest-run-parallel (#33070) --- sklearn/utils/tests/test_response.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/utils/tests/test_response.py b/sklearn/utils/tests/test_response.py index 4e9a2c489e1c6..199ed7f1beb4b 100644 --- a/sklearn/utils/tests/test_response.py +++ b/sklearn/utils/tests/test_response.py @@ -441,7 +441,7 @@ def test_response_values_output_shape_( else: # multilabel y = np.array([[0, 1], [1, 0]] * 5) - clf = estimator.fit(X, y) + clf = clone(estimator).fit(X, y) y_pred, _ = _get_response_values(clf, X, response_method=response_method) From 75bf0c6eed87e245ad4ee612d51f8434142dcbba Mon Sep 17 00:00:00 2001 From: Auguste Baum <52001167+augustebaum@users.noreply.github.com> Date: Wed, 14 Jan 2026 13:07:17 +0100 Subject: [PATCH 124/462] CI Port MacOS no_openmp test job from Azure to GHA (#33065) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- .github/workflows/unit-tests.yml | 10 +++++++++- azure-pipelines.yml | 19 ------------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 7429e79fce61a..bc6f266e6022a 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -167,7 +167,7 @@ jobs: SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 1 # non-default seed - name: macOS pylatest_conda_forge_arm - os: macOS-15 + os: macos-15 DISTRIB: conda LOCK_FILE: build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 5 # non-default seed @@ -175,6 +175,14 @@ jobs: PYTORCH_ENABLE_MPS_FALLBACK: 1 CHECK_PYTEST_SOFT_DEPENDENCY: true + - name: macOS x86-64 pylatest_conda_forge_mkl_no_openmp + os: macos-15-intel + DISTRIB: conda + LOCK_FILE: build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock + SKLEARN_TEST_NO_OPENMP: true + SKLEARN_SKIP_OPENMP_TEST: true + SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 6 # non-default seed + - name: Windows x64 pymin_conda_forge_openblas os: windows-latest DISTRIB: conda diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5429d45a7e013..80c8a9ec73f4c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -156,22 +156,3 @@ jobs: COVERAGE: "true" LOCK_FILE: './build_tools/azure/debian_32bit_lock.txt' SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '4' # non-default seed - -- template: build_tools/azure/posix.yml - parameters: - name: macOS - vmImage: macOS-15 - dependsOn: [linting, git_commit, Ubuntu_Jammy_Jellyfish] - # Runs when dependencies succeeded or skipped - condition: | - and( - not(or(failed(), canceled())), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[ci skip]')) - ) - matrix: - pylatest_conda_forge_mkl_no_openmp: - DISTRIB: 'conda' - LOCK_FILE: './build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock' - SKLEARN_TEST_NO_OPENMP: 'true' - SKLEARN_SKIP_OPENMP_TEST: 'true' - SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '6' # non-default seed From 0e729831aeb5574c806e87a74bcefd4e76ac6bdc Mon Sep 17 00:00:00 2001 From: Auguste Baum <52001167+augustebaum@users.noreply.github.com> Date: Wed, 14 Jan 2026 14:23:18 +0100 Subject: [PATCH 125/462] CI Run all Azure jobs in parallel (#33077) --- azure-pipelines.yml | 9 +---- build_tools/azure/posix-all-parallel.yml | 50 ------------------------ doc/developers/contributing.rst | 1 - 3 files changed, 2 insertions(+), 58 deletions(-) delete mode 100644 build_tools/azure/posix-all-parallel.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 80c8a9ec73f4c..ee51ddf5c8b75 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -114,12 +114,7 @@ jobs: SCIPY_ARRAY_API: '1' # Check compilation with Ubuntu 22.04 LTS (Jammy Jellyfish) and scipy from conda-forge -# By default the CI is sequential, where `Ubuntu_Jammy_Jellyfish` runs first and -# the others jobs are run only if `Ubuntu_Jammy_Jellyfish` succeeds. -# When "[azure parallel]" is in the commit message, `Ubuntu_Jammy_Jellyfish` will -# run in parallel with the rest of the jobs. On Azure, the job's name will be -# `Ubuntu_Jammy_Jellyfish_Parallel`. -- template: build_tools/azure/posix-all-parallel.yml +- template: build_tools/azure/posix.yml parameters: name: Ubuntu_Jammy_Jellyfish vmImage: ubuntu-22.04 @@ -142,7 +137,7 @@ jobs: parameters: name: Linux_Docker vmImage: ubuntu-24.04 - dependsOn: [linting, git_commit, Ubuntu_Jammy_Jellyfish] + dependsOn: [linting, git_commit] # Runs when dependencies succeeded or skipped condition: | and( diff --git a/build_tools/azure/posix-all-parallel.yml b/build_tools/azure/posix-all-parallel.yml deleted file mode 100644 index 45d2b4569110f..0000000000000 --- a/build_tools/azure/posix-all-parallel.yml +++ /dev/null @@ -1,50 +0,0 @@ -# This configuration allows enables a job based on `posix.yml` to have two modes: -# -# 1. When `[azure parallel]` *is not* in the commit message, then this job will -# run first. If this job succeeds, then all dependent jobs can run. -# 2. When `[azure parallel]` *is* in the commit message, then this job will -# run with name `{{ parameters.name }}_Parallel` along with all other jobs. -# -# To enable this template, all dependent jobs should check if this job succeeded -# or skipped by using: -# dependsOn: in(dependencies[{{ parameters.name }}]['result'], 'Succeeded', 'Skipped') - -parameters: - name: '' - vmImage: '' - matrix: [] - dependsOn: [] - condition: '' - commitMessage: '' - -jobs: - -# When [azure parallel] *is not* in the commit message, this job will run -# first. -- template: posix.yml - parameters: - name: ${{ parameters.name }} - vmImage: ${{ parameters.vmImage }} - matrix: ${{ parameters.matrix }} - dependsOn: ${{ parameters.dependsOn }} - condition: | - and( - ${{ parameters.condition }}, - not(contains(${{ parameters.commitMessage }}, '[azure parallel]')) - ) - -# When [azure parallel] *is* in the commit message, this job and dependent -# jobs will run in parallel. Implementation-wise, the job above is skipped and -# this job, named ${{ parameters.name }}_Parallel, will run in parallel with -# the other jobs. -- template: posix.yml - parameters: - name: ${{ parameters.name }}_Parallel - vmImage: ${{ parameters.vmImage }} - matrix: ${{ parameters.matrix }} - dependsOn: ${{ parameters.dependsOn }} - condition: | - and( - ${{ parameters.condition }}, - contains(${{ parameters.commitMessage }}, '[azure parallel]') - ) diff --git a/doc/developers/contributing.rst b/doc/developers/contributing.rst index 06f36cc0fe3d5..20017f7d3746e 100644 --- a/doc/developers/contributing.rst +++ b/doc/developers/contributing.rst @@ -539,7 +539,6 @@ Commit Message Marker Action Taken by CI [scipy-dev] Build & test with our dependencies (numpy, scipy, etc.) development builds [free-threaded] Build & test with CPython 3.14 free-threaded [pyodide] Build & test with Pyodide -[azure parallel] Run Azure CI jobs in parallel [float32] Run float32 tests by setting `SKLEARN_RUN_FLOAT32_TESTS=1`. See :ref:`environment_variable` for more details [all random seeds] Run tests using the `global_random_seed` fixture with all random seeds. See `this `_ From 28a733911f8e4b37ab98a320b2540c4a20989625 Mon Sep 17 00:00:00 2001 From: Auguste Baum <52001167+augustebaum@users.noreply.github.com> Date: Wed, 14 Jan 2026 15:26:17 +0100 Subject: [PATCH 126/462] CI Port ubuntu_2204 test job from Azure to GHA (#33078) --- .github/workflows/unit-tests.yml | 9 +++++++++ azure-pipelines.yml | 20 -------------------- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index bc6f266e6022a..65b0324be6c4b 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -127,6 +127,15 @@ jobs: DISTRIB: conda LOCK_FILE: build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock + # Check compilation with Ubuntu 22.04 LTS (Jammy Jellyfish) and scipy from conda-forge + - name: Linux x86-64 pymin_conda_forge_openblas_ubuntu_2204 + os: ubuntu-22.04 + DISTRIB: conda + LOCK_FILE: build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock + SKLEARN_WARNINGS_AS_ERRORS: 1 + COVERAGE: false + SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 0 # non-default seed + # Linux build with minimum supported version of dependencies - name: Linux x86-64 pymin_conda_forge_openblas_min_dependencies os: ubuntu-22.04 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ee51ddf5c8b75..31f797dbde270 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -113,26 +113,6 @@ jobs: SKLEARN_SKIP_NETWORK_TESTS: '0' SCIPY_ARRAY_API: '1' -# Check compilation with Ubuntu 22.04 LTS (Jammy Jellyfish) and scipy from conda-forge -- template: build_tools/azure/posix.yml - parameters: - name: Ubuntu_Jammy_Jellyfish - vmImage: ubuntu-22.04 - dependsOn: [git_commit, linting] - condition: | - and( - succeeded(), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[ci skip]')) - ) - commitMessage: dependencies['git_commit']['outputs']['commit.message'] - matrix: - pymin_conda_forge_openblas_ubuntu_2204: - DISTRIB: 'conda' - LOCK_FILE: './build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock' - SKLEARN_WARNINGS_AS_ERRORS: '1' - COVERAGE: 'false' - SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '0' # non-default seed - - template: build_tools/azure/posix-docker.yml parameters: name: Linux_Docker From 6c084a8152d41419fb7baf2bc1692890385d6599 Mon Sep 17 00:00:00 2001 From: pavitra danappa byali Date: Wed, 14 Jan 2026 20:03:02 +0530 Subject: [PATCH 127/462] DOC Fix incomplete sentence in linear model introduction (#33024) --- doc/modules/linear_model.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/modules/linear_model.rst b/doc/modules/linear_model.rst index 242f2fb5515b9..179237441703a 100644 --- a/doc/modules/linear_model.rst +++ b/doc/modules/linear_model.rst @@ -8,8 +8,9 @@ Linear Models The following are a set of methods intended for regression in which the target value is expected to be a linear combination of the features. -In mathematical notation, if :math:`\hat{y}` is the predicted -value. +In mathematical notation, the predicted value :math:`\hat{y}` can be +written as: + .. math:: \hat{y}(w, x) = w_0 + w_1 x_1 + ... + w_p x_p From d85628422cd1f36c886670a42ff70f92a5a695d0 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Thu, 15 Jan 2026 07:01:16 +0100 Subject: [PATCH 128/462] MNT rename l1_reg to alpha in enet_coordinate_descent_multi_task (#33083) --- sklearn/linear_model/_cd_fast.pyx | 56 +++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/sklearn/linear_model/_cd_fast.pyx b/sklearn/linear_model/_cd_fast.pyx index 4fabb7632b723..ffb44e9c992fb 100644 --- a/sklearn/linear_model/_cd_fast.pyx +++ b/sklearn/linear_model/_cd_fast.pyx @@ -1245,8 +1245,8 @@ cdef (floating, floating) gap_enet_multi_task( int n_features, int n_tasks, const floating[::1, :] W, # in - floating l1_reg, - floating l2_reg, + floating alpha, + floating beta, const floating[::1, :] X, # in const floating[::1, :] Y, # in const floating[::1, :] R, # in @@ -1263,7 +1263,7 @@ cdef (floating, floating) gap_enet_multi_task( R : memoryview of shape (n_samples, n_tasks) Current residuals = Y - X @ W.T XtA : memoryview of shape (n_features, n_tasks) - Inplace calculated as XtA = X.T @ R - l2_reg * W.T + Inplace calculated as XtA = X.T @ R - beta * W.T XtA_row_norms : memoryview of shape n_features Inplace calculated as np.sqrt(np.sum(XtA ** 2, axis=1)) """ @@ -1276,22 +1276,22 @@ cdef (floating, floating) gap_enet_multi_task( cdef unsigned int t, j # w_l2_norm2 = linalg.norm(W, ord="fro") ** 2 - if l2_reg > 0: + if beta > 0: w_l2_norm2 = _dot(n_features * n_tasks, &W[0, 0], 1, &W[0, 0], 1) # R_norm2 = linalg.norm(R, ord="fro") ** 2 R_norm2 = _dot(n_samples * n_tasks, &R[0, 0], 1, &R[0, 0], 1) # Ry = np.sum(R * Y) - if not (l1_reg == 0 and l2_reg == 0): + if not (alpha == 0 and beta == 0): Ry = _dot(n_samples * n_tasks, &R[0, 0], 1, &Y[0, 0], 1) - if l1_reg == 0: + if alpha == 0: # XtA = X.T @ R for j in range(n_features): for t in range(n_tasks): XtA[j, t] = _dot(n_samples, &X[0, j], 1, &R[0, t], 1) # ||X'R||_2^2 dual_norm_XtA = _dot(n_features * n_tasks, &XtA[0, 0], 1, &XtA[0, 0], 1) - if l2_reg == 0: + if beta == 0: # This is OLS, no dual gap available. Resort to first order condition # X'R = 0 # gap = ||X'R||_2^2 @@ -1299,14 +1299,14 @@ cdef (floating, floating) gap_enet_multi_task( gap = dual_norm_XtA return gap, dual_norm_XtA # This is Ridge regression, we use formulation B for the dual gap. - gap = R_norm2 + 0.5 * l2_reg * w_l2_norm2 - Ry - gap += 1 / (2 * l2_reg) * dual_norm_XtA + gap = R_norm2 + 0.5 * beta * w_l2_norm2 - Ry + gap += 1 / (2 * beta) * dual_norm_XtA return gap, dual_norm_XtA - # XtA = X.T @ R - l2_reg * W.T + # XtA = X.T @ R - beta * W.T for j in range(n_features): for t in range(n_tasks): - XtA[j, t] = _dot(n_samples, &X[0, j], 1, &R[0, t], 1) - l2_reg * W[t, j] + XtA[j, t] = _dot(n_samples, &X[0, j], 1, &R[0, t], 1) - beta * W[t, j] # dual_norm_XtA = np.max(np.sqrt(np.sum(XtA ** 2, axis=1))) dual_norm_XtA = 0.0 @@ -1322,8 +1322,8 @@ cdef (floating, floating) gap_enet_multi_task( w_l21_norm += _nrm2(n_tasks, &W[0, ii], 1) gap = dual_gap_formulation_A( - alpha=l1_reg, - beta=l2_reg, + alpha=alpha, + beta=beta, w_l1_norm=w_l21_norm, w_l2_norm2=w_l2_norm2, R_norm2=R_norm2, @@ -1335,8 +1335,8 @@ cdef (floating, floating) gap_enet_multi_task( def enet_coordinate_descent_multi_task( floating[::1, :] W, - floating l1_reg, - floating l2_reg, + floating alpha, + floating beta, const floating[::1, :] X, const floating[::1, :] Y, unsigned int max_iter, @@ -1350,7 +1350,7 @@ def enet_coordinate_descent_multi_task( We minimize - 0.5 * norm(Y - X W.T, 2)^2 + l1_reg ||W.T||_21 + 0.5 * l2_reg norm(W.T, 2)^2 + 0.5 * norm(Y - X W.T, 2)^2 + alpha * ||W.T||_21 + 0.5 * beta * norm(W.T, 2)^2 The algorithm follows Noah Simon, Jerome Friedman, Trevor Hastie. 2013. @@ -1414,7 +1414,7 @@ def enet_coordinate_descent_multi_task( cdef uint32_t rand_r_state_seed = rng.randint(0, RAND_R_MAX) cdef uint32_t* rand_r_state = &rand_r_state_seed - if l1_reg == 0: + if alpha == 0: # No screeing without L1-penalty. do_screening = False @@ -1435,7 +1435,7 @@ def enet_coordinate_descent_multi_task( # Check convergence before entering the main loop. gap, dual_norm_XtA = gap_enet_multi_task( - n_samples, n_features, n_tasks, W, l1_reg, l2_reg, X, Y, R, XtA, XtA_row_norms + n_samples, n_features, n_tasks, W, alpha, beta, X, Y, R, XtA, XtA_row_norms ) if gap <= tol: with gil: @@ -1452,9 +1452,9 @@ def enet_coordinate_descent_multi_task( excluded_set[j] = 1 continue # Xj_theta = ||X[:,j] @ dual_theta||_2 - Xj_theta = XtA_row_norms[j] / fmax(l1_reg, dual_norm_XtA) - d_j = (1 - Xj_theta) / sqrt(norm2_cols_X[j] + l2_reg) - if d_j <= sqrt(2 * gap) / l1_reg: + Xj_theta = XtA_row_norms[j] / fmax(alpha, dual_norm_XtA) + d_j = (1 - Xj_theta) / sqrt(norm2_cols_X[j] + beta) + if d_j <= sqrt(2 * gap) / alpha: # include feature j active_set[n_active] = j excluded_set[j] = 0 @@ -1502,9 +1502,9 @@ def enet_coordinate_descent_multi_task( # nn = sqrt(np.sum(tmp ** 2)) nn = _nrm2(n_tasks, &tmp[0], 1) - # W[:, j] = tmp * fmax(1. - l1_reg / nn, 0) / (norm2_cols_X[j] + l2_reg) + # W[:, j] = tmp * fmax(1. - alpha / nn, 0) / (norm2_cols_X[j] + beta) _copy(n_tasks, &tmp[0], 1, &W[0, j], 1) - _scal(n_tasks, fmax(1. - l1_reg / nn, 0) / (norm2_cols_X[j] + l2_reg), + _scal(n_tasks, fmax(1. - alpha / nn, 0) / (norm2_cols_X[j] + beta), &W[0, j], 1) # Update residual @@ -1535,7 +1535,7 @@ def enet_coordinate_descent_multi_task( # the tolerance: check the duality gap as ultimate stopping # criterion gap, dual_norm_XtA = gap_enet_multi_task( - n_samples, n_features, n_tasks, W, l1_reg, l2_reg, X, Y, R, XtA, XtA_row_norms + n_samples, n_features, n_tasks, W, alpha, beta, X, Y, R, XtA, XtA_row_norms ) if gap <= tol: # return if we reached desired tolerance @@ -1549,9 +1549,9 @@ def enet_coordinate_descent_multi_task( if excluded_set[j]: continue # Xj_theta = ||X[:,j] @ dual_theta||_2 - Xj_theta = XtA_row_norms[j] / fmax(l1_reg, dual_norm_XtA) - d_j = (1 - Xj_theta) / sqrt(norm2_cols_X[j] + l2_reg) - if d_j <= sqrt(2 * gap) / l1_reg: + Xj_theta = XtA_row_norms[j] / fmax(alpha, dual_norm_XtA) + d_j = (1 - Xj_theta) / sqrt(norm2_cols_X[j] + beta) + if d_j <= sqrt(2 * gap) / alpha: # include feature j active_set[n_active] = j excluded_set[j] = 0 @@ -1570,7 +1570,7 @@ def enet_coordinate_descent_multi_task( message_conv + f" Duality gap: {gap:.6e}, tolerance: {tol:.3e}" ) - if l1_reg < np.finfo(np.float64).eps: + if alpha < np.finfo(np.float64).eps: message += "\n" + message_ridge warnings.warn(message, ConvergenceWarning) From 0707e6287f128d824860d970896d414d9d96da7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Thu, 15 Jan 2026 10:07:51 +0100 Subject: [PATCH 129/462] TST Mark test_logreg_l1 as thread-unsafe (#33080) --- sklearn/linear_model/tests/test_logistic.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index 22e7458373f99..1d655599c55ce 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -1218,6 +1218,9 @@ def test_logreg_intercept_scaling_zero(): assert clf.intercept_ == 0.0 +# XXX: investigate thread-safety bug that might be related to: +# https://github.com/scikit-learn/scikit-learn/issues/31883 +@pytest.mark.thread_unsafe @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) def test_logreg_l1(global_random_seed, csr_container): # Because liblinear penalizes the intercept and saga does not, we do not From d1424602ff403b7e50e97dc145a60e8535c686ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Thu, 15 Jan 2026 16:29:27 +0100 Subject: [PATCH 130/462] CI Fix scipy-dev build issues (#33087) --- build_tools/azure/install.sh | 5 ++++- sklearn/utils/_testing.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/build_tools/azure/install.sh b/build_tools/azure/install.sh index 6a462aea3ae95..8523bd2bb4274 100755 --- a/build_tools/azure/install.sh +++ b/build_tools/azure/install.sh @@ -72,11 +72,14 @@ python_environment_install_and_activate() { if [[ "$DISTRIB" == "conda-pip-scipy-dev" ]]; then echo "Installing development dependency wheels" dev_anaconda_url=https://pypi.anaconda.org/scientific-python-nightly-wheels/simple - dev_packages="numpy scipy pandas Cython" + dev_packages="numpy scipy pandas" pip install --pre --upgrade --timeout=60 --extra-index $dev_anaconda_url $dev_packages --only-binary :all: check_packages_dev_version $dev_packages + echo "Installing Cython from latest sources" + # NO_CYTHON_COMPILE=true installs Cython as a pure Python package (faster install) + NO_CYTHON_COMPILE=true pip install https://github.com/cython/cython/archive/master.zip echo "Installing joblib from latest sources" pip install https://github.com/joblib/joblib/archive/master.zip echo "Installing pillow from latest sources" diff --git a/sklearn/utils/_testing.py b/sklearn/utils/_testing.py index c3a1b5d6b73b7..c8e64fc7f1d63 100644 --- a/sklearn/utils/_testing.py +++ b/sklearn/utils/_testing.py @@ -1423,6 +1423,16 @@ def to_filterwarning_str(self): WarningInfo( "ignore", message="Attribute n is deprecated", category=DeprecationWarning ), + # numpy 2.5 DeprecationWarning in joblib, see + # https://github.com/joblib/joblib/issues/1772 + WarningInfo( + "ignore", + message=( + "Setting the shape on a NumPy array has been deprecated" + r" in NumPy 2.5" + ), + category=DeprecationWarning, + ), # Python 3.12 warnings from sphinx-gallery fixed in master but not # released yet, see # https://github.com/sphinx-gallery/sphinx-gallery/pull/1242 From e96804eeb7604700b74270dfafe746d88bab7411 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Thu, 15 Jan 2026 16:57:03 +0100 Subject: [PATCH 131/462] FIX add actual class name to error message in class vs. instance error (#33088) Co-authored-by: Olivier Grisel --- .../compose/tests/test_column_transformer.py | 17 +++++++----- sklearn/tests/test_pipeline.py | 27 ++++++++++--------- sklearn/utils/metaestimators.py | 4 +-- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index f37ee10c2cc05..f24830417a3ae 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -94,18 +94,21 @@ def transform(self, X, y=None): @pytest.mark.parametrize( - "transformers", + "transformers, class_name", [ - [("trans1", Trans, [0]), ("trans2", Trans(), [1])], - [("trans1", Trans(), [0]), ("trans2", Trans, [1])], - [("drop", "drop", [0]), ("trans2", Trans, [1])], - [("trans1", Trans, [0]), ("passthrough", "passthrough", [1])], + ([("trans1", Trans, [0]), ("trans2", Trans(), [1])], "Trans"), + ([("trans1", Trans(), [0]), ("trans2", Trans, [1])], "Trans"), + ([("drop", "drop", [0]), ("trans2", Trans, [1])], "Trans"), + ([("trans1", Trans, [0]), ("passthrough", "passthrough", [1])], "Trans"), ], ) -def test_column_transformer_raises_class_not_instance_error(transformers): +def test_column_transformer_raises_class_not_instance_error(transformers, class_name): # non-regression tests for https://github.com/scikit-learn/scikit-learn/issues/32719 ct = ColumnTransformer(transformers) - msg = "Expected an estimator instance (.*()), got estimator class instead (.*)." + msg = re.escape( + f"Expected an estimator instance ({class_name}()), " + f"got estimator class instead ({class_name})." + ) with pytest.raises(TypeError, match=msg): ct.fit([[1]]) diff --git a/sklearn/tests/test_pipeline.py b/sklearn/tests/test_pipeline.py index 00bddae53d34e..063450f50a162 100644 --- a/sklearn/tests/test_pipeline.py +++ b/sklearn/tests/test_pipeline.py @@ -283,22 +283,25 @@ def test_pipeline_invalid_parameters(): @pytest.mark.parametrize( - "meta_estimators", + "meta_estimators, class_name", [ - Pipeline([("pca", PCA)]), - Pipeline([("pca", PCA), ("ident", None)]), - Pipeline([("passthrough", "passthrough"), ("pca", PCA)]), - Pipeline([("passthrough", None), ("pca", PCA)]), - Pipeline([("scale", StandardScaler), ("pca", PCA())]), - FeatureUnion([("pca", PCA), ("svd", TruncatedSVD())]), - FeatureUnion([("pca", PCA()), ("svd", TruncatedSVD)]), - FeatureUnion([("drop", "drop"), ("svd", TruncatedSVD)]), - FeatureUnion([("pca", PCA), ("passthrough", "passthrough")]), + (Pipeline([("pca", PCA)]), "PCA"), + (Pipeline([("pca", PCA), ("ident", None)]), "PCA"), + (Pipeline([("passthrough", "passthrough"), ("pca", PCA)]), "PCA"), + (Pipeline([("passthrough", None), ("pca", PCA)]), "PCA"), + (Pipeline([("scale", StandardScaler), ("pca", PCA())]), "StandardScaler"), + (FeatureUnion([("pca", PCA), ("svd", TruncatedSVD())]), "PCA"), + (FeatureUnion([("pca", PCA()), ("svd", TruncatedSVD)]), "TruncatedSVD"), + (FeatureUnion([("drop", "drop"), ("svd", TruncatedSVD)]), "TruncatedSVD"), + (FeatureUnion([("pca", PCA), ("passthrough", "passthrough")]), "PCA"), ], ) -def test_meta_estimator_raises_class_not_instance_error(meta_estimators): +def test_meta_estimator_raises_class_not_instance_error(meta_estimators, class_name): # non-regression tests for https://github.com/scikit-learn/scikit-learn/issues/32719 - msg = "Expected an estimator instance (.*()), got estimator class instead (.*)." + msg = re.escape( + f"Expected an estimator instance ({class_name}()), " + f"got estimator class instead ({class_name})." + ) with pytest.raises(TypeError, match=msg): meta_estimators.fit([[1]]) diff --git a/sklearn/utils/metaestimators.py b/sklearn/utils/metaestimators.py index 5f2a38f16f96d..38b4a065f9029 100644 --- a/sklearn/utils/metaestimators.py +++ b/sklearn/utils/metaestimators.py @@ -104,8 +104,8 @@ def _check_estimators_are_instances(self, estimators): for estimator in estimators: if isinstance(estimator, type): raise TypeError( - "Expected an estimator instance ({estimator.__name__}()), got " - "estimator class instead ({estimator.__name__})." + f"Expected an estimator instance ({estimator.__name__}()), got " + f"estimator class instead ({estimator.__name__})." ) From fdb20acfa6f197f316bc3cc3a2cab71351136128 Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Thu, 15 Jan 2026 18:34:18 +0100 Subject: [PATCH 132/462] DOC Simplify metadata routing example and add short example to docstrings (#32191) --- .../miscellaneous/plot_metadata_routing.py | 119 +++++++--------- sklearn/utils/_metadata_requests.py | 129 ++++++++++++++++-- 2 files changed, 170 insertions(+), 78 deletions(-) diff --git a/examples/miscellaneous/plot_metadata_routing.py b/examples/miscellaneous/plot_metadata_routing.py index 63dddac1f9c2f..f27d8fb2ec527 100644 --- a/examples/miscellaneous/plot_metadata_routing.py +++ b/examples/miscellaneous/plot_metadata_routing.py @@ -1,22 +1,22 @@ """ -================ -Metadata Routing -================ +===================================================== +Developing Estimators Compliant with Metadata Routing +===================================================== .. currentmodule:: sklearn This document shows how you can use the :ref:`metadata routing mechanism -` in scikit-learn to route metadata to the estimators, -scorers, and CV splitters consuming them. +` in scikit-learn to build estimators that route metadata +to other estimators, scorers, and CV splitters, that can consume :term:`metadata`. To better understand the following document, we need to introduce two concepts: -routers and consumers. A router is an object which forwards some given data and -metadata to other objects. In most cases, a router is a :term:`meta-estimator`, -i.e. an estimator which takes another estimator as a parameter. A function such -as :func:`sklearn.model_selection.cross_validate` which takes an estimator as a -parameter and forwards data and metadata, is also a router. +:term:`routers ` and :term:`consumers `. A :term:`router` is an object +which forwards some given data and metadata to other objects. In most cases, a router is +a :term:`meta-estimator`, i.e. an estimator which takes another estimator as a +parameter. A function such as :func:`sklearn.model_selection.cross_validate` which takes +an estimator as a parameter and forwards data and metadata, is also a router. -A consumer, on the other hand, is an object which accepts and uses some given +A :term:`consumer`, on the other hand, is an object which accepts and uses some given metadata. For instance, an estimator taking into account ``sample_weight`` in its :term:`fit` method is a consumer of ``sample_weight``. @@ -51,7 +51,6 @@ from sklearn.utils.metadata_routing import ( MetadataRouter, MethodMapping, - get_routing_for_object, process_routing, ) from sklearn.utils.validation import check_is_fitted @@ -92,7 +91,7 @@ def print_routing(obj): # ------------------- # Here we demonstrate how an estimator can expose the required API to support # metadata routing as a consumer. Imagine a simple classifier accepting -# ``sample_weight`` as a metadata on its ``fit`` and ``groups`` in its +# ``sample_weight`` as a metadata in its ``fit`` and ``groups`` in its # ``predict`` method: @@ -146,10 +145,21 @@ def predict(self, X, groups=None): # metadata and the set values are ignored, since a consumer does not # validate or route given metadata. A simple usage of the above estimator # would work as expected. - -est = ExampleClassifier() -est.fit(X, y, sample_weight=my_weights) -est.predict(X[:3, :], groups=my_groups) +# +# .. code-block:: python +# +# est = ExampleClassifier() +# est.fit(X, y, sample_weight=my_weights) +# est.predict(X[:3, :], groups=my_groups) +# +# Out: +# +# .. code-block:: python-console +# +# Received sample_weight of length = 100 in ExampleClassifier. +# Received groups of length = 100 in ExampleClassifier. +# +# array([1., 1., 1.]) # %% # Routing Meta-Estimator @@ -157,6 +167,13 @@ def predict(self, X, groups=None): # Now, we show how to design a meta-estimator to be a router. As a simplified # example, here is a meta-estimator, which doesn't do much other than routing # the metadata. +# +# To make the meta-estimator a router, you only need to: +# +# - define its `get_metadata_routing` method, which returns a `MetadataRouter` +# instance in charge of configuring the metadata routing. +# - use `process_routing` inside its methods (`fit`, `predict`, ...) to properly +# route the metadata from the meta-estimator to its sub-estimator. class MetaClassifier(MetaEstimatorMixin, ClassifierMixin, BaseEstimator): @@ -166,7 +183,7 @@ def __init__(self, estimator): def get_metadata_routing(self): # This method defines the routing for this meta-estimator. # In order to do so, a `MetadataRouter` instance is created, and the - # routing is added to it. More explanations follow below. + # routing is added to it. router = MetadataRouter(owner=self).add( estimator=self.estimator, method_mapping=MethodMapping() @@ -177,56 +194,36 @@ def get_metadata_routing(self): return router def fit(self, X, y, **fit_params): - # `get_routing_for_object` returns a copy of the `MetadataRouter` - # constructed by the above `get_metadata_routing` method, that is - # internally called. - request_router = get_routing_for_object(self) - # Meta-estimators are responsible for validating the given metadata. - # `method` refers to the parent's method, i.e. `fit` in this example. - request_router.validate_metadata(params=fit_params, method="fit") - # `MetadataRouter.route_params` maps the given metadata to the metadata - # required by the underlying estimator based on the routing information - # defined by the MetadataRouter. The output of type `Bunch` has a key - # for each consuming object and those hold keys for their consuming - # methods, which then contain key for the metadata which should be - # routed to them. - routed_params = request_router.route_params(params=fit_params, caller="fit") - + # Get information on all the metadata that should be routed from here to + # consuming methods. + routed_params = process_routing(self, "fit", **fit_params) # A sub-estimator is fitted and its classes are attributed to the - # meta-estimator. + # meta-estimator. Since we call the sub-estimator's fit method, we pass the + # the metadata stored in `routed_params.estimator.fit`. self.estimator_ = clone(self.estimator).fit(X, y, **routed_params.estimator.fit) self.classes_ = self.estimator_.classes_ return self def predict(self, X, **predict_params): check_is_fitted(self) - # As in `fit`, we get a copy of the object's MetadataRouter, - request_router = get_routing_for_object(self) - # then we validate the given metadata, - request_router.validate_metadata(params=predict_params, method="predict") - # and then prepare the input to the underlying `predict` method. - routed_params = request_router.route_params( - params=predict_params, caller="predict" - ) + # As in `fit`, we get information on all the metadata that should be routed and + # pass the metadata that is stored in `routed_params.estimator.predict` to the + # sub-estimator's predict method. + routed_params = process_routing(self, "predict", **predict_params) return self.estimator_.predict(X, **routed_params.estimator.predict) # %% # Let's break down different parts of the above code. # -# First, the :meth:`~utils.metadata_routing.get_routing_for_object` takes our -# meta-estimator (``self``) and returns a -# :class:`~utils.metadata_routing.MetadataRouter` or, a -# :class:`~utils.metadata_routing.MetadataRequest` if the object is a consumer, -# based on the output of the estimator's ``get_metadata_routing`` method. -# -# Then in each method, we use the ``route_params`` method to construct a -# dictionary of the form ``{"object_name": {"method_name": {"metadata": +# In each method, we use the ``process_routing`` function to construct a +# :class:`~utils.Bunch` of the form ``{"object_name": {"method_name": {"metadata": # value}}}`` to pass to the underlying estimator's method. The ``object_name`` -# (``estimator`` in the above ``routed_params.estimator.fit`` example) is the -# same as the one added in the ``get_metadata_routing``. ``validate_metadata`` -# makes sure all given metadata are requested to avoid silent bugs. -# +# (``estimator`` in ``routed_params.estimator.fit``) is the same as the `estimator` +# added in the ``get_metadata_routing``. ``process_routing`` also validates the input +# metadata: it makes sure all given metadata are requested to avoid silent bugs. + +# %% # Next, we illustrate the different behaviors and notably the type of errors # raised. @@ -378,24 +375,14 @@ def fit(self, X, y, sample_weight, **fit_params): # We add `sample_weight` to the `fit_params` dictionary. if sample_weight is not None: fit_params["sample_weight"] = sample_weight - - request_router = get_routing_for_object(self) - request_router.validate_metadata(params=fit_params, method="fit") - routed_params = request_router.route_params(params=fit_params, caller="fit") + routed_params = process_routing(self, "fit", **fit_params) self.estimator_ = clone(self.estimator).fit(X, y, **routed_params.estimator.fit) self.classes_ = self.estimator_.classes_ return self def predict(self, X, **predict_params): check_is_fitted(self) - # As in `fit`, we get a copy of the object's MetadataRouter, - request_router = get_routing_for_object(self) - # we validate the given metadata, - request_router.validate_metadata(params=predict_params, method="predict") - # and then prepare the input to the underlying ``predict`` method. - routed_params = request_router.route_params( - params=predict_params, caller="predict" - ) + routed_params = process_routing(self, "predict", **predict_params) return self.estimator_.predict(X, **routed_params.estimator.predict) diff --git a/sklearn/utils/_metadata_requests.py b/sklearn/utils/_metadata_requests.py index c871471403afe..d8d4e229cb53f 100644 --- a/sklearn/utils/_metadata_requests.py +++ b/sklearn/utils/_metadata_requests.py @@ -558,13 +558,17 @@ def __str__(self): class MetadataRequest: - """Contains the metadata request info of a consumer. + """Container for storing metadata request info and an associated consumer (`owner`). Instances of `MethodMetadataRequest` are used in this class for each - available method under `metadatarequest.{method}`. + available method under `MetadataRequest(owner=obj).{method}`. - Consumer-only classes such as simple estimators return a serialized - version of this class as the output of `get_metadata_routing()`. + Every :term:`consumer` in scikit-learn has a `_metadata_request` attribute that is a + `MetadataRequest`. + + Read more on developing custom estimators that can route metadata in the + :ref:`Metadata Routing Developing Guide + `. .. versionadded:: 1.3 @@ -572,6 +576,21 @@ class MetadataRequest: ---------- owner : object The object to which these requests belong. + + Examples + -------- + >>> from sklearn import set_config + >>> set_config(enable_metadata_routing=True) + >>> from pprint import pprint + >>> from sklearn.utils.metadata_routing import MetadataRequest + >>> r = MetadataRequest(owner="any_object") + >>> r.fit.add_request(param="sample_weight", alias=True) + {'sample_weight': True} + >>> r.score.add_request(param="sample_weight", alias=False) + {'sample_weight': False} + >>> pprint(r) + {'fit': {'sample_weight': True}, 'score': {'sample_weight': False}} + >>> set_config(enable_metadata_routing=False) """ # this is here for us to use this attribute's value instead of doing @@ -754,7 +773,7 @@ def __str__(self): class MethodMapping: - """Stores the mapping between caller and callee methods for a :term:`router`. + """Stores the mapping between `caller` and `callee` methods for a :term:`router`. This class is primarily used in a ``get_metadata_routing()`` of a router object when defining the mapping between the router's methods and a sub-object (a @@ -763,7 +782,17 @@ class MethodMapping: Iterating through an instance of this class yields ``MethodPair(caller, callee)`` instances. + Read more on developing custom estimators that can route metadata in the + :ref:`Metadata Routing Developing Guide + `. + .. versionadded:: 1.3 + + Examples + -------- + >>> from sklearn.utils.metadata_routing import MethodMapping + >>> MethodMapping().add(caller="fit", callee="split") + [{'caller': 'fit', 'callee': 'split'}] """ def __init__(self): @@ -834,12 +863,40 @@ class MetadataRouter: :class:`~sklearn.utils.metadata_routing.MetadataRequest` or another :class:`~sklearn.utils.metadata_routing.MetadataRouter` instance. + Read more on developing custom estimators that can route metadata in the + :ref:`Metadata Routing Developing Guide + `. + .. versionadded:: 1.3 Parameters ---------- owner : object The object to which these requests belong. + + Examples + -------- + >>> from pprint import pprint + >>> from sklearn import set_config + >>> from sklearn.feature_selection import SelectFromModel + >>> from sklearn.linear_model import LinearRegression + >>> from sklearn.utils.metadata_routing import MetadataRouter, MethodMapping + >>> set_config(enable_metadata_routing=True) + >>> meta_estimator = SelectFromModel( + ... estimator=LinearRegression().set_fit_request(sample_weight=True) + ... ) + >>> router = MetadataRouter(owner=meta_estimator).add( + ... estimator=meta_estimator.estimator, + ... method_mapping=MethodMapping() + ... .add(caller="partial_fit", callee="partial_fit") + ... .add(caller="fit", callee="fit"), + ... ) + >>> pprint(router) + {'estimator': {'mapping': [{'caller': 'partial_fit', 'callee': 'partial_fit'}, + {'caller': 'fit', 'callee': 'fit'}], + 'router': {'fit': {'sample_weight': True}, + 'score': {'sample_weight': None}}}} + >>> set_config(enable_metadata_routing=False) """ # this is here for us to use this attribute's value instead of doing @@ -1185,7 +1242,7 @@ def get_routing_for_object(obj=None): :class:`~sklearn.utils.metadata_routing.MetadataRouter` or a :class:`~sklearn.utils.metadata_routing.MetadataRequest` from the given input. - This function always returns a copy or an instance constructed from the + This function always returns a copy or a new instance constructed from the input, such that changing the output of this function will not change the original object. @@ -1208,6 +1265,26 @@ def get_routing_for_object(obj=None): obj : MetadataRequest or MetadataRouter A ``MetadataRequest`` or a ``MetadataRouter`` taken or created from the given object. + + Examples + -------- + >>> from sklearn.datasets import make_classification + >>> from sklearn.pipeline import Pipeline + >>> from sklearn.preprocessing import StandardScaler + >>> from sklearn.linear_model import LogisticRegressionCV + >>> from sklearn.utils.metadata_routing import get_routing_for_object + >>> X, y = make_classification() + >>> pipe = Pipeline( + ... [("scaler", StandardScaler()), ("lr_cv", LogisticRegressionCV())] + ... ) + >>> pipe.fit(X, y) # doctest: +SKIP + Pipeline(steps=[('scaler', StandardScaler()), ('lr_cv', LogisticRegressionCV())]) + >>> type(get_routing_for_object(pipe)) + + >>> type(get_routing_for_object(pipe.named_steps.scaler)) + + >>> type(get_routing_for_object(pipe.named_steps.lr_cv)) + """ # doing this instead of a try/except since an AttributeError could be raised # for other reasons. @@ -1583,10 +1660,24 @@ def process_routing(_obj, _method, /, **kwargs): a call to this function would be: ``process_routing(self, "fit", sample_weight=sample_weight, **fit_params)``. + Internally, the function uses the router's `MetadataRouter` object (as + returned by a call to its `get_metadata_routing` method) to validate + per method that the routed metadata had been requested by the underlying + estimator, and extracts a mapping of the given metadata to the requested + metadata based on the routing information defined by the `MetadataRouter`. + Note that if routing is not enabled and ``kwargs`` is empty, then it returns an empty routing where ``process_routing(...).ANYTHING.ANY_METHOD`` is always an empty dictionary. + The output of this function is a :class:`~sklearn.utils.Bunch` that has a key for + each consuming object and those hold keys for their consuming methods, which then + contain keys for the metadata which should be routed to them. + + Read more on developing custom estimators that can route metadata in the + :ref:`Metadata Routing Developing Guide + `. + .. versionadded:: 1.3 Parameters @@ -1604,12 +1695,26 @@ def process_routing(_obj, _method, /, **kwargs): Returns ------- routed_params : Bunch - A :class:`~utils.Bunch` of the form ``{"object_name": {"method_name": - {metadata: value}}}`` which can be used to pass the required metadata to - A :class:`~sklearn.utils.Bunch` of the form ``{"object_name": {"method_name": - {metadata: value}}}`` which can be used to pass the required metadata to - corresponding methods or corresponding child objects. The object names - are those defined in `obj.get_metadata_routing()`. + A :class:`~sklearn.utils.Bunch` of the form ``{"object_name": + {"method_name": {metadata: value}}}`` which can be used to pass the + required metadata to corresponding methods or corresponding child objects. + The object names are those defined in `obj.get_metadata_routing()`. + + Examples + -------- + >>> import numpy as np + >>> from sklearn import set_config + >>> from sklearn.utils.metadata_routing import process_routing + >>> from sklearn.linear_model import Ridge + >>> from sklearn.feature_selection import SelectFromModel + >>> set_config(enable_metadata_routing=True) + >>> process_routing( + ... SelectFromModel(Ridge().set_fit_request(sample_weight=True)), + ... "fit", + ... sample_weight=np.array([1, 1, 2]), + ... ) + {'estimator': {'fit': {'sample_weight': array([1, 1, 2])}}} + >>> set_config(enable_metadata_routing=False) """ if not kwargs: # If routing is not enabled and kwargs are empty, then we don't have to From 6ea7b189c105793d925e006064b66b6be9857d44 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Thu, 15 Jan 2026 18:57:37 +0100 Subject: [PATCH 133/462] CI remove scipy<1.16.2 requirement in wheel builder (#33090) --- .github/workflows/wheels.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index 5c08cc860415b..a1cf2d76a9b2d 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -228,10 +228,7 @@ jobs: CIBW_BEFORE_TEST_WINDOWS: bash build_tools/github/build_minimal_windows_image.sh ${{ matrix.python }} ${{matrix.platform_id}} CIBW_ENVIRONMENT_PASS_LINUX: RUNNER_OS # TODO Put back pandas when there is a pandas release with Python 3.14 wheels - # TODO Remove scipy<1.16.2 when hang on macOS_x86_64 has been fixed. - # See https://github.com/scikit-learn/scikit-learn/issues/32279 for - # more details. - CIBW_TEST_REQUIRES: ${{ contains(matrix.python, '314') && 'pytest' || 'pytest pandas' }} scipy<1.16.2 + CIBW_TEST_REQUIRES: ${{ contains(matrix.python, '314') && 'pytest' || 'pytest pandas' }} scipy # On Windows, we use a custom Docker image and CIBW_TEST_REQUIRES_WINDOWS # does not make sense because it would install dependencies in the host # rather than inside the Docker image From b76422979fc4d215d8063dc27e4b8acdcd33c60d Mon Sep 17 00:00:00 2001 From: Arthur Lacote Date: Thu, 15 Jan 2026 23:29:03 +0100 Subject: [PATCH 134/462] FIX: fix deprecation of "friedman_mse" criterion in forests (#33039) Co-authored-by: Christian Lorentzen --- sklearn/ensemble/_forest.py | 20 ++++++++++++++++++++ sklearn/ensemble/tests/test_forest.py | 13 ++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/sklearn/ensemble/_forest.py b/sklearn/ensemble/_forest.py index b7b4707dcaa0e..e1d666a8bf50f 100644 --- a/sklearn/ensemble/_forest.py +++ b/sklearn/ensemble/_forest.py @@ -1928,6 +1928,16 @@ def __init__( max_samples=max_samples, ) + if isinstance(criterion, str) and criterion == "friedman_mse": + # TODO(1.11): remove support of "friedman_mse" criterion. + criterion = "squared_error" + warn( + 'Value `"friedman_mse"` for `criterion` is deprecated and will be ' + 'removed in 1.11. It maps to `"squared_error"` as both ' + 'were always equivalent. Use `criterion="squared_error"` ' + "to remove this warning.", + FutureWarning, + ) self.criterion = criterion self.max_depth = max_depth self.min_samples_split = min_samples_split @@ -2662,6 +2672,16 @@ def __init__( max_samples=max_samples, ) + if isinstance(criterion, str) and criterion == "friedman_mse": + # TODO(1.11): remove support of "friedman_mse" criterion. + criterion = "squared_error" + warn( + 'Value `"friedman_mse"` for `criterion` is deprecated and will be ' + 'removed in 1.11. It maps to `"squared_error"` as both ' + 'were always equivalent. Use `criterion="squared_error"` ' + "to remove this warning.", + FutureWarning, + ) self.criterion = criterion self.max_depth = max_depth self.min_samples_split = min_samples_split diff --git a/sklearn/ensemble/tests/test_forest.py b/sklearn/ensemble/tests/test_forest.py index 20a452ecb75c4..b04c46c845d27 100644 --- a/sklearn/ensemble/tests/test_forest.py +++ b/sklearn/ensemble/tests/test_forest.py @@ -157,8 +157,12 @@ def test_iris_criterion(name, criterion): assert score > 0.5, "Failed with criterion %s and score = %f" % (criterion, score) +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize("name", FOREST_REGRESSORS) -@pytest.mark.parametrize("criterion", ("squared_error", "absolute_error")) +@pytest.mark.parametrize( + "criterion", ("squared_error", "friedman_mse", "absolute_error") +) def test_regression_criterion(name, criterion): # Check consistency on regression dataset. ForestRegressor = FOREST_REGRESSORS[name] @@ -1864,3 +1868,10 @@ def test_non_supported_criterion_raises_error_with_missing_values(Forest): msg = ".*does not accept missing values" with pytest.raises(ValueError, match=msg): forest.fit(X, y) + + +# TODO(1.11): remove test with the deprecation of friedman_mse criterion +@pytest.mark.parametrize("Forest", FOREST_REGRESSORS.values()) +def test_friedman_mse_deprecation(Forest): + with pytest.warns(FutureWarning, match="friedman_mse"): + _ = Forest(criterion="friedman_mse") From de7661dbbba546d22e4610b23bf5a38bcc7e4303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Fri, 16 Jan 2026 13:17:43 +0100 Subject: [PATCH 135/462] CI Fix the unit tests GHA on windows (#33081) --- .github/workflows/unit-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 65b0324be6c4b..f92d242b29cfc 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -237,6 +237,7 @@ jobs: - name: Set random seed for nightly/manual runs if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' run: echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 100))" >> $GITHUB_ENV + shell: bash - name: Run tests env: @@ -267,6 +268,7 @@ jobs: - name: Update tracking issue if: ${{ always() && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')}} + shell: bash run: | set -ex From ce1b377f3bb2580e7cc1e35ba7eed2131e3b8e8e Mon Sep 17 00:00:00 2001 From: antoinebaker Date: Fri, 16 Jan 2026 15:13:24 +0100 Subject: [PATCH 136/462] FIX Draw indices using sample_weight in Random Forests (#31529) Co-authored-by: Olivier Grisel Co-authored-by: Lucy Liu Co-authored-by: Arthur Lacote --- .../sklearn.ensemble/31529.fix.rst | 10 + sklearn/ensemble/_bagging.py | 58 +--- sklearn/ensemble/_bootstrap.py | 69 +++++ sklearn/ensemble/_forest.py | 269 ++++++++++-------- sklearn/ensemble/tests/test_bagging.py | 51 ---- sklearn/ensemble/tests/test_bootstrap.py | 81 ++++++ sklearn/ensemble/tests/test_forest.py | 122 ++++++-- sklearn/ensemble/tests/test_voting.py | 7 +- 8 files changed, 402 insertions(+), 265 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.ensemble/31529.fix.rst create mode 100644 sklearn/ensemble/_bootstrap.py create mode 100644 sklearn/ensemble/tests/test_bootstrap.py diff --git a/doc/whats_new/upcoming_changes/sklearn.ensemble/31529.fix.rst b/doc/whats_new/upcoming_changes/sklearn.ensemble/31529.fix.rst new file mode 100644 index 0000000000000..adac2129baf0a --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.ensemble/31529.fix.rst @@ -0,0 +1,10 @@ +- :class:`ensemble.RandomForestClassifier`, :class:`ensemble.RandomForestRegressor`, + :class:`ensemble.ExtraTreesClassifier` and :class:`ensemble.ExtraTreesRegressor` + now use `sample_weight` to draw the samples instead of forwarding them + multiplied by a uniformly sampled mask to the underlying estimators. + Furthermore, when `max_samples` is a float, it is now interpreted as a + fraction of `sample_weight.sum()` instead of `X.shape[0]`. As sampling is done + with replacement, a float `max_samples` greater than `1.0` is now allowed, as + well as an integer `max_samples` greater then `X.shape[0]`. The default + `max_samples=None` draws `X.shape[0]` samples, irrespective of `sample_weight`. + By :user:`Antoine Baker `. diff --git a/sklearn/ensemble/_bagging.py b/sklearn/ensemble/_bagging.py index a3d0b2bc931c7..e7d470fcf4fa3 100644 --- a/sklearn/ensemble/_bagging.py +++ b/sklearn/ensemble/_bagging.py @@ -14,6 +14,7 @@ from sklearn.base import ClassifierMixin, RegressorMixin, _fit_context from sklearn.ensemble._base import BaseEnsemble, _partition_estimators +from sklearn.ensemble._bootstrap import _get_n_samples_bootstrap from sklearn.metrics import accuracy_score, r2_score from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor from sklearn.utils import Bunch, _safe_indexing, check_random_state, column_or_1d @@ -46,63 +47,6 @@ MAX_INT = np.iinfo(np.int32).max -def _get_n_samples_bootstrap(n_samples, max_samples, sample_weight): - """ - Get the number of samples in a bootstrap sample. - - Parameters - ---------- - n_samples : int - Number of samples in the dataset. - - max_samples : None, int or float - The maximum number of samples to draw. - - - If None, then draw `n_samples` samples. - - If int, then draw `max_samples` samples. - - If float, then draw `max_samples * n_samples` unweighted samples or - `max_samples * sample_weight.sum()` weighted samples. - - sample_weight : array of shape (n_samples,) or None - Sample weights with frequency semantics when `max_samples` is explicitly - set to a float or integer value. When keeping the `max_samples=None` default - value, the equivalence between fitting with integer weighted data points or - integer repeated data points is no longer guaranteed because the effective - bootstrap size is no longer guaranteed to be equivalent. - - Returns - ------- - n_samples_bootstrap : int - The total number of samples to draw for the bootstrap sample. - """ - if max_samples is None: - return n_samples - elif isinstance(max_samples, Integral): - return max_samples - - if sample_weight is None: - weighted_n_samples = n_samples - weighted_n_samples_msg = f"the number of samples is {weighted_n_samples} " - else: - weighted_n_samples = sample_weight.sum() - weighted_n_samples_msg = ( - f"the total sum of sample weights is {weighted_n_samples} " - ) - - # max_samples Real fractional value relative to weighted_n_samples - n_samples_bootstrap = max(int(max_samples * weighted_n_samples), 1) - # Warn when number of bootstrap samples is suspiciously small - # This heuristic for "suspiciously small" might be adapted if found - # unsuitable in practice - if n_samples_bootstrap < max(10, n_samples ** (1 / 3)): - warn( - f"Using the fractional value {max_samples=} when {weighted_n_samples_msg}" - f"results in a low number ({n_samples_bootstrap}) of bootstrap samples. " - "We recommend passing `max_samples` as an integer instead." - ) - return n_samples_bootstrap - - def _generate_indices(random_state, bootstrap, n_population, n_samples): """Draw randomly sampled indices.""" # Draw sample indices diff --git a/sklearn/ensemble/_bootstrap.py b/sklearn/ensemble/_bootstrap.py new file mode 100644 index 0000000000000..53d3cd51a675a --- /dev/null +++ b/sklearn/ensemble/_bootstrap.py @@ -0,0 +1,69 @@ +"""Utility function to get the number of bootstrap samples.""" + +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +from numbers import Integral +from warnings import warn + + +def _get_n_samples_bootstrap(n_samples, max_samples, sample_weight): + """ + Get the number of samples in a bootstrap sample. + + Notes + ----- + The frequency semantics of :term:`sample_weight` is guaranteed when + `max_samples` is a float or integer, but not when `max_samples` is None. The + returned `n_samples_bootstrap` will be the same between a weighted dataset + with integer `sample_weights` and a dataset with as many rows repeated when + `max_samples` is a float or integer. They will differ when `max_samples` is + None (the weighted and repeated datasets do not have the same number of rows). + + Parameters + ---------- + n_samples : int + Number of samples in the dataset. + + max_samples : None, int or float + The maximum number of samples to draw. + + - If None, then draw `n_samples` samples. + - If int, then draw `max_samples` samples. + - If float, then draw `max_samples * n_samples` unweighted samples or + `max_samples * sample_weight.sum()` weighted samples. + + sample_weight : array of shape (n_samples,) or None + Sample weights. + + Returns + ------- + n_samples_bootstrap : int + The total number of samples to draw for the bootstrap sample. + """ + if max_samples is None: + return n_samples + elif isinstance(max_samples, Integral): + return max_samples + + if sample_weight is None: + weighted_n_samples = n_samples + weighted_n_samples_msg = f"the number of samples is {weighted_n_samples} " + else: + weighted_n_samples = sample_weight.sum() + weighted_n_samples_msg = ( + f"the total sum of sample weights is {weighted_n_samples} " + ) + + # max_samples Real fractional value relative to weighted_n_samples + n_samples_bootstrap = max(int(max_samples * weighted_n_samples), 1) + # Warn when number of bootstrap samples is suspiciously small. + # This heuristic for "suspiciously small" might be adapted if found + # unsuitable in practice. + if n_samples_bootstrap < max(10, n_samples ** (1 / 3)): + warn( + f"Using the fractional value {max_samples=} when {weighted_n_samples_msg}" + f"results in a low number ({n_samples_bootstrap}) of bootstrap samples. " + "We recommend passing `max_samples` as an integer instead." + ) + return n_samples_bootstrap diff --git a/sklearn/ensemble/_forest.py b/sklearn/ensemble/_forest.py index e1d666a8bf50f..6df5152e04273 100644 --- a/sklearn/ensemble/_forest.py +++ b/sklearn/ensemble/_forest.py @@ -37,8 +37,8 @@ class calls the ``fit`` method of each sub-estimator on random samples import threading from abc import ABCMeta, abstractmethod -from numbers import Integral, Real -from warnings import catch_warnings, simplefilter, warn +from numbers import Integral +from warnings import warn import numpy as np from scipy.sparse import hstack as sparse_hstack @@ -53,6 +53,7 @@ class calls the ``fit`` method of each sub-estimator on random samples is_classifier, ) from sklearn.ensemble._base import BaseEnsemble, _partition_estimators +from sklearn.ensemble._bootstrap import _get_n_samples_bootstrap from sklearn.exceptions import DataConversionWarning from sklearn.metrics import accuracy_score, r2_score from sklearn.preprocessing import OneHotEncoder @@ -64,7 +65,11 @@ class calls the ``fit`` method of each sub-estimator on random samples ExtraTreeRegressor, ) from sklearn.tree._tree import DOUBLE, DTYPE -from sklearn.utils import check_random_state, compute_sample_weight +from sklearn.utils import ( + check_random_state, + compute_class_weight, + compute_sample_weight, +) from sklearn.utils._param_validation import Interval, RealNotInt, StrOptions from sklearn.utils._tags import get_tags from sklearn.utils.multiclass import check_classification_targets, type_of_target @@ -88,56 +93,34 @@ class calls the ``fit`` method of each sub-estimator on random samples MAX_INT = np.iinfo(np.int32).max -def _get_n_samples_bootstrap(n_samples, max_samples): - """ - Get the number of samples in a bootstrap sample. - - Parameters - ---------- - n_samples : int - Number of samples in the dataset. - max_samples : int or float - The maximum number of samples to draw from the total available: - - if float, this indicates a fraction of the total and should be - the interval `(0.0, 1.0]`; - - if int, this indicates the exact number of samples; - - if None, this indicates the total number of samples. - - Returns - ------- - n_samples_bootstrap : int - The total number of samples to draw for the bootstrap sample. - """ - if max_samples is None: - return n_samples - - if isinstance(max_samples, Integral): - if max_samples > n_samples: - msg = "`max_samples` must be <= n_samples={} but got value {}" - raise ValueError(msg.format(n_samples, max_samples)) - return max_samples - - if isinstance(max_samples, Real): - return max(round(n_samples * max_samples), 1) - - -def _generate_sample_indices(random_state, n_samples, n_samples_bootstrap): +def _generate_sample_indices( + random_state, n_samples, n_samples_bootstrap, sample_weight +): """ Private function used to _parallel_build_trees function.""" random_instance = check_random_state(random_state) - sample_indices = random_instance.randint( - 0, n_samples, n_samples_bootstrap, dtype=np.int32 - ) - + if sample_weight is None: + sample_indices = random_instance.randint(0, n_samples, n_samples_bootstrap) + else: + normalized_sample_weight = sample_weight / np.sum(sample_weight) + sample_indices = random_instance.choice( + n_samples, + n_samples_bootstrap, + replace=True, + p=normalized_sample_weight, + ) + sample_indices = sample_indices.astype(np.int32) return sample_indices -def _generate_unsampled_indices(random_state, n_samples, n_samples_bootstrap): +def _generate_unsampled_indices( + random_state, n_samples, n_samples_bootstrap, sample_weight +): """ Private function used to forest._set_oob_score function.""" sample_indices = _generate_sample_indices( - random_state, n_samples, n_samples_bootstrap + random_state, n_samples, n_samples_bootstrap, sample_weight ) sample_counts = np.bincount(sample_indices, minlength=n_samples) unsampled_mask = sample_counts == 0 @@ -167,28 +150,21 @@ def _parallel_build_trees( if bootstrap: n_samples = X.shape[0] - if sample_weight is None: - curr_sample_weight = np.ones((n_samples,), dtype=np.float64) - else: - curr_sample_weight = sample_weight.copy() - indices = _generate_sample_indices( - tree.random_state, n_samples, n_samples_bootstrap + tree.random_state, n_samples, n_samples_bootstrap, sample_weight ) - sample_counts = np.bincount(indices, minlength=n_samples) - curr_sample_weight *= sample_counts - - if class_weight == "subsample": - with catch_warnings(): - simplefilter("ignore", DeprecationWarning) - curr_sample_weight *= compute_sample_weight("auto", y, indices=indices) - elif class_weight == "balanced_subsample": - curr_sample_weight *= compute_sample_weight("balanced", y, indices=indices) + # Simulate row-wise sampling by passing counts as sample_weight in trees. + sample_weight_tree = np.bincount(indices, minlength=n_samples) + if class_weight == "balanced_subsample": + expanded_class_weight = compute_sample_weight( + "balanced", y, indices=indices + ) + sample_weight_tree = sample_weight_tree * expanded_class_weight tree._fit( X, y, - sample_weight=curr_sample_weight, + sample_weight=sample_weight_tree, check_input=False, missing_values_in_feature_mask=missing_values_in_feature_mask, ) @@ -222,7 +198,7 @@ class BaseForest(MultiOutputMixin, BaseEnsemble, metaclass=ABCMeta): "warm_start": ["boolean"], "max_samples": [ None, - Interval(RealNotInt, 0.0, 1.0, closed="right"), + Interval(RealNotInt, 0.0, None, closed="neither"), Interval(Integral, 1, None, closed="left"), ], } @@ -415,16 +391,23 @@ def fit(self, X, y, sample_weight=None): self._n_samples, self.n_outputs_ = y.shape - y, expanded_class_weight = self._validate_y_class_weight(y) + y, expanded_class_weight = self._validate_y_class_weight(y, sample_weight) if getattr(y, "dtype", None) != DOUBLE or not y.flags.contiguous: y = np.ascontiguousarray(y, dtype=DOUBLE) - if expanded_class_weight is not None: - if sample_weight is not None: - sample_weight = sample_weight * expanded_class_weight - else: - sample_weight = expanded_class_weight + # Combined _sample_weight = sample_weight * expanded_class_weight + # (when provided) used in _parallel_build_trees to draw indices + # (bootstrap=True) or passed to the trees (bootstrap=False). + if sample_weight is None: + _sample_weight = expanded_class_weight + elif expanded_class_weight is None: + _sample_weight = sample_weight + else: + _sample_weight = sample_weight * expanded_class_weight + + # Storing _sample_weight (needed by _get_estimators_indices). + self._sample_weight = _sample_weight if not self.bootstrap and self.max_samples is not None: raise ValueError( @@ -434,7 +417,7 @@ def fit(self, X, y, sample_weight=None): ) elif self.bootstrap: n_samples_bootstrap = _get_n_samples_bootstrap( - n_samples=X.shape[0], max_samples=self.max_samples + X.shape[0], self.max_samples, _sample_weight ) else: n_samples_bootstrap = None @@ -493,7 +476,7 @@ def fit(self, X, y, sample_weight=None): self.bootstrap, X, y, - sample_weight, + _sample_weight, i, len(trees), verbose=self.verbose, @@ -590,16 +573,12 @@ def _compute_oob_predictions(self, X, y): oob_pred = np.zeros(shape=oob_pred_shape, dtype=np.float64) n_oob_pred = np.zeros((n_samples, n_outputs), dtype=np.int64) - - n_samples_bootstrap = _get_n_samples_bootstrap( - n_samples, - self.max_samples, - ) for estimator in self.estimators_: unsampled_indices = _generate_unsampled_indices( estimator.random_state, n_samples, - n_samples_bootstrap, + self._n_samples_bootstrap, + self._sample_weight, ) y_pred = self._get_oob_predictions(estimator, X[unsampled_indices, :]) @@ -621,7 +600,7 @@ def _compute_oob_predictions(self, X, y): return oob_pred - def _validate_y_class_weight(self, y): + def _validate_y_class_weight(self, y, sample_weight): # Default implementation return y, None @@ -694,7 +673,10 @@ def _get_estimators_indices(self): # Operations accessing random_state must be performed identically # to those in `_parallel_build_trees()` yield _generate_sample_indices( - seed, self._n_samples, self._n_samples_bootstrap + seed, + self._n_samples, + self._n_samples_bootstrap, + self._sample_weight, ) @property @@ -826,15 +808,10 @@ def _set_oob_score_and_attributes(self, X, y, scoring_function=None): y, np.argmax(self.oob_decision_function_, axis=1) ) - def _validate_y_class_weight(self, y): + def _validate_y_class_weight(self, y, sample_weight): check_classification_targets(y) - y = np.copy(y) - expanded_class_weight = None - - if self.class_weight is not None: - y_original = np.copy(y) - + y_original = np.copy(y) self.classes_ = [] self.n_classes_ = [] @@ -847,36 +824,60 @@ def _validate_y_class_weight(self, y): self.n_classes_.append(classes_k.shape[0]) y = y_store_unique_indices - if self.class_weight is not None: - valid_presets = ("balanced", "balanced_subsample") - if isinstance(self.class_weight, str): - if self.class_weight not in valid_presets: - raise ValueError( - "Valid presets for class_weight include " - '"balanced" and "balanced_subsample".' - 'Given "%s".' % self.class_weight - ) - if self.warm_start: - warn( - 'class_weight presets "balanced" or ' - '"balanced_subsample" are ' - "not recommended for warm_start if the fitted data " - "differs from the full dataset. In order to use " - '"balanced" weights, use compute_class_weight ' - '("balanced", classes, y). In place of y you can use ' - "a large enough sample of the full training set " - "target to properly estimate the class frequency " - "distributions. Pass the resulting weights as the " - "class_weight parameter." - ) - - if self.class_weight != "balanced_subsample" or not self.bootstrap: - if self.class_weight == "balanced_subsample": - class_weight = "balanced" - else: - class_weight = self.class_weight - expanded_class_weight = compute_sample_weight(class_weight, y_original) + if self.class_weight is None: + return y, None + + # User defined class_weight (dict or list) + if isinstance(self.class_weight, (dict, list)): + expanded_class_weight = compute_sample_weight(self.class_weight, y_original) + return y, expanded_class_weight + + # Checking class_weight options + valid_presets = ("balanced", "balanced_subsample") + if self.class_weight not in valid_presets: + raise ValueError( + "Valid presets for class_weight include " + '"balanced" and "balanced_subsample".' + 'Given "%s".' % self.class_weight + ) + if self.warm_start: + warn( + 'class_weight presets "balanced" or ' + '"balanced_subsample" are ' + "not recommended for warm_start if the fitted data " + "differs from the full dataset. In order to use " + '"balanced" weights, use compute_class_weight ' + '("balanced", classes, y). In place of y you can use ' + "a large enough sample of the full training set " + "target to properly estimate the class frequency " + "distributions. Pass the resulting weights as the " + "class_weight parameter." + ) + + # "balanced_subsample" option with subsampling (bootstrap=True) + if self.class_weight == "balanced_subsample" and self.bootstrap: + # class_weight will be computed on the bootstrap sample + return y, None + # Computing class_weight (dict or list) for the "balanced" option. + # The "balanced_subsample" option without subsampling (bootstrap=False) + # is equivalent to the "balanced" option. + class_weight = [] + for k in range(self.n_outputs_): + class_weight_k_vect = compute_class_weight( + "balanced", + classes=self.classes_[k], + y=y_original[:, k], + sample_weight=sample_weight, + ) + class_weight_k = { + key: val for (key, val) in zip(self.classes_[k], class_weight_k_vect) + } + class_weight.append(class_weight_k) + if self.n_outputs_ == 1: + class_weight = class_weight[0] + + expanded_class_weight = compute_sample_weight(class_weight, y_original) return y, expanded_class_weight def predict(self, X): @@ -1364,13 +1365,18 @@ class RandomForestClassifier(ForestClassifier): If bootstrap is True, the number of samples to draw from X to train each base estimator. - - If None (default), then draw `X.shape[0]` samples. + - If None (default), then draw `X.shape[0]` samples irrespective of + `sample_weight`. - If int, then draw `max_samples` samples. - - If float, then draw `max(round(n_samples * max_samples), 1)` samples. Thus, - `max_samples` should be in the interval `(0.0, 1.0]`. + - If float, then draw `max_samples * X.shape[0]` unweighted samples + or `max_samples * sample_weight.sum()` weighted samples. .. versionadded:: 0.22 + .. versionchanged:: 1.9 + Float `max_samples` is relative to `sample_weight.sum()` instead of + `X.shape[0]` for weighted samples. + monotonic_cst : array-like of int of shape (n_features), default=None Indicates the monotonicity constraint to enforce on each feature. - 1: monotonic increase @@ -1752,13 +1758,18 @@ class RandomForestRegressor(ForestRegressor): If bootstrap is True, the number of samples to draw from X to train each base estimator. - - If None (default), then draw `X.shape[0]` samples. + - If None (default), then draw `X.shape[0]` samples irrespective of + `sample_weight`. - If int, then draw `max_samples` samples. - - If float, then draw `max(round(n_samples * max_samples), 1)` samples. Thus, - `max_samples` should be in the interval `(0.0, 1.0]`. + - If float, then draw `max_samples * X.shape[0]` unweighted samples + or `max_samples * sample_weight.sum()` weighted samples. .. versionadded:: 0.22 + .. versionchanged:: 1.9 + Float `max_samples` is relative to `sample_weight.sum()` instead of + `X.shape[0]` for weighted samples. + monotonic_cst : array-like of int of shape (n_features), default=None Indicates the monotonicity constraint to enforce on each feature. - 1: monotonically increasing @@ -2141,13 +2152,18 @@ class ExtraTreesClassifier(ForestClassifier): If bootstrap is True, the number of samples to draw from X to train each base estimator. - - If None (default), then draw `X.shape[0]` samples. + - If None (default), then draw `X.shape[0]` samples irrespective of + `sample_weight`. - If int, then draw `max_samples` samples. - - If float, then draw `max_samples * X.shape[0]` samples. Thus, - `max_samples` should be in the interval `(0.0, 1.0]`. + - If float, then draw `max_samples * X.shape[0]` unweighted samples + or `max_samples * sample_weight.sum()` weighted samples. .. versionadded:: 0.22 + .. versionchanged:: 1.9 + Float `max_samples` is relative to `sample_weight.sum()` instead of + `X.shape[0]` for weighted samples. + monotonic_cst : array-like of int of shape (n_features), default=None Indicates the monotonicity constraint to enforce on each feature. - 1: monotonically increasing @@ -2512,13 +2528,18 @@ class ExtraTreesRegressor(ForestRegressor): If bootstrap is True, the number of samples to draw from X to train each base estimator. - - If None (default), then draw `X.shape[0]` samples. + - If None (default), then draw `X.shape[0]` samples irrespective of + `sample_weight`. - If int, then draw `max_samples` samples. - - If float, then draw `max_samples * X.shape[0]` samples. Thus, - `max_samples` should be in the interval `(0.0, 1.0]`. + - If float, then draw `max_samples * X.shape[0]` unweighted samples + or `max_samples * sample_weight.sum()` weighted samples. .. versionadded:: 0.22 + .. versionchanged:: 1.9 + Float `max_samples` is relative to `sample_weight.sum()` instead of + `X.shape[0]` for weighted samples. + monotonic_cst : array-like of int of shape (n_features), default=None Indicates the monotonicity constraint to enforce on each feature. - 1: monotonically increasing diff --git a/sklearn/ensemble/tests/test_bagging.py b/sklearn/ensemble/tests/test_bagging.py index 0b73499467da6..05789ff63d0e8 100644 --- a/sklearn/ensemble/tests/test_bagging.py +++ b/sklearn/ensemble/tests/test_bagging.py @@ -6,7 +6,6 @@ # SPDX-License-Identifier: BSD-3-Clause import re -import warnings from itertools import cycle, product import joblib @@ -27,7 +26,6 @@ RandomForestClassifier, RandomForestRegressor, ) -from sklearn.ensemble._bagging import _get_n_samples_bootstrap from sklearn.feature_selection import SelectKBest from sklearn.linear_model import LogisticRegression, Perceptron from sklearn.model_selection import GridSearchCV, ParameterGrid, train_test_split @@ -816,55 +814,6 @@ def test_draw_indices_using_sample_weight( assert_allclose(estimator.y_, y[samples]) -def test_get_n_samples_bootstrap(): - n_samples, max_samples, sample_weight = 10, None, "not_used" - assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == n_samples - - n_samples, max_samples, sample_weight = 10, 5, "not_used" - assert ( - _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == max_samples - ) - - n_samples, max_samples, sample_weight = 10, 1e-5, None - assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == 1 - - n_samples, max_samples, sample_weight = 10, 0.66, None - warning_msg = ".+the number of samples.+low number.+max_samples.+as an integer" - with pytest.warns(UserWarning, match=warning_msg): - assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == int( - max_samples * n_samples - ) - - n_samples, max_samples, sample_weight = 10, 1e-5, None - with pytest.warns(UserWarning, match=warning_msg): - assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == 1 - - warning_msg_with_weights = ( - ".+the total sum of sample weights.+low number.+max_samples.+as an integer" - ) - rng = np.random.default_rng(0) - n_samples, max_samples, sample_weight = 1_000_000, 1e-5, rng.uniform(size=1_000_000) - with pytest.warns(UserWarning, match=warning_msg_with_weights): - assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == int( - max_samples * sample_weight.sum() - ) - - sample_weight = np.ones(3) - with warnings.catch_warnings(): - warnings.simplefilter("error") - - n_samples, max_samples, sample_weight = 100, 30, None - assert ( - _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) - == max_samples - ) - - n_samples, max_samples, sample_weight = 100, 0.5, rng.uniform(size=100) - assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == int( - max_samples * sample_weight.sum() - ) - - def test_oob_score_removed_on_warm_start(): X, y = make_hastie_10_2(n_samples=100, random_state=1) diff --git a/sklearn/ensemble/tests/test_bootstrap.py b/sklearn/ensemble/tests/test_bootstrap.py new file mode 100644 index 0000000000000..31d2c534a88d2 --- /dev/null +++ b/sklearn/ensemble/tests/test_bootstrap.py @@ -0,0 +1,81 @@ +""" +Testing for the utility function _get_n_samples_bootstrap +""" + +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +import warnings + +import numpy as np +import pytest + +from sklearn.ensemble._bootstrap import _get_n_samples_bootstrap + + +def test_get_n_samples_bootstrap(): + # max_samples=None returns n_samples + n_samples, max_samples, sample_weight = 10, None, "not_used" + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == n_samples + + # max_samples:int returns max_samples + n_samples, max_samples, sample_weight = 10, 5, "not_used" + assert ( + _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == max_samples + ) + + # cases where n_samples_bootstrap is small and should raise a warning + warning_msg = ".+the number of samples.+low number.+max_samples.+as an integer" + n_samples, max_samples, sample_weight = 10, 0.66, None + with pytest.warns(UserWarning, match=warning_msg): + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == int( + max_samples * n_samples + ) + + n_samples, max_samples, sample_weight = 10, 0.01, None + with pytest.warns(UserWarning, match=warning_msg): + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == 1 + + warning_msg_with_weights = ( + ".+the total sum of sample weights.+low number.+max_samples.+as an integer" + ) + rng = np.random.default_rng(0) + n_samples, max_samples, sample_weight = 10, 0.8, rng.uniform(size=10) + with pytest.warns(UserWarning, match=warning_msg_with_weights): + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == int( + max_samples * sample_weight.sum() + ) + + # cases where n_samples_bootstrap is big enough and shouldn't raise a warning + with warnings.catch_warnings(): + warnings.simplefilter("error") + n_samples, max_samples, sample_weight = 100, 30, None + assert ( + _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) + == max_samples + ) + n_samples, max_samples, sample_weight = 100, 0.5, rng.uniform(size=100) + assert _get_n_samples_bootstrap(n_samples, max_samples, sample_weight) == int( + max_samples * sample_weight.sum() + ) + + +@pytest.mark.parametrize("max_samples", [None, 1, 5, 1000, 0.1, 1.0, 1.5]) +def test_n_samples_bootstrap_repeated_weighted_equivalence(max_samples): + # weighted dataset + n_samples = 100 + rng = np.random.RandomState(0) + sample_weight = rng.randint(2, 5, n_samples) + # repeated dataset + n_samples_repeated = sample_weight.sum() + + n_bootstrap_weighted = _get_n_samples_bootstrap( + n_samples, max_samples, sample_weight + ) + n_bootstrap_repeated = _get_n_samples_bootstrap( + n_samples_repeated, max_samples, None + ) + if max_samples is None: + assert n_bootstrap_weighted != n_bootstrap_repeated + else: + assert n_bootstrap_weighted == n_bootstrap_repeated diff --git a/sklearn/ensemble/tests/test_forest.py b/sklearn/ensemble/tests/test_forest.py index b04c46c845d27..7d6283300a256 100644 --- a/sklearn/ensemble/tests/test_forest.py +++ b/sklearn/ensemble/tests/test_forest.py @@ -31,10 +31,8 @@ RandomForestRegressor, RandomTreesEmbedding, ) -from sklearn.ensemble._forest import ( - _generate_unsampled_indices, - _get_n_samples_bootstrap, -) +from sklearn.ensemble._bootstrap import _get_n_samples_bootstrap +from sklearn.ensemble._forest import _generate_unsampled_indices from sklearn.exceptions import NotFittedError from sklearn.metrics import ( explained_variance_score, @@ -645,7 +643,7 @@ def test_forest_multioutput_integral_regression_target(ForestRegressor): ) estimator.fit(X, y) - n_samples_bootstrap = _get_n_samples_bootstrap(len(X), estimator.max_samples) + n_samples_bootstrap = _get_n_samples_bootstrap(len(X), estimator.max_samples, None) n_samples_test = X.shape[0] // 4 oob_pred = np.zeros([n_samples_test, 2]) for sample_idx, sample in enumerate(X[:n_samples_test]): @@ -653,7 +651,7 @@ def test_forest_multioutput_integral_regression_target(ForestRegressor): oob_pred_sample = np.zeros(2) for tree in estimator.estimators_: oob_unsampled_indices = _generate_unsampled_indices( - tree.random_state, len(X), n_samples_bootstrap + tree.random_state, len(X), n_samples_bootstrap, None ) if sample_idx in oob_unsampled_indices: n_samples_oob += 1 @@ -1163,50 +1161,104 @@ def test_1d_input(name): @pytest.mark.parametrize("name", FOREST_CLASSIFIERS) -def test_class_weights(name): - # Check class_weights resemble sample_weights behavior. +@pytest.mark.parametrize("n_classes", [2, 3, 4]) +def test_validate_y_class_weight(name, n_classes, global_random_seed): ForestClassifier = FOREST_CLASSIFIERS[name] + clf = ForestClassifier(random_state=0) + # toy dataset with n_classes + y = np.repeat(np.arange(n_classes), 3) + rng = np.random.RandomState(global_random_seed) + sw = rng.randint(1, 5, size=len(y)) + weighted_frequency = np.bincount(y, weights=sw) / sw.sum() + balanced_class_weight = 1 / (n_classes * weighted_frequency) + # validation in fit reshapes y as (n_samples, 1) + y_reshaped = np.reshape(y, (-1, 1)) + # Manually set these attributes, as we are not calling `fit` + clf._n_samples, clf.n_outputs_ = y_reshaped.shape + + # checking dict class_weight + class_weight = rng.randint(1, 7, size=n_classes) + class_weight_dict = dict(enumerate(class_weight)) + clf.set_params(class_weight=class_weight_dict) + _, expanded_class_weight = clf._validate_y_class_weight(y_reshaped, sw) + assert_allclose(expanded_class_weight, class_weight[y]) + + # checking class_weight="balanced" + clf.set_params(class_weight="balanced") + _, expanded_class_weight = clf._validate_y_class_weight(y_reshaped, sw) + assert_allclose(expanded_class_weight, balanced_class_weight[y]) + + # checking class_weight="balanced_subsample" with bootstrap=False + # (should be equivalent to "balanced") + clf.set_params(class_weight="balanced_subsample", bootstrap=False) + _, expanded_class_weight = clf._validate_y_class_weight(y_reshaped, sw) + assert_allclose(expanded_class_weight, balanced_class_weight[y]) + + # checking class_weight="balanced_subsample" with bootstrap=True + # (should be None) + clf.set_params(class_weight="balanced_subsample", bootstrap=True) + _, expanded_class_weight = clf._validate_y_class_weight(y_reshaped, sw) + assert expanded_class_weight is None + - # Iris is balanced, so no effect expected for using 'balanced' weights - clf1 = ForestClassifier(random_state=0) - clf1.fit(iris.data, iris.target) - clf2 = ForestClassifier(class_weight="balanced", random_state=0) +@pytest.mark.parametrize("name", FOREST_CLASSIFIERS) +@pytest.mark.parametrize("bootstrap", [True, False]) +def test_class_weights_forest(name, bootstrap, global_random_seed): + # Check class_weights resemble sample_weights behavior. + ForestClassifier = FOREST_CLASSIFIERS[name] + clf = ForestClassifier(random_state=global_random_seed, bootstrap=bootstrap) + + # Iris is balanced, so no effect expected for using 'balanced' weights. + # Using the class_weight="balanced" option is then equivalent to fit with + # all ones sample_weight. However we cannot guarantee the same fit for + # sample_weight = None vs all ones, because the indices are drawn by + # different rng functions (choice vs randint). Thus we explicitly pass + # the sample_weight as all ones in clf1 fit. + clf1 = clone(clf) + clf1.fit(iris.data, iris.target, sample_weight=np.ones_like(iris.target)) + clf2 = clone(clf).set_params(class_weight="balanced") clf2.fit(iris.data, iris.target) + assert_almost_equal(clf2._sample_weight, 1) assert_almost_equal(clf1.feature_importances_, clf2.feature_importances_) # Make a multi-output problem with three copies of Iris iris_multi = np.vstack((iris.target, iris.target, iris.target)).T # Create user-defined weights that should balance over the outputs - clf3 = ForestClassifier( + clf3 = clone(clf).set_params( class_weight=[ {0: 2.0, 1: 2.0, 2: 1.0}, {0: 2.0, 1: 1.0, 2: 2.0}, {0: 1.0, 1: 2.0, 2: 2.0}, - ], - random_state=0, + ] ) clf3.fit(iris.data, iris_multi) - assert_almost_equal(clf2.feature_importances_, clf3.feature_importances_) + # for multi-output, weights are multiplied + assert_almost_equal(clf3._sample_weight, 2 * 2 * 1) + # FIXME why is this test brittle ? + assert_allclose(clf2.feature_importances_, clf3.feature_importances_, atol=0.002) # Check against multi-output "balanced" which should also have no effect - clf4 = ForestClassifier(class_weight="balanced", random_state=0) + clf4 = clone(clf).set_params(class_weight="balanced") clf4.fit(iris.data, iris_multi) + assert_almost_equal(clf4._sample_weight, 1) assert_almost_equal(clf3.feature_importances_, clf4.feature_importances_) # Inflate importance of class 1, check against user-defined weights sample_weight = np.ones(iris.target.shape) sample_weight[iris.target == 1] *= 100 class_weight = {0: 1.0, 1: 100.0, 2: 1.0} - clf1 = ForestClassifier(random_state=0) + clf1 = clone(clf) clf1.fit(iris.data, iris.target, sample_weight) - clf2 = ForestClassifier(class_weight=class_weight, random_state=0) + clf2 = clone(clf).set_params(class_weight=class_weight) clf2.fit(iris.data, iris.target) + assert_almost_equal(clf1._sample_weight, clf2._sample_weight) assert_almost_equal(clf1.feature_importances_, clf2.feature_importances_) # Check that sample_weight and class_weight are multiplicative - clf1 = ForestClassifier(random_state=0) + clf1 = clone(clf) clf1.fit(iris.data, iris.target, sample_weight**2) - clf2 = ForestClassifier(class_weight=class_weight, random_state=0) + clf2 = clone(clf).set_params(class_weight=class_weight) clf2.fit(iris.data, iris.target, sample_weight) + assert_almost_equal(clf1._sample_weight, clf2._sample_weight) assert_almost_equal(clf1.feature_importances_, clf2.feature_importances_) @@ -1531,6 +1583,25 @@ def test_forest_degenerate_feature_importances(): assert_array_equal(gbr.feature_importances_, np.zeros(10, dtype=np.float64)) +@pytest.mark.parametrize("name", FOREST_CLASSIFIERS_REGRESSORS) +def test_max_samples_geq_one(name): + # Check that `max_samples >= 1.0` and `max_samples >= n_samples ` + # is allowed, issue #28507 + X, y = hastie_X, hastie_y + max_samples_float = 1.5 + max_sample_int = int(max_samples_float * X.shape[0]) + est1 = FOREST_CLASSIFIERS_REGRESSORS[name]( + bootstrap=True, max_samples=max_samples_float, random_state=11 + ) + est1.fit(X, y) + est2 = FOREST_CLASSIFIERS_REGRESSORS[name]( + bootstrap=True, max_samples=max_sample_int, random_state=11 + ) + est2.fit(X, y) + assert est1._n_samples_bootstrap == est2._n_samples_bootstrap + assert_allclose(est1.score(X, y), est2.score(X, y)) + + @pytest.mark.parametrize("name", FOREST_CLASSIFIERS_REGRESSORS) def test_max_samples_bootstrap(name): # Check invalid `max_samples` values @@ -1544,15 +1615,6 @@ def test_max_samples_bootstrap(name): est.fit(X, y) -@pytest.mark.parametrize("name", FOREST_CLASSIFIERS_REGRESSORS) -def test_large_max_samples_exception(name): - # Check invalid `max_samples` - est = FOREST_CLASSIFIERS_REGRESSORS[name](bootstrap=True, max_samples=int(1e9)) - match = "`max_samples` must be <= n_samples=6 but got value 1000000000" - with pytest.raises(ValueError, match=match): - est.fit(X, y) - - @pytest.mark.parametrize("name", FOREST_REGRESSORS) def test_max_samples_boundary_regressors(name): X_train, X_test, y_train, y_test = train_test_split( diff --git a/sklearn/ensemble/tests/test_voting.py b/sklearn/ensemble/tests/test_voting.py index 7ea3627ac2eca..47523705ccbd2 100644 --- a/sklearn/ensemble/tests/test_voting.py +++ b/sklearn/ensemble/tests/test_voting.py @@ -11,6 +11,7 @@ from sklearn.datasets import make_multilabel_classification from sklearn.dummy import DummyRegressor from sklearn.ensemble import ( + GradientBoostingClassifier, RandomForestClassifier, RandomForestRegressor, VotingClassifier, @@ -325,13 +326,13 @@ def test_parallel_fit(global_random_seed): def test_sample_weight(global_random_seed): """Tests sample_weight parameter of VotingClassifier""" clf1 = LogisticRegression(random_state=global_random_seed) - clf2 = RandomForestClassifier(n_estimators=10, random_state=global_random_seed) + clf2 = GradientBoostingClassifier(n_estimators=10, random_state=global_random_seed) clf3 = CalibratedClassifierCV(SVC(random_state=global_random_seed), ensemble=False) eclf1 = VotingClassifier( - estimators=[("lr", clf1), ("rf", clf2), ("svc", clf3)], voting="soft" + estimators=[("lr", clf1), ("gbdt", clf2), ("svc", clf3)], voting="soft" ).fit(X_scaled, y, sample_weight=np.ones((len(y),))) eclf2 = VotingClassifier( - estimators=[("lr", clf1), ("rf", clf2), ("svc", clf3)], voting="soft" + estimators=[("lr", clf1), ("gbdt", clf2), ("svc", clf3)], voting="soft" ).fit(X_scaled, y) assert_array_equal(eclf1.predict(X_scaled), eclf2.predict(X_scaled)) assert_array_almost_equal( From 830d84190cefbd9dd2a108786616d008dae3b910 Mon Sep 17 00:00:00 2001 From: Bodhi Silberling Date: Sun, 18 Jan 2026 15:19:19 -0800 Subject: [PATCH 137/462] Fix inconsistent string formatting in check_is_fitted function (#33104) --- sklearn/utils/validation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index 163542a2409ed..531ff66995b87 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -1686,7 +1686,7 @@ def check_is_fitted(estimator, attributes=None, *, msg=None, all_or_any=all): >>> check_is_fitted(lr) """ if isclass(estimator): - raise TypeError("{} is a class, not an instance.".format(estimator)) + raise TypeError(f"{estimator} is a class, not an instance.") if msg is None: msg = ( "This %(name)s instance is not fitted yet. Call 'fit' with " @@ -1694,7 +1694,7 @@ def check_is_fitted(estimator, attributes=None, *, msg=None, all_or_any=all): ) if not hasattr(estimator, "fit"): - raise TypeError("%s is not an estimator instance." % (estimator)) + raise TypeError(f"{estimator} is not an estimator instance.") tags = get_tags(estimator) From 9cc8266aaf067885f7553c61dc525d6116579635 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 19 Jan 2026 09:21:51 +0100 Subject: [PATCH 138/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33050) Co-authored-by: Lock file bot --- ...pylatest_free_threaded_linux-64_conda.lock | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index da6285265539f..e7203672de4fb 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -12,30 +12,28 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda# https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda#518e9bbbc3e3486d6a4519192ba690f8 +https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 -https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-he1279bd_0_cp314t.conda#08a2a24f4e6907bea0ebfe22eecae6be -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.2-py314hd8ed1ab_0.conda#d0ce45508dd9dffaec3795252897bd7a https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.conda#cc2fcbfdf0628b5ad05b319866187bbc @@ -49,14 +47,14 @@ https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py314hd4f4903_0.conda#d0c7122fcbd0bffc0d76d7c7d476e537 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py314hd4f4903_0.conda#66c5cfbc84524e3eb553503b80874087 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.2-h92d6c8b_0.conda#f4db4d53331f31ec695670d5b3cedabb -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py314h529d2a9_2.conda#eda5b8c13cf149dc41ca6796d127fcab -https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.1-pyhd8ed1ab_0.conda#4e98ccdfa64d30826a7977c7a4fa17e8 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py314h529d2a9_0.conda#5c2d81fe28dd2bdcf502a070c58abc40 +https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.2-pyhd8ed1ab_0.conda#288250b7e539cddf52f39616deae278d From da6dcb1ea9945520e452dcb93fc2cf15c5761ab4 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 19 Jan 2026 10:16:35 +0100 Subject: [PATCH 139/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33105) Co-authored-by: Lock file bot --- build_tools/azure/debian_32bit_lock.txt | 4 +-- ...latest_conda_forge_mkl_linux-64_conda.lock | 26 +++++++++---------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 11 ++++---- .../pylatest_conda_forge_osx-arm64_conda.lock | 24 +++++++++-------- ...st_pip_openblas_pandas_linux-64_conda.lock | 16 +++++------- ...nblas_min_dependencies_linux-64_conda.lock | 13 +++++----- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 13 +++++----- ...min_conda_forge_openblas_win-64_conda.lock | 6 ++--- build_tools/azure/ubuntu_atlas_lock.txt | 4 +-- build_tools/circle/doc_linux-64_conda.lock | 24 ++++++++--------- .../doc_min_dependencies_linux-64_conda.lock | 18 ++++++------- ...n_conda_forge_arm_linux-aarch64_conda.lock | 14 +++++----- 12 files changed, 86 insertions(+), 87 deletions(-) diff --git a/build_tools/azure/debian_32bit_lock.txt b/build_tools/azure/debian_32bit_lock.txt index 650347404e90c..f8b8381a20a94 100644 --- a/build_tools/azure/debian_32bit_lock.txt +++ b/build_tools/azure/debian_32bit_lock.txt @@ -14,9 +14,9 @@ iniconfig==2.3.0 # via pytest joblib==1.5.3 # via -r build_tools/azure/debian_32bit_requirements.txt -meson==1.10.0 +meson==1.10.1 # via meson-python -meson-python==0.18.0 +meson-python==0.19.0 # via -r build_tools/azure/debian_32bit_requirements.txt ninja==1.13.0 # via -r build_tools/azure/debian_32bit_requirements.txt diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index b9faef0b2bb70..d7198fd604eb7 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -21,7 +21,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.2-hb03c661_0.conda#ada39f5726bc5481e9dce293709dfabc +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 @@ -34,12 +34,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.con https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f -https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.2-hfe17d71_0.conda#5641725dfad698909ec71dac80d16736 +https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -50,6 +50,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002. https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f +https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.13-h2c9d079_1.conda#3c3d02681058c3d206b562b2e3bc337f https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h8b1a151_9.conda#f7ec84186dfe7a9e3a9f9e5a4d023e75 https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h8b1a151_4.conda#c7e3e08b7b1b285524ab9d74162ce40b @@ -67,7 +68,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 +https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae @@ -89,6 +91,7 @@ https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#4 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-hdaf4b65_5.conda#132e8f8f40f0ffc0bbde12bb4e8dd1a1 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 @@ -96,7 +99,6 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_4.conda#07479fc04ba3ddd5d9f760ef1635cfa7 @@ -119,7 +121,6 @@ https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.12.0-h36edbcc_0.conda#adc6bd7e0e0ccd769227344712e80b28 @@ -137,7 +138,6 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-hc63082f_11.co https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda#1d4e0d37da5f3c22ecd44033f673feba https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py313h18e8e13_0.conda#d9e90792551a527200637e23a915dd79 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda#6c4d3597cf43f3439a51b2b13e29a4ba -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 @@ -225,7 +225,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_1.conda#e933f92cedca212eb2916f24823cf90b https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_1.conda#e00afd65b88a3258212661b32c1469cb https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.57.0-pyhcf101f3_0.conda#a61bfabd06f24469454086deb7f8166e https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 @@ -236,14 +236,14 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.13.0-hf38f1be_1.conda#f10b9303c7239fbce3580a60a92bcf97 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.0-py310hffdcd12_0.conda#5b2fbd248429505337095d2a84956655 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.1-py310hffdcd12_0.conda#732a536c6ce768f096f5340121e10cc5 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-hb6ed5f4_6_cpu.conda#fbaa3742ccca0f7096216c0832137b72 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad -https://conda.anaconda.org/conda-forge/noarch/polars-1.37.0-pyh6a1acc5_0.conda#45be32f1fff99fd27aae7b6eaf388a1f +https://conda.anaconda.org/conda-forge/noarch/polars-1.37.1-pyh6a1acc5_0.conda#1894d4373da653406c91e20ef89f05c8 https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-h6f76662_3.conda#f134a496ef494f2b6c5a26e5d739acc6 https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-22.0.0-h8c2c5c3_6_cpu.conda#d2cd924b5f451a7c258001cb1c14155d @@ -254,7 +254,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py313h85046ba_0.c https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-22.0.0-h635bf11_6_cpu.conda#5a8f878ca313083960ab819a009848b3 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.9.1-cpu_mkl_hfee2a32_102.conda#9f6f123bb5da9de569fe7e34a5913867 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.9.1-cpu_mkl_hfee2a32_103.conda#c39901fc181701c54648a8580d027bcb https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py313hf6604e3_0.conda#7d51e3bef1a4b00bde1861d85ba2f874 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-22.0.0-py313he109ebe_0_cpu.conda#0b4a0a9ab270b275eb6da8671edb9458 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 @@ -262,13 +262,13 @@ https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda#6186382cb34a9953bf2a18fc763dc346 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-22.0.0-h635bf11_6_cpu.conda#579bdb829ab093d048e49a289d3c9883 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_2.conda#8a69ea71fdd37bfe42a28f0967dbb75a -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.9.1-cpu_mkl_py313_hf5c6997_102.conda#8327cda07d244ae7825736ed1515b55e +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.9.1-cpu_mkl_py313_hf5c6997_103.conda#0246272db9858e29f2cf4e1d16316faf https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py313h4b8bb8b_0.conda#6cf603754566f66ff2be27f7f038b83a https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.0.1-pyhe01879c_0.conda#303ec962addf1b6016afd536e9db6bc6 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-22.0.0-h3f74fd7_6_cpu.conda#cfc7d2c5a81eb6de3100661a69de5f3d https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed -https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.9.1-cpu_mkl_hd61e0f4_102.conda#81cbeaa402d3aacc8244deb09be6bb90 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.9.1-cpu_mkl_hd61e0f4_103.conda#a402c0472ddad8058ef23fd3ffc10df8 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b https://conda.anaconda.org/conda-forge/linux-64/pyarrow-22.0.0-py313h78bf25f_0.conda#dfe7289ae9ad7aa091979a7c5e6a55c7 diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 4612b5c0c0090..fc79165b1eb94 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -14,7 +14,7 @@ https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda#22 https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda#d214916b24c625bcc459b245d509f22e https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda#210a85a1119f97ea7887188d176db135 https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.2-h8616949_0.conda#48dda187f169f5a8f1e5e07701d5cdd9 -https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda#8468beea04b9065b9807fc8b9cdc5894 +https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda#688a0c3d57fa118b9c97bf7e471ab46c https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda#18b81186a6adb43f000ad19ed7b70381 https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda#7bb6608cf1f83578587297a158a6630b https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda#003a54a4e32b02f7355b50a837e699da @@ -23,11 +23,13 @@ https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda#ced34 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda#47f1b8b4a76ebd0cd22bd7153e54a4dc https://conda.anaconda.org/conda-forge/osx-64/xorg-libxdmcp-1.1.5-h8616949_1.conda#435446d9d7db8e094d2c989766cfb146 +https://conda.anaconda.org/conda-forge/osx-64/xxhash-0.8.3-h13e91ac_0.conda#3e1f33316570709dac5d04bc4ad1b6d0 https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda#eaac87c21aff3ed21ad9656697bb8326 https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda#21f765ced1a0ef4070df53cb425e1967 https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda#63186ac7a8a24b3528b4b14f21c03f54 https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f -https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.53-h380d223_0.conda#0cdbbd56f660997cfe5d33e516afac2f +https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda#5a088b358e37ccb4f4e5c573ff37a9f9 +https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.54-h07817ec_0.conda#3d43dcdfcc3971939c80f855cf2df235 https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda#d910105ce2b14dfb2b32e92ec7653420 https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-hd57b93d_1.conda#060f6892620dc862f3b54b9b2da8f177 @@ -39,6 +41,7 @@ https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda#bd9f1de https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.2-h8bce59a_1.conda#cdd69480d52f2b871fad1a91324d9942 https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf +https://conda.anaconda.org/conda-forge/osx-64/ccache-4.12.2-h23dfd00_0.conda#18be62e9b80f56a47b1ccd830e5e1941 https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.conda#dfbdc8fd781dc3111541e4234c19fdbd https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_15.conda#c816665789d1e47cdfd6da8a81e1af64 https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 @@ -83,11 +86,9 @@ https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.0-py314hf9dbaa9_0.cond https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.13.0-h06b67a2_5.conda#f3e5cd2b56a3c866214b1d2529a54730 -https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.0.2-h2beb688_0.tar.bz2#524282b2c46c9dedf051b3bc2ae05494 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 https://conda.anaconda.org/conda-forge/osx-64/mkl-2023.2.0-h694c41f_50502.conda#0bdfc939c8542e0bc6041cbd9a900219 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/osx-64/ccache-4.11.3-h33566b8_0.conda#b65cad834bd6c1f660c101cca09430bf https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-20_osx64_mkl.conda#160fdc97a51d66d51dc782fb67d35205 https://conda.anaconda.org/conda-forge/osx-64/mkl-devel-2023.2.0-h694c41f_50502.conda#045f993e4434eaa02518d780fdca34ae https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock index de6b5421b9335..4d920f2ce7884 100644 --- a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock @@ -19,7 +19,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda#411ff7cd5d1472bba0f55c0faf04453b https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda#4d5a7445f0b25b6a3ddbb56e790f5251 https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda#f0695fbecf1006f27f4395d64bd0c4b8 -https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda#d6df911d4564d77c4374b02552cb17d1 +https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda#009f0d956d7bfb00de86901d16e486c7 https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda#85ccccb47823dd9f7a99d2c7f530342f https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda#c0d87c3c8e075daf1daf6c31b53e8083 https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda#e5e7d467f80da752be17796b87fe6385 @@ -29,6 +29,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda#06 https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda#415816daf82e0b23a736a069a75e9da7 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda#78b548eed8227a689f93775d5d23ae09 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxdmcp-1.1.5-hc919400_1.conda#9d1299ace1924aa8f4e0bc8e71dd0cf7 +https://conda.anaconda.org/conda-forge/osx-arm64/xxhash-0.8.3-haa4e116_0.conda#54a24201d62fc17c73523e4b86f71ae8 https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda#a44032f282e7d2acdeb1c240308052dd https://conda.anaconda.org/conda-forge/osx-arm64/fmt-12.1.0-h403dcb5_0.conda#ae2f556fbb43e5a75cc80a47ac942a8e https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-h7bae524_2.conda#eed7278dfbab727b56f2c0b64330814b @@ -38,7 +39,8 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20250512.1-cxx17_hd41 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda#079e88933963f3f149054eec2c487bc2 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef -https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.53-hfab5511_0.conda#62b6111feeffe607c3ecc8ca5bd1514b +https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda#58b2c5aee0ad58549bf92baead9baead +https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.54-h132b30e_0.conda#1b80fd1eecb98f1cb7de4239f5d7dc15 https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda#4b0bf313c53c3e89692f020fb55d5f2c https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h5ef1a60_1.conda#7eed1026708e26ee512f43a04d9d0027 @@ -53,6 +55,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda#e31 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.2-hed4e4f5_1.conda#75f39a44c08cb5dc4ea847698de34ba3 https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c +https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.12.2-h414bf82_0.conda#5cacaa11f10beb9477976bc997305e27 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda#6d4ede03e2a8e20eb51f7f681d2a2550 https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_16.conda#8b216bac0de7a9d60f3ddeba2515545c https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.31.1-h98f38fd_4.conda#8a6b4281c176f1695ae0015f420e6aa9 @@ -117,13 +120,11 @@ https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_ https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_7.conda#3b992d143f0008588ca26df8a324eee9 https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_3.conda#fac8bcc3f72041318061b92c1f269aa4 https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h8d724d3_accelerate.conda#c32b3b0d73d5cb1ab2a095a69bf3a7bd -https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.0.2-hbec66e7_0.tar.bz2#37ca71a16015b17397da4a5e6883f66f https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.18.0-py313ha61f8ec_0.conda#08c825d0a6cde154eb8c4729563114e7 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.11.3-hd7c7cec_0.conda#7fe1ee81492f43731ea583b4bee50b8b https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_h8c76c84_3.conda#972e9ed0155a9f563d1bd7a0a4ffeb28 https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_h752f6bc_accelerate.conda#e5733907c1c77e6db5012c299e42a5ad https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hcb0d94e_accelerate.conda#3b5a735865842f8d6bf8b78b376ca9e1 @@ -132,18 +133,18 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.co https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_3.conda#7b0ea95f0288f1a25f692800b407daf2 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_3.conda#d197a4b2169c054aa91252e1f95d7b08 https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-5_hbdd07e9_accelerate.conda#29c7d09cbe6d342ced64b0447e1f3792 -https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.9.1-cpu_generic_h812a54d_2.conda#7aa9f7ae0c71c7c51b1d8510e97addb6 +https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.9.1-cpu_generic_h812a54d_3.conda#7f333017d415d7104592feeac90e5f61 https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.1-py313h16eae64_0.conda#527abeb3c3f65345d9c337fb49e32d51 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-5_h55bc449_accelerate.conda#6696b095e91860523bcc97303e11d30d https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313ha61f8ec_3.conda#5643cff3e9ab77999fba139465156e35 https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.3-py313h7d16b84_2.conda#03771a1c710d15974372ae791811bcde -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.9.1-cpu_generic_py313_hf9b77c4_2.conda#fe9b1a3fe70b571ef23580c77d173930 +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.9.1-cpu_generic_py313_hf9b77c4_3.conda#2578f6b6a8bde43e10755b85b09516db https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.0-py313hc753a45_0.conda#9820f8f7d2f7b973e0b71c00adb32172 https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.305-accelerate.conda#5f941c90faaca70599ef8302d0c2738f https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py313h58042b9_0.conda#745c18472bc6d3dc9146c3dec18bb740 https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py313h28ea3aa_1.conda#51a353d043e612a8f520627cf0e73653 -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.9.1-cpu_generic_hcc7c195_2.conda#97de67427e3786a0aa68c091bb2bbda8 +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.9.1-cpu_generic_hcc7c195_3.conda#cd865dffd904fb755c5633facf59926b https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py313h39782a4_0.conda#bae471007cbebf097a19e851c219d56a https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda#148516e0c9edf4e9331a4d53ae806a9b https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_7.conda#13150cdd8e6bc61aa68b55d1a2a69083 @@ -151,11 +152,12 @@ https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_impl_osx-arm64-14.3.0-h6d03799_1.conda#1e9ec88ecc684d92644a45c6df2399d0 https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_7.conda#bde6fcb6b1fcefb687a7fb95675c6ec8 -https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_29.conda#e1cbe6c2279228ca3a0ee32a80e89c89 +https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_30.conda#c4084c97eb4a40f93efc3844c552d895 https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_7.conda#4fa4a9227c428372847c534a9bffd698 -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_29.conda#8dcfeec0143f62fc8beffc8065995105 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_hc995acf_7.conda#0c1f688616da9aac0ce556d74a24f740 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_osx-arm64-14.3.0-h3c33bd0_0.conda#8db8c0061c0f3701444b7b9cc9966511 -https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda#043afed05ca5a0f2c18252ae4378bdee +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_30.conda#ad0ecddf92544c4be2e431e1b720f9ed https://conda.anaconda.org/conda-forge/osx-arm64/gfortran-14.3.0-h3ef1dbf_0.conda#e148e0bc9bbc90b6325a479a5501786d +https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda#043afed05ca5a0f2c18252ae4378bdee https://conda.anaconda.org/conda-forge/osx-arm64/fortran-compiler-1.11.0-h81a4f41_0.conda#d221c62af175b83186f96d8b0880bff6 https://conda.anaconda.org/conda-forge/osx-arm64/compilers-1.11.0-hce30654_0.conda#aac0d423ecfd95bde39582d0de9ca657 diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index b1ee2dcb2e5fb..9c968f1bc40b4 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -12,27 +12,23 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda# https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 +https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 -https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 @@ -50,7 +46,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip joblib @ https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl#sha256=5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 # pip kiwisolver @ https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 -# pip meson @ https://files.pythonhosted.org/packages/32/4f/c398c6f06ece1c6c246e008d5dac3824c98f54d3eb3d8014f4910afd6d48/meson-1.10.0-py3-none-any.whl#sha256=4b27aafce281e652dcb437b28007457411245d975c48b5db3a797d3e93ae1585 +# pip meson @ https://files.pythonhosted.org/packages/9c/d5/582789135863eec7c8c1fa31fbde401b3d5d82dbbb4a0973351a1698f738/meson-1.10.1-py3-none-any.whl#sha256=fe43d1cc2e6de146fbea78f3a062194bcc0e779efc8a0f0d7c35544dfb86731f # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip numpy @ https://files.pythonhosted.org/packages/ba/87/d341e519956273b39d8d47969dd1eaa1af740615394fe67d06f1efa68773/numpy-2.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8 # pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 @@ -81,7 +77,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip scipy @ https://files.pythonhosted.org/packages/63/1e/12fbf2a3bb240161651c94bb5cdd0eae5d4e8cc6eaeceb74ab07b12a753d/scipy-1.17.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=6680f2dfd4f6182e7d6db161344537da644d1cf85cf293f015c60a17ecf08752 # pip lightgbm @ https://files.pythonhosted.org/packages/42/86/dabda8fbcb1b00bcfb0003c3776e8ade1aa7b413dff0a2c08f457dace22f/lightgbm-4.6.0-py3-none-manylinux_2_28_x86_64.whl#sha256=cb19b5afea55b5b61cbb2131095f50538bd608a00655f23ad5d25ae3e3bf1c8d # pip matplotlib @ https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486 -# pip meson-python @ https://files.pythonhosted.org/packages/28/58/66db620a8a7ccb32633de9f403fe49f1b63c68ca94e5c340ec5cceeb9821/meson_python-0.18.0-py3-none-any.whl#sha256=3b0fe051551cc238f5febb873247c0949cd60ded556efa130aa57021804868e2 +# pip meson-python @ https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl#sha256=67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298 # pip pandas @ https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac # pip pyamg @ https://files.pythonhosted.org/packages/63/f3/c13ae1422434baeefe4d4f306a1cc77f024fe96d2abab3c212cfa1bf3ff8/pyamg-5.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=5cc223c66a7aca06fba898eb5e8ede6bb7974a9ddf7b8a98f56143c829e63631 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 97642e50abbd7..450dc8568f1bb 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -17,7 +17,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.2-hb03c661_0.conda#ada39f5726bc5481e9dce293709dfabc +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 @@ -29,12 +29,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.con https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb9d3cd8_3.conda#20ab6b90150325f1af7ca96bffafde63 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b -https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda#b64523fb87ac6f87f0790f324ad43046 +https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 @@ -48,6 +48,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 +https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.8.23-hd590300_0.conda#cc4f06f7eedb1523f3b83fd0fb3942ff https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d @@ -61,7 +62,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 +https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae @@ -84,6 +86,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1.conda#f883d61afbc95c50f7b3f62546da4235 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 @@ -122,7 +125,6 @@ https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 -https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -138,7 +140,6 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.3.1-h1e0337 https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.7.10-h9ab9c9b_2.conda#cf49873da2e59f876a2ad4794b05801b https://conda.anaconda.org/conda-forge/linux-64/brotli-1.0.9-h166bdaf_9.conda#4601544b4982ba1861fa9b9c607b2c06 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.0.9-py311ha362b79_9.conda#ced5340f5dc6cff43a80deac8d0e398f -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 0e2f50c4b26ce..fe5f051e42d17 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -16,7 +16,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35 https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 @@ -27,11 +27,12 @@ https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f +https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 @@ -39,23 +40,21 @@ https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 -https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 @@ -98,7 +97,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_0.conda#a1698614a27f4bd96815bac2ab22e1fc diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock index 1867bf0babeb0..fa74a97d2b340 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock @@ -30,7 +30,7 @@ https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda#ba4a https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_16.conda#1edb8bd8e093ebd31558008e9cb23b47 https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#64571d1dd6cdcfa25d0664a5950fdaa2 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda#56a686f92ac0273c0f6af58858a3f013 -https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda#c15148b2e18da456f5108ccb5e411446 +https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda#ba0bfd4c3cf73f299ffe46ff0eaeb8e3 https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.30-pthreads_h877e47f_4.conda#f551f8ae0ae6535be1ffde181f9377f3 https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda#903979414b47d777d548e5f0165e6cd8 https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.328.1-h477610d_0.conda#4403eae6c81f448d63a7f66c0b330536 @@ -47,7 +47,7 @@ https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_h0adab6e_openblas https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda#450e3ae947fc46b60f1d8f8f318b40d4 https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda#ccd93cfa8e54fd9df4e83dbe55ff6e8c https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda#2cf0cf76cc15d360dfa2f17fd6cf9772 -https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.53-h7351971_0.conda#fb6f43f6f08ca100cb24cff125ab0d9e +https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.54-h7351971_0.conda#638ecb69e44b6a588afd5633e81f9e61 https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h3cfd58e_1.conda#07d73826fde28e7dbaec52a3297d7d26 https://conda.anaconda.org/conda-forge/win-64/openblas-0.3.30-pthreads_h4a7f399_4.conda#482e61f83248a880d180629bf8ed36b2 https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda#77eaf2336f3ae749e712f63e36b0f0a1 @@ -103,7 +103,7 @@ https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-5_ha590de0_openb https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h3fd045d_3.conda#5e7e380c470e9f4683b3129fedafbcdf https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py311h3f79411_0.conda#e5445b571c6e2919198c40c6db3d25c5 https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda#d69c21967f35eb2ce7f1f85d6b6022d3 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.0-py311h17b8079_0.conda#da30e4de83b61f936f73660eb4fa3cd5 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.0-py311h9c22a71_0.conda#5a37e6e0b88c9fcfd1050ded185d07a1 diff --git a/build_tools/azure/ubuntu_atlas_lock.txt b/build_tools/azure/ubuntu_atlas_lock.txt index 12a53d14e1085..56a9a13757954 100644 --- a/build_tools/azure/ubuntu_atlas_lock.txt +++ b/build_tools/azure/ubuntu_atlas_lock.txt @@ -12,9 +12,9 @@ iniconfig==2.3.0 # via pytest joblib==1.3.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt -meson==1.10.0 +meson==1.10.1 # via meson-python -meson-python==0.18.0 +meson-python==0.19.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt ninja==1.13.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 22705df8fce74..7cd3004e9ed90 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -22,7 +22,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.2-hb03c661_0.conda#ada39f5726bc5481e9dce293709dfabc +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed @@ -33,7 +33,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.con https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b @@ -63,7 +63,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_16.conda#0617b134e4dc4474c1038707499f7eed https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda#a587892d3c13b6621a6091be690dbca2 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae @@ -92,7 +92,7 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee -https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_6.conda#08ed2d4223458aac1f07d855361bb476 +https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_7.conda#3a29a37b34dbd06672bdccb63829ec14 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 @@ -173,7 +173,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.co https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.23.1-pyhd8ed1ab_0.conda#a1e91db2d17fd258c64921cb38e6745a +https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.24.1-pyhd8ed1ab_0.conda#7526d20621b53440b0aae45d4797847e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.1-py311haee01d2_0.conda#8cc656ea4773e02929cc58745669b116 https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda#7d9daffbb8d8e0af0f769dbbcd173a54 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef @@ -189,11 +189,11 @@ https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h2315fbb_0.con https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda#3893f7b40738f9fe87510cb4468cdda5 -https://conda.anaconda.org/conda-forge/noarch/send2trash-2.0.0-pyha191276_0.conda#f2cc28627a451a28ddd5ef5ab0bf579d +https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_0.conda#645026465469ecd4989188e1c4e24953 https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 -https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.1-pyhd8ed1ab_0.conda#7de28c27fe620a4f7dbfaea137c6232b +https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.2-pyhd8ed1ab_0.conda#fcbe3971b6017792e9b24ff451daa7f5 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b @@ -245,7 +245,7 @@ https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py311h2e04523_0.conda#716357afd11c16214cdac522da447704 https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 -https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.1-pyhd8ed1ab_0.conda#0a8b38871cab04059c1cc04853b415a2 +https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.2-pyhd8ed1ab_0.conda#7702bcd70891dd0154d765a69e1afa94 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.14-hd8ed1ab_2.conda#a4effc7e6eb335d0e1080a5554590425 @@ -271,15 +271,15 @@ https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d354 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_16.conda#dcaf539ffe75649239192101037f1406 https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h9ce9316_17.conda#d5db7829d4b9b1676419fca2c63909b3 https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h310e576_17.conda#94474857477981fedf74cf7c47c88ba5 -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.1-py311h273f733_0.conda#1e2ccd20e277220a515d2afe5a810917 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h273f733_0.conda#fc4da80856253cd3786551227c34bc7a https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 -https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_1.conda#2d983ff1b82a1ccb6f2e9d8784bdd6bd +https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda#7b8bace4943e0dc345fc45938826f2b8 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 @@ -300,7 +300,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.cond https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.12.20-pyhd8ed1ab_0.conda#f8a199849a262291f127f4835c990935 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.1.14-pyhd8ed1ab_0.conda#3888b51c92979cdeef45120181dc8420 https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 3b39b271b2931..df58c6452d0e3 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -23,7 +23,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.2-hb03c661_0.conda#ada39f5726bc5481e9dce293709dfabc +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 @@ -35,11 +35,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.con https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b -https://conda.anaconda.org/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda#b64523fb87ac6f87f0790f324ad43046 +https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 @@ -69,7 +69,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_16.conda#0617b134e4dc4474c1038707499f7eed https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae @@ -102,7 +102,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hb https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee -https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_6.conda#08ed2d4223458aac1f07d855361bb476 +https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_7.conda#3a29a37b34dbd06672bdccb63829ec14 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_3.conda#70d1de6301b58ed99fea01490a9802a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 @@ -175,7 +175,7 @@ https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda#3ee https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 -https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.1-pyhd8ed1ab_0.conda#7de28c27fe620a4f7dbfaea137c6232b +https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.2-pyhd8ed1ab_0.conda#fcbe3971b6017792e9b24ff451daa7f5 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.2-pyhd8ed1ab_0.conda#5d99943f2ae3cc69e1ada12ce9d4d701 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f @@ -225,7 +225,7 @@ https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_1.conda#e933f92cedca212eb2916f24823cf90b https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_1.conda#e00afd65b88a3258212661b32c1469cb -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 @@ -254,7 +254,7 @@ https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.1-py311h273f733_0.conda#1e2ccd20e277220a515d2afe5a810917 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h273f733_0.conda#fc4da80856253cd3786551227c34bc7a https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.conda#643f8cb35133eb1be4919fb953f0a25f https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 @@ -265,7 +265,7 @@ https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2025.12.20-pyhd8ed1ab_0.conda#f8a199849a262291f127f4835c990935 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.1.14-pyhd8ed1ab_0.conda#3888b51c92979cdeef45120181dc8420 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.22.0-py311h320fe9a_2.conda#e94b7f09b52628b89e66cdbd8c3029dd https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.12.0-pyhd8ed1ab_0.tar.bz2#05ee2fb22c1eca4309c06d11aff049f3 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index f4a1da2471f16..e12bb662f93d8 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -17,7 +17,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.con https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_16.conda#cf9cd6739a3b694dcf551d898e112331 -https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.2-he30d5cf_0.conda#c7b811feff0255c3d00c2a080261856b +https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.3-he30d5cf_0.conda#4a98cbc4ade694520227402ff8880630 https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_8.conda#2921ac0b541bf37c69e66bd6d9a43bca https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda#e7df0aab10b9cbb73ab2a467ebfaf8c7 https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d5cf_1.conda#8ec1d03f3000108899d1799d9964f281 @@ -28,7 +28,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_1 https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_16.conda#87b4ffedaba8b4d675479313af74f612 https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda#5a86bf847b9b926f3a4f203339748d78 https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda#5109d7f837a3dfdf5c60f60e311b041f -https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.1-h86ecc28_2.conda#7d362346a479256857ab338588190da0 +https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda#96944e3c92386a12755b94619bae0b35 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_16.conda#52d9df8055af3f1665ba471cce77da48 @@ -41,6 +41,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libice-1.1.2-h86ecc28_0.conda#c8d8ec3e00cd0fd8a231789b91a7c5b7 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda#1c246e1105000c3660558459e2fd6d43 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda#bff06dcde4a707339d66d45d96ceb2e2 +https://conda.anaconda.org/conda-forge/linux-aarch64/xxhash-0.8.3-hd794028_0.conda#f2accdfbd632e2be9a63bed23cb08045 https://conda.anaconda.org/conda-forge/linux-aarch64/double-conversion-3.4.0-hfae3067_0.conda#9fd794eaf983eabf975ead524540b4be https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda#4aa540e9541cc9d6581ab23ff2043f13 https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.2-hb1525cb_0.conda#15b35dc33e185e7d2aac1cfcd6778627 @@ -50,8 +51,9 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda#2079727b538f6dd16f3fa579d4c3c53f https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda#fb640d776fc92b682a14e001980825b1 https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_16.conda#776cca322459d09aad229a49761c0654 +https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.3.0-h5ad3122_1.conda#c11818b31f7c054ce220041b2459aacb https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.53-h1abf092_0.conda#7591d867dbcba9eb7fb5e88a5f756591 +https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.54-h1abf092_0.conda#45b47396febdf400c55fe129cfc398aa https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_16.conda#20b7f96f58ccbe8931c3a20778fb3b32 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda#b4df5d7d4b63579d081fd3a4cf99740e @@ -65,10 +67,10 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0 https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.2-ha7cb516_1.conda#055d3357e5d6f57291a687c6983e1884 https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 +https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.12.2-h185addb_0.conda#bd265b4c7864af1bcc22822150cf74be https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.21.3-h50a48e9_0.conda#29c10432a2ca1472b53f299ffb2ffa37 https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45-default_h1979696_105.conda#849c4cbbf8dd1d71e66c13afed1d2f12 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.1-hdae7a39_0.conda#9c2f56b6e011c6d8010ff43b796aab2f -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-ng-15.2.0-he9431aa_16.conda#3b55579065fac309af0129098fa1657b https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.3-hf53f6bf_0.conda#f226b9798c6c176d2a94eea1350b3b6b https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.2-h10b116e_0.conda#4e3ba0d5d192f99217b85f07a0761e64 @@ -88,7 +90,6 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_o https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h5cdc715_5.conda#ac0333d338076ef19170938bbaf97582 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.1-h8af1aa0_0.conda#1e61fb236ccd3d6ccaf9e91cb2d7e12d https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a -https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.0.2-h05efe27_0.tar.bz2#a87f068744fd20334cd41489eb163bee https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.1-h825857f_1.conda#eb4665cdf78fd02d4abc4edf8c15b7b9 https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.30-pthreads_h3a8cbd8_4.conda#e3f245ed352bd66d181b73a78d886038 https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c @@ -98,7 +99,6 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xkeyboard-config-2.46-he30d https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.6-h57736b2_0.conda#bd1e86dd8aa3afd78a4bfdb4ef918165 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5cf_0.conda#e8b4056544341daf1d415eaeae7a040c https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda#ae2c2dd0e2d38d249887727db2af960e -https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.11.3-h4889ad1_0.conda#e0b9e519da2bf0fb8c48381daf87a194 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.4-py311hdc11669_0.conda#931a90956062cc7219c6bce6c6ccfe7f @@ -154,7 +154,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-5_h9678261_openblas.conda#33a0e650392a79b56ae0bfa3db02ddbf https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311hfca10b7_3.conda#47c305536dbf44cd3e629b6851605a50 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.16.3-py311h399493a_2.conda#cacb6fbad878af1122e1301482fbc957 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.305-openblas.conda#2efe635198609d0d2a122c6a0923b8f8 From 1c827286a4dfe19a5a0a52277fca539e4445037f Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 19 Jan 2026 10:17:38 +0100 Subject: [PATCH 140/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33051) Co-authored-by: Lock file bot --- ...pylatest_pip_scipy_dev_linux-64_conda.lock | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 92a464bdd432a..22e24424493e4 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -12,27 +12,23 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda# https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda#518e9bbbc3e3486d6a4519192ba690f8 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 +https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda#b1f35e70f047918b49fb4b181e40300e -https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-h32b2ec7_100_cp314.conda#1cef1236a05c3a98f68c33ae9425f656 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 @@ -45,7 +41,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip imagesize @ https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl#sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip markupsafe @ https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 -# pip meson @ https://files.pythonhosted.org/packages/32/4f/c398c6f06ece1c6c246e008d5dac3824c98f54d3eb3d8014f4910afd6d48/meson-1.10.0-py3-none-any.whl#sha256=4b27aafce281e652dcb437b28007457411245d975c48b5db3a797d3e93ae1585 +# pip meson @ https://files.pythonhosted.org/packages/9c/d5/582789135863eec7c8c1fa31fbde401b3d5d82dbbb4a0973351a1698f738/meson-1.10.1-py3-none-any.whl#sha256=fe43d1cc2e6de146fbea78f3a062194bcc0e779efc8a0f0d7c35544dfb86731f # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 # pip platformdirs @ https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl#sha256=d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31 @@ -67,7 +63,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 -# pip meson-python @ https://files.pythonhosted.org/packages/28/58/66db620a8a7ccb32633de9f403fe49f1b63c68ca94e5c340ec5cceeb9821/meson_python-0.18.0-py3-none-any.whl#sha256=3b0fe051551cc238f5febb873247c0949cd60ded556efa130aa57021804868e2 +# pip meson-python @ https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl#sha256=67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298 # pip pooch @ https://files.pythonhosted.org/packages/a8/87/77cc11c7a9ea9fd05503def69e3d18605852cd0d4b0d3b8f15bbeb3ef1d1/pooch-1.8.2-py3-none-any.whl#sha256=3529a57096f7198778a5ceefd5ac3ef0e4d06a6ddaf9fc2d609b806f25302c47 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 From 935121fb73f68b7f8f61fd2be29203325948cb52 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Mon, 19 Jan 2026 11:22:05 +0100 Subject: [PATCH 141/462] MAINT update array API lock file (#33107) --- ...a_forge_cuda_array-api_linux-64_conda.lock | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index a3142d4ed1ac8..e508d51d75caa 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -21,7 +21,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 -https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.1-hb03c661_0.conda#bba37fb066adb90e1d876dff0fd5d09d +https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.10.6-hb9d3cd8_0.conda#d7d4680337a14001b0e043e96529409b https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 @@ -34,7 +34,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.con https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda#1a580f7796c7bf6393fddb8bbbde58dc +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b @@ -50,6 +50,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002. https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f +https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.8.1-h1a47875_3.conda#55a8561fdbbbd34f50f57d9be12ed084 https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.0-h4e1184b_5.conda#3f4c1197462a6df2be6dc8241828fe93 https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.1-h4e1184b_4.conda#a5126a90e74ac739b00564a4c7ddcc36 @@ -66,8 +67,9 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.53-h421ea60_0.conda#00d4e66b1f746cb14944cad23fffb405 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-h0c1763c_1.conda#ad1fd565aff83b543d726382c0ab0af2 +https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -87,6 +89,7 @@ https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#4 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.15.3-h173a860_6.conda#9a063178f1af0a898526cc24ba7be486 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb03c661_4.conda#ca4ed8015764937c81b830f7f5b68543 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf https://conda.anaconda.org/conda-forge/linux-64/cudatoolkit-11.8.0-h4ba93d1_13.conda#eb43f5f1f16e2fad2eba22219c3e499b https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 @@ -95,7 +98,6 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.28.2-h5b01275_0.conda#ab0bff36363bec94720275a681af8b83 @@ -114,13 +116,12 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.9.2-hefd7a92_4.cond https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb03c661_4.conda#eaf3fbd2aa97c212336de38a51fe404e https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.17-h717163a_0.conda#000e85703f0fd9594c81710dd5066471 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.1.4-h7d33bf5_0.conda#93fe78190bc6fe40d5e7a737c8065286 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.0.2-h2cc385e_0.tar.bz2#b34907d3a81a3cd8095ee83d174c074a https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.9-h04c0eec_0.conda#35eeb0a2add53b1e50218ed230fa6a02 https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -135,16 +136,15 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_ https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.8.0-hb921021_15.conda#c79d50f64cffa5ad51ecc1a81057962f https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.11.0-h11f4f37_12.conda#96c3e0221fa2da97619ee82faa341a73 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.14.0-h5cfcd09_0.conda#0a8838771cc2e985cd295e01ae83baf1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.11.3-h80c52d3_0.conda#eb517c6a2b960c3ccb6f1db1005f063a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda#9bcbd351966dc56a24fc0c368da5ad99 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.2-pyhd8ed1ab_0.conda#7e7cf4d6c2be6991e6ae2b3f4331701c +https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda#2cfaaccf085c133a477f0a7a8657afe9 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2025.12.0-pyhd8ed1ab_0.conda#a3b9510e2491c20c7fc0f5e730227fbb +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.1.0-pyhd8ed1ab_0.conda#1daaf94a304a27ba3446a306235a37ea https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 https://conda.anaconda.org/conda-forge/linux-64/libcudnn-dev-9.10.1.4-h0fdc2d1_0.conda#a0c0b44d26a4710e6ea577fcddbe09d1 @@ -173,7 +173,7 @@ https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.con https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.3.0-pyhcf101f3_0.conda#d2732eb636c264dc9aa4cbee404b1a53 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py313h07c4f96_0.conda#82da2dcf1ea3e298f2557b50459809e0 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 @@ -208,7 +208,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.29.7-hd92328a_7.co https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.13.0-h3cf044e_1.conda#7eb66060455c7a47d9dcdbfa9f46579b https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.32.0-h0121fbd_0.conda#877a5ec0431a5af83bf0cd0522bfe661 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.18.0-pyh70fd9c4_0.conda#576c04b9d9f8e45285fb4d9452c26133 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha770c72_17.conda#e4ab075598123e783b788b995afbdad0 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 @@ -217,31 +217,31 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-37_h5875eb1_mkl.conda#888c2ae634bce09709dffd739ba9f1bc https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2024.2.2-ha770c72_17.conda#e67269e07e58be5672f06441316f05f2 -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.36.1-py310hffdcd12_0.conda#af35229f34c80dcfab5a40414440df23 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.1-py310hffdcd12_0.conda#732a536c6ce768f096f5340121e10cc5 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/libarrow-18.1.0-h44a453e_6_cpu.conda#2cf6d608d6e66506f69797d5c6944c35 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-37_hfef963f_mkl.conda#f66eb9a9396715013772b8a3ef7396be https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-37_h5e43f62_mkl.conda#0c4af651539e79160cd3f0783391e918 -https://conda.anaconda.org/conda-forge/noarch/polars-1.36.1-pyh6a1acc5_0.conda#160b41862a43936cbe509d1879d67f54 +https://conda.anaconda.org/conda-forge/noarch/polars-1.37.1-pyh6a1acc5_0.conda#1894d4373da653406c91e20ef89f05c8 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.2-h5bd77bc_1.conda#f7bfe5b8e7641ce7d11ea10cfd9f33cc https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-18.1.0-hcb10f89_6_cpu.conda#143f9288b64759a6427563f058c62f2b https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-37_hdba1596_mkl.conda#4e76080972d13c913f178c90726b21ce https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.8.0-h9ddd185_2.conda#8de40c4f75d36bb00a5870f682457f1d https://conda.anaconda.org/conda-forge/linux-64/libparquet-18.1.0-h081d1f1_6_cpu.conda#68788df49ce7480187eb6387f15b2b67 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.0-py313hf6604e3_0.conda#07963f5dbb5351201035e1f8815ed8da +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py313hf6604e3_0.conda#7d51e3bef1a4b00bde1861d85ba2f874 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-18.1.0-py313he5f92c8_0_cpu.conda#5380e12f4468e891911dbbd4248b521a https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.2-py313ha3f37dd_1.conda#e2ec46ec4c607b97623e7b691ad31c54 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-37_hcf00494_mkl.conda#3a3a2906daecd117aad30e4d68276394 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda#6186382cb34a9953bf2a18fc763dc346 -https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.6.0-py313hc2a895b_2.conda#1b3207acc9af23dcfbccb4647df0838e +https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.4.1-py313hc2a895b_0.conda#46dd595e816b278b178e3bef8a6acf71 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-18.1.0-hcb10f89_6_cpu.conda#20ca46a6bc714a6ab189d5b3f46e66d8 https://conda.anaconda.org/conda-forge/linux-64/libmagma_sparse-2.8.0-h9ddd185_0.conda#f4eb3cfeaf9d91e72d5b2b8706bf059f https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_2.conda#8a69ea71fdd37bfe42a28f0967dbb75a -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py313h4b8bb8b_1.conda#2b18fe5b4b2d1611ddf8c2f080a46563 https://conda.anaconda.org/conda-forge/linux-64/blas-2.137-mkl.conda#9deb2d32720cc73c9991dbd9e24b499e -https://conda.anaconda.org/conda-forge/linux-64/cupy-13.6.0-py313h66a2ee2_2.conda#9d83bdb568a47daf7fc38117db17fe4e +https://conda.anaconda.org/conda-forge/linux-64/cupy-13.4.1-py313h66a2ee2_0.conda#784d6bd149ef2b5d9c733ea3dd4d15ad https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-18.1.0-h3ee7192_6_cpu.conda#aa313b3168caf98d00b3753f5ba27650 https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.5.1-cuda118_hb34f2e8_303.conda#da799bf557ff6376a1a58f40bddfb293 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 From 34653fe1a15a406b53fe31ba6e3601ea32145b16 Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Mon, 19 Jan 2026 11:39:58 +0100 Subject: [PATCH 142/462] DOC/MNT Little clean up around the splitting docs and error message (#33091) --- sklearn/calibration.py | 4 ++-- sklearn/covariance/_graph_lasso.py | 4 ++-- sklearn/feature_selection/_base.py | 2 +- sklearn/feature_selection/_rfe.py | 4 ++-- sklearn/feature_selection/_sequential.py | 2 +- sklearn/linear_model/_coordinate_descent.py | 16 ++++++++-------- sklearn/linear_model/_least_angle.py | 8 ++++---- sklearn/linear_model/_omp.py | 4 ++-- sklearn/linear_model/_ridge.py | 8 ++++---- sklearn/model_selection/_plot.py | 4 ++-- sklearn/model_selection/_search.py | 4 ++-- .../_search_successive_halving.py | 4 ++-- sklearn/model_selection/_split.py | 16 +++++++++------- sklearn/model_selection/_validation.py | 8 ++++---- sklearn/model_selection/tests/test_split.py | 3 ++- sklearn/multioutput.py | 4 ++-- 16 files changed, 49 insertions(+), 46 deletions(-) diff --git a/sklearn/calibration.py b/sklearn/calibration.py index d6c206f8870b2..f0497bc221eae 100644 --- a/sklearn/calibration.py +++ b/sklearn/calibration.py @@ -142,9 +142,9 @@ class CalibratedClassifierCV(ClassifierMixin, MetaEstimatorMixin, BaseEstimator) Possible inputs for cv are: - None, to use the default 5-fold cross-validation, - - integer, to specify the number of folds. + - integer, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, if ``y`` is binary or multiclass, :class:`~sklearn.model_selection.StratifiedKFold` is used. If ``y`` is diff --git a/sklearn/covariance/_graph_lasso.py b/sklearn/covariance/_graph_lasso.py index dce753fea71f4..aa114cb4ba195 100644 --- a/sklearn/covariance/_graph_lasso.py +++ b/sklearn/covariance/_graph_lasso.py @@ -747,9 +747,9 @@ class GraphicalLassoCV(BaseGraphicalLasso): Possible inputs for cv are: - None, to use the default 5-fold cross-validation, - - integer, to specify the number of folds. + - integer, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs :class:`~sklearn.model_selection.KFold` is used. diff --git a/sklearn/feature_selection/_base.py b/sklearn/feature_selection/_base.py index 4527cfd0cd815..05b52ba5ade1b 100644 --- a/sklearn/feature_selection/_base.py +++ b/sklearn/feature_selection/_base.py @@ -24,7 +24,7 @@ class SelectorMixin(TransformerMixin, metaclass=ABCMeta): """ - Transformer mixin that performs feature selection given a support mask + Transformer mixin that performs feature selection given a support mask. This mixin provides a feature selector implementation with `transform` and `inverse_transform` functionality given an implementation of diff --git a/sklearn/feature_selection/_rfe.py b/sklearn/feature_selection/_rfe.py index bbb735cda5f56..2b1317d49128f 100644 --- a/sklearn/feature_selection/_rfe.py +++ b/sklearn/feature_selection/_rfe.py @@ -597,9 +597,9 @@ class RFECV(RFE): Possible inputs for cv are: - None, to use the default 5-fold cross-validation, - - integer, to specify the number of folds. + - integer, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, if ``y`` is binary or multiclass, :class:`~sklearn.model_selection.StratifiedKFold` is used. If the diff --git a/sklearn/feature_selection/_sequential.py b/sklearn/feature_selection/_sequential.py index fcfc01cac2037..3daad1e4fd42c 100644 --- a/sklearn/feature_selection/_sequential.py +++ b/sklearn/feature_selection/_sequential.py @@ -99,7 +99,7 @@ class SequentialFeatureSelector(SelectorMixin, MetaEstimatorMixin, BaseEstimator - None, to use the default 5-fold cross validation, - integer, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, if the estimator is a classifier and ``y`` is either binary or multiclass, diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index 9ab0312be04ce..71eae8a688750 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -2046,9 +2046,9 @@ class LassoCV(RegressorMixin, LinearModelCV): Possible inputs for cv are: - None, to use the default 5-fold cross-validation, - - int, to specify the number of folds. + - int, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For int/None inputs, :class:`~sklearn.model_selection.KFold` is used. @@ -2316,9 +2316,9 @@ class ElasticNetCV(RegressorMixin, LinearModelCV): Possible inputs for cv are: - None, to use the default 5-fold cross-validation, - - int, to specify the number of folds. + - int, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For int/None inputs, :class:`~sklearn.model_selection.KFold` is used. @@ -3014,9 +3014,9 @@ class MultiTaskElasticNetCV(RegressorMixin, LinearModelCV): Possible inputs for cv are: - None, to use the default 5-fold cross-validation, - - int, to specify the number of folds. + - int, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For int/None inputs, :class:`~sklearn.model_selection.KFold` is used. @@ -3272,9 +3272,9 @@ class MultiTaskLassoCV(RegressorMixin, LinearModelCV): Possible inputs for cv are: - None, to use the default 5-fold cross-validation, - - int, to specify the number of folds. + - int, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For int/None inputs, :class:`~sklearn.model_selection.KFold` is used. diff --git a/sklearn/linear_model/_least_angle.py b/sklearn/linear_model/_least_angle.py index c50b552313925..a1a858c4f9f71 100644 --- a/sklearn/linear_model/_least_angle.py +++ b/sklearn/linear_model/_least_angle.py @@ -1542,9 +1542,9 @@ class LarsCV(Lars): Possible inputs for cv are: - None, to use the default 5-fold cross-validation, - - integer, to specify the number of folds. + - integer, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, :class:`~sklearn.model_selection.KFold` is used. @@ -1862,9 +1862,9 @@ class LassoLarsCV(LarsCV): Possible inputs for cv are: - None, to use the default 5-fold cross-validation, - - integer, to specify the number of folds. + - integer, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, :class:`~sklearn.model_selection.KFold` is used. diff --git a/sklearn/linear_model/_omp.py b/sklearn/linear_model/_omp.py index 98ddc93a49b20..50014a054d23f 100644 --- a/sklearn/linear_model/_omp.py +++ b/sklearn/linear_model/_omp.py @@ -926,9 +926,9 @@ class OrthogonalMatchingPursuitCV(RegressorMixin, LinearModel): Possible inputs for cv are: - None, to use the default 5-fold cross-validation, - - integer, to specify the number of folds. + - integer, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, :class:`~sklearn.model_selection.KFold` is used. diff --git a/sklearn/linear_model/_ridge.py b/sklearn/linear_model/_ridge.py index 359916d93600e..344ef1307b796 100644 --- a/sklearn/linear_model/_ridge.py +++ b/sklearn/linear_model/_ridge.py @@ -2654,9 +2654,9 @@ class RidgeCV(MultiOutputMixin, RegressorMixin, _BaseRidgeCV): Possible inputs for cv are: - None, to use the efficient Leave-One-Out cross-validation - - integer, to specify the number of folds. + - integer, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, if ``y`` is binary or multiclass, :class:`~sklearn.model_selection.StratifiedKFold` is used, else, @@ -2847,9 +2847,9 @@ class RidgeClassifierCV(_RidgeClassifierMixin, _BaseRidgeCV): Possible inputs for cv are: - None, to use the efficient Leave-One-Out cross-validation - - integer, to specify the number of folds. + - integer, to specify the number of folds, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. Refer :ref:`User Guide ` for the various cross-validation strategies that can be used here. diff --git a/sklearn/model_selection/_plot.py b/sklearn/model_selection/_plot.py index 16da45b03e65d..c6d74a9aeba95 100644 --- a/sklearn/model_selection/_plot.py +++ b/sklearn/model_selection/_plot.py @@ -354,7 +354,7 @@ def from_estimator( - None, to use the default 5-fold cross validation, - int, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For int/None inputs, if the estimator is a classifier and `y` is either binary or multiclass, @@ -741,7 +741,7 @@ def from_estimator( - None, to use the default 5-fold cross validation, - int, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For int/None inputs, if the estimator is a classifier and `y` is either binary or multiclass, diff --git a/sklearn/model_selection/_search.py b/sklearn/model_selection/_search.py index 420df1d79250e..3f568ce60c842 100644 --- a/sklearn/model_selection/_search.py +++ b/sklearn/model_selection/_search.py @@ -1347,7 +1347,7 @@ class GridSearchCV(BaseSearchCV): - None, to use the default 5-fold cross validation, - integer, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, if the estimator is a classifier and ``y`` is either binary or multiclass, :class:`StratifiedKFold` is used. In all @@ -1732,7 +1732,7 @@ class RandomizedSearchCV(BaseSearchCV): - None, to use the default 5-fold cross validation, - integer, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, if the estimator is a classifier and ``y`` is either binary or multiclass, :class:`StratifiedKFold` is used. In all diff --git a/sklearn/model_selection/_search_successive_halving.py b/sklearn/model_selection/_search_successive_halving.py index 825b44ed2d5c1..35d1fb0611e2c 100644 --- a/sklearn/model_selection/_search_successive_halving.py +++ b/sklearn/model_selection/_search_successive_halving.py @@ -461,7 +461,7 @@ class HalvingGridSearchCV(BaseSuccessiveHalving): - integer, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, if the estimator is a classifier and ``y`` is either binary or multiclass, :class:`StratifiedKFold` is used. In all @@ -820,7 +820,7 @@ class HalvingRandomSearchCV(BaseSuccessiveHalving): - integer, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For integer/None inputs, if the estimator is a classifier and ``y`` is either binary or multiclass, :class:`StratifiedKFold` is used. In all diff --git a/sklearn/model_selection/_split.py b/sklearn/model_selection/_split.py index 6582427d80d24..c9a3a5bfaea92 100644 --- a/sklearn/model_selection/_split.py +++ b/sklearn/model_selection/_split.py @@ -2696,9 +2696,9 @@ def check_cv(cv=5, y=None, *, classifier=False): Determines the cross-validation splitting strategy. Possible inputs for cv are: - None, to use the default 5-fold cross validation, - - integer, to specify the number of folds. + - integer, to specify the number of folds, - :term:`CV splitter`, - - An iterable that generates (train, test) splits as arrays of indices. + - an iterable that generates (train, test) splits as arrays of indices. For integer/None inputs, if classifier is True and ``y`` is either binary or multiclass, :class:`StratifiedKFold` is used. In all other @@ -2714,8 +2714,10 @@ def check_cv(cv=5, y=None, *, classifier=False): The target variable for supervised learning problems. classifier : bool, default=False - Whether the task is a classification task, in which case - stratified KFold will be used. + Whether the task is a classification task. When ``True`` and `cv` is an + integer or ``None``, :class:`StratifiedKFold` is used if ``y`` is binary + or multiclass; otherwise :class:`KFold` is used. Ignored if `cv` is a + cross-validator instance or iterable. Returns ------- @@ -2745,9 +2747,9 @@ def check_cv(cv=5, y=None, *, classifier=False): if not hasattr(cv, "split") or isinstance(cv, str): if not isinstance(cv, Iterable) or isinstance(cv, str): raise ValueError( - "Expected cv as an integer, cross-validation " - "object (from sklearn.model_selection) " - "or an iterable. Got %s." % cv + "Expected `cv` as an integer, a cross-validation object " + "(from sklearn.model_selection), or an iterable yielding (train, test) " + f"splits as arrays of indices. Got {cv}." ) return _CVIterableWrapper(cv) diff --git a/sklearn/model_selection/_validation.py b/sklearn/model_selection/_validation.py index 3f7f424757bfa..d1e5693a45f29 100644 --- a/sklearn/model_selection/_validation.py +++ b/sklearn/model_selection/_validation.py @@ -170,7 +170,7 @@ def cross_validate( - None, to use the default 5-fold cross validation, - int, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For int/None inputs, if the estimator is a classifier and ``y`` is either binary or multiclass, :class:`StratifiedKFold` is used. In all @@ -1504,7 +1504,7 @@ def permutation_test_score( - `None`, to use the default 5-fold cross validation, - int, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For `int`/`None` inputs, if the estimator is a classifier and `y` is either binary or multiclass, :class:`StratifiedKFold` is used. In all @@ -1810,7 +1810,7 @@ def learning_curve( - None, to use the default 5-fold cross validation, - int, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For int/None inputs, if the estimator is a classifier and ``y`` is either binary or multiclass, :class:`StratifiedKFold` is used. In all @@ -2296,7 +2296,7 @@ def validation_curve( - None, to use the default 5-fold cross validation, - int, to specify the number of folds in a `(Stratified)KFold`, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. For int/None inputs, if the estimator is a classifier and ``y`` is either binary or multiclass, :class:`StratifiedKFold` is used. In all diff --git a/sklearn/model_selection/tests/test_split.py b/sklearn/model_selection/tests/test_split.py index c4be05b695dd7..052273cf4734f 100644 --- a/sklearn/model_selection/tests/test_split.py +++ b/sklearn/model_selection/tests/test_split.py @@ -1621,7 +1621,8 @@ def test_check_cv(): cv = check_cv(3, y_multioutput, classifier=True) np.testing.assert_equal(list(KFold(3).split(X)), list(cv.split(X))) - with pytest.raises(ValueError): + msg = "Expected `cv` as an integer, a cross-validation object" + with pytest.raises(ValueError, match=msg): check_cv(cv="lolo") diff --git a/sklearn/multioutput.py b/sklearn/multioutput.py index 34a93e9a63b72..d03cb4ac4e7f8 100644 --- a/sklearn/multioutput.py +++ b/sklearn/multioutput.py @@ -920,7 +920,7 @@ class ClassifierChain(MetaEstimatorMixin, ClassifierMixin, _BaseChain): - None, to use true labels when fitting, - integer, to specify the number of folds in a (Stratified)KFold, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. chain_method : {'predict', 'predict_proba', 'predict_log_proba', \ 'decision_function'} or list of such str's, default='predict' @@ -1205,7 +1205,7 @@ class RegressorChain(MetaEstimatorMixin, RegressorMixin, _BaseChain): - None, to use true labels when fitting, - integer, to specify the number of folds in a (Stratified)KFold, - :term:`CV splitter`, - - An iterable yielding (train, test) splits as arrays of indices. + - an iterable yielding (train, test) splits as arrays of indices. random_state : int, RandomState instance or None, optional (default=None) If ``order='random'``, determines random number generation for the From afc095a7b17d5528d62f55f07cab39f963299c78 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Tue, 20 Jan 2026 18:31:37 +1100 Subject: [PATCH 143/462] DOC Fix typo in changelog readme (#33111) --- doc/whats_new/upcoming_changes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats_new/upcoming_changes/README.md b/doc/whats_new/upcoming_changes/README.md index 86edb6bd00e74..0d6be128bc452 100644 --- a/doc/whats_new/upcoming_changes/README.md +++ b/doc/whats_new/upcoming_changes/README.md @@ -33,7 +33,7 @@ folder with the following content:: now supports missing values in the data matrix `X`. Missing-values are handled by randomly moving all of the samples to the left, or right child node as the tree is traversed. - By :user:`Adam Li ` + By :user:`Adam Li `. ``` If you are unsure how to name the news fragment or which folder to use, don't From 3c5f668eb1131499e3db2fc50c1f99ee0b670756 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Tue, 20 Jan 2026 14:30:21 +0100 Subject: [PATCH 144/462] MNT Add specific error message to `get_tags()` when users pass estimator class instead of instance (#32565) Co-authored-by: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> --- .../sklearn.utils/32565.enhancement.rst | 3 +++ sklearn/utils/_tags.py | 6 ++++++ sklearn/utils/tests/test_tags.py | 16 ++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/32565.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/32565.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/32565.enhancement.rst new file mode 100644 index 0000000000000..06993be1ff366 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.utils/32565.enhancement.rst @@ -0,0 +1,3 @@ +- ``sklearn.utils._tags.get_tags`` now provides a clearer error message when a class + is passed instead of an estimator instance. + By :user:`Achyuthan S ` and :user:`Anne Beyer `. diff --git a/sklearn/utils/_tags.py b/sklearn/utils/_tags.py index a87d34b4d54f3..5319fc692d449 100644 --- a/sklearn/utils/_tags.py +++ b/sklearn/utils/_tags.py @@ -271,6 +271,12 @@ def get_tags(estimator) -> Tags: The estimator tags. """ + if isinstance(estimator, type): + raise TypeError( + f"Expected an estimator instance ({estimator.__name__}()), got " + f"estimator class instead ({estimator.__name__})." + ) + try: tags = estimator.__sklearn_tags__() except AttributeError as exc: diff --git a/sklearn/utils/tests/test_tags.py b/sklearn/utils/tests/test_tags.py index 5d910537b26d7..073b8359803c4 100644 --- a/sklearn/utils/tests/test_tags.py +++ b/sklearn/utils/tests/test_tags.py @@ -1,3 +1,4 @@ +import re from dataclasses import dataclass, fields import numpy as np @@ -32,6 +33,21 @@ class EmptyRegressor(RegressorMixin, BaseEstimator): pass +def test_type_error_is_thrown_for_class_vs_instance(): + """Test that a clearer error is raised if a class is passed instead of an instance. + + Related to the discussion in + https://github.com/scikit-learn/scikit-learn/issues/32394#issuecomment-3375647854. + """ + estimator_class = EmptyClassifier + match = re.escape( + "Expected an estimator instance (EmptyClassifier()), " + "got estimator class instead (EmptyClassifier)." + ) + with pytest.raises(TypeError, match=match): + get_tags(estimator_class) + + @pytest.mark.parametrize( "estimator, value", [ From 6d1ce8ce15d942f4d2e99a92ca0a845de87db29c Mon Sep 17 00:00:00 2001 From: Albert Dorador Chalar Date: Wed, 21 Jan 2026 19:30:05 +0100 Subject: [PATCH 145/462] FIX Resolve precompute in enet_path when check_input is False #32989 (#33014) Co-authored-by: Shruti Nath <51656807+snath-xoc@users.noreply.github.com> Co-authored-by: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> --- .../upcoming_changes/sklearn.linear_model/33014.fix.rst | 6 ++++++ sklearn/linear_model/_coordinate_descent.py | 4 ++-- sklearn/linear_model/tests/test_coordinate_descent.py | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33014.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33014.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33014.fix.rst new file mode 100644 index 0000000000000..83150ff46d8a0 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33014.fix.rst @@ -0,0 +1,6 @@ +- :func:`linear_model.enet_path` now correctly handles the ``precompute`` + parameter when ``check_input=False``. Previously, the value of + ``precompute`` was not properly treated which could lead to a ValueError. + This also affects :class:`linear_model.ElasticNetCV`, :class:`linear_model.LassoCV`, + :class:`linear_model.MultiTaskElasticNetCV` and :class:`linear_model.MultiTaskLassoCV`. + By :user:`Albert Dorador ` diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index 71eae8a688750..ca160d5f63705 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -633,7 +633,7 @@ def enet_path( # X should have been passed through _pre_fit already if function is called # from ElasticNet.fit - if check_input: + if check_input or precompute is not False: X, y, _, _, _, precompute, Xy = _pre_fit( X, y, @@ -641,7 +641,7 @@ def enet_path( precompute, fit_intercept=False, copy=False, - check_gram=True, + check_gram=check_input, ) if alphas is None: # fit_intercept and sample_weight have already been dealt with in calling diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index 788e097db0003..34fcb0c687f86 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -1875,3 +1875,11 @@ def test_linear_model_cv_alphas(Estimator): else: clf.fit(X, y[:, 0]) assert len(clf.alphas_) == 100 + + +@pytest.mark.parametrize("precompute", ["auto", True, False]) +def test_enet_path_check_input_false(precompute): + """Test enet_path works with check_input=False and various precompute settings.""" + X, y = make_regression(n_samples=100, n_features=5, n_informative=2, random_state=0) + X = np.asfortranarray(X) + alphas, _, _ = enet_path(X, y, n_alphas=3, check_input=False, precompute=precompute) From c9656a5c5749435bd5d01ceac2e5031edac7355d Mon Sep 17 00:00:00 2001 From: ABHISHEK <94426368+abhisheksainimitawa@users.noreply.github.com> Date: Thu, 22 Jan 2026 18:06:06 +0530 Subject: [PATCH 146/462] DOC: Remove redundant import in plot_iris_dtc example (#33102) --- examples/tree/plot_iris_dtc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/tree/plot_iris_dtc.py b/examples/tree/plot_iris_dtc.py index 349f4a893511e..8b865651572c9 100644 --- a/examples/tree/plot_iris_dtc.py +++ b/examples/tree/plot_iris_dtc.py @@ -30,7 +30,6 @@ import matplotlib.pyplot as plt import numpy as np -from sklearn.datasets import load_iris from sklearn.inspection import DecisionBoundaryDisplay from sklearn.tree import DecisionTreeClassifier From 492ad117b774fc01c08c831e61743a7d95e0215e Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Fri, 23 Jan 2026 02:58:15 +0100 Subject: [PATCH 147/462] FEA Add array API support for `average_precision_score` (#32909) Co-authored-by: Lucy Liu --- doc/modules/array_api.rst | 1 + .../array-api/32909.feature.rst | 3 ++ sklearn/metrics/_base.py | 45 ++++++++++++------- sklearn/metrics/_ranking.py | 30 +++++++++---- sklearn/metrics/tests/test_common.py | 17 +++++++ 5 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/32909.feature.rst diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index ba8abb1056342..03daabf933149 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -160,6 +160,7 @@ Metrics ------- - :func:`sklearn.metrics.accuracy_score` +- :func:`sklearn.metrics.average_precision_score` - :func:`sklearn.metrics.balanced_accuracy_score` - :func:`sklearn.metrics.brier_score_loss` - :func:`sklearn.metrics.cluster.calinski_harabasz_score` diff --git a/doc/whats_new/upcoming_changes/array-api/32909.feature.rst b/doc/whats_new/upcoming_changes/array-api/32909.feature.rst new file mode 100644 index 0000000000000..c3e550401d375 --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/32909.feature.rst @@ -0,0 +1,3 @@ +- :func:`sklearn.metrics.ranking.average_precision_score` now supports Array API + compliant inputs. + By :user:`Stefanie Senger `. diff --git a/sklearn/metrics/_base.py b/sklearn/metrics/_base.py index c7668bce9fceb..9964929a446b5 100644 --- a/sklearn/metrics/_base.py +++ b/sklearn/metrics/_base.py @@ -10,7 +10,9 @@ import numpy as np +import sklearn.externals.array_api_extra as xpx from sklearn.utils import check_array, check_consistent_length +from sklearn.utils._array_api import _average, _ravel, get_namespace_and_device from sklearn.utils.multiclass import type_of_target @@ -19,6 +21,9 @@ def _average_binary_score(binary_metric, y_true, y_score, average, sample_weight Parameters ---------- + binary_metric : callable, returns shape [n_classes] + The binary metric function to use. + y_true : array, shape = [n_samples] or [n_samples, n_classes] True binary labels in binary label indicators. @@ -47,9 +52,6 @@ def _average_binary_score(binary_metric, y_true, y_score, average, sample_weight sample_weight : array-like of shape (n_samples,), default=None Sample weights. - binary_metric : callable, returns shape [n_classes] - The binary metric function to use. - Returns ------- score : float or array of shape [n_classes] @@ -57,6 +59,7 @@ def _average_binary_score(binary_metric, y_true, y_score, average, sample_weight classes. """ + xp, _, _device = get_namespace_and_device(y_true, y_score, sample_weight) average_options = (None, "micro", "macro", "weighted", "samples") if average not in average_options: raise ValueError("average has to be one of {0}".format(average_options)) @@ -78,18 +81,23 @@ def _average_binary_score(binary_metric, y_true, y_score, average, sample_weight if average == "micro": if score_weight is not None: - score_weight = np.repeat(score_weight, y_true.shape[1]) - y_true = y_true.ravel() - y_score = y_score.ravel() + score_weight = xp.repeat(score_weight, y_true.shape[1]) + y_true = _ravel(y_true) + y_score = _ravel(y_score) elif average == "weighted": if score_weight is not None: - average_weight = np.sum( - np.multiply(y_true, np.reshape(score_weight, (-1, 1))), axis=0 + # Mixed integer and float type promotion not defined in array standard + y_true = xp.asarray(y_true, dtype=score_weight.dtype) + average_weight = xp.sum( + xp.multiply(y_true, xp.reshape(score_weight, (-1, 1))), axis=0 ) else: - average_weight = np.sum(y_true, axis=0) - if np.isclose(average_weight.sum(), 0.0): + average_weight = xp.sum(y_true, axis=0) + if xpx.isclose( + xp.sum(average_weight), + xp.asarray(0, dtype=average_weight.dtype, device=_device), + ): return 0 elif average == "samples": @@ -99,16 +107,20 @@ def _average_binary_score(binary_metric, y_true, y_score, average, sample_weight not_average_axis = 0 if y_true.ndim == 1: - y_true = y_true.reshape((-1, 1)) + y_true = xp.reshape(y_true, (-1, 1)) if y_score.ndim == 1: - y_score = y_score.reshape((-1, 1)) + y_score = xp.reshape(y_score, (-1, 1)) n_classes = y_score.shape[not_average_axis] - score = np.zeros((n_classes,)) + score = xp.zeros((n_classes,), device=_device) for c in range(n_classes): - y_true_c = y_true.take([c], axis=not_average_axis).ravel() - y_score_c = y_score.take([c], axis=not_average_axis).ravel() + y_true_c = _ravel( + xp.take(y_true, xp.asarray([c], device=_device), axis=not_average_axis) + ) + y_score_c = _ravel( + xp.take(y_score, xp.asarray([c], device=_device), axis=not_average_axis) + ) score[c] = binary_metric(y_true_c, y_score_c, sample_weight=score_weight) # Average the results @@ -116,9 +128,8 @@ def _average_binary_score(binary_metric, y_true, y_score, average, sample_weight if average_weight is not None: # Scores with 0 weights are forced to be 0, preventing the average # score from being affected by 0-weighted NaN elements. - average_weight = np.asarray(average_weight) score[average_weight == 0] = 0 - return float(np.average(score, weights=average_weight)) + return float(_average(score, weights=average_weight, xp=xp)) else: return score diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index 782f5c0fc7dbe..8712c63f0780a 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -31,6 +31,7 @@ from sklearn.utils._array_api import ( _max_precision_float_dtype, get_namespace_and_device, + move_to, size, ) from sklearn.utils._encode import _encode, _unique @@ -225,25 +226,36 @@ def average_precision_score( >>> average_precision_score(y_true, y_scores) 0.77 """ + xp, _, device = get_namespace_and_device(y_score) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) + + if sample_weight is not None: + sample_weight = column_or_1d(sample_weight) def _binary_uninterpolated_average_precision( - y_true, y_score, pos_label=1, sample_weight=None + y_true, + y_score, + pos_label=1, + sample_weight=None, + xp=xp, ): precision, recall, _ = precision_recall_curve( - y_true, y_score, pos_label=pos_label, sample_weight=sample_weight + y_true, + y_score, + pos_label=pos_label, + sample_weight=sample_weight, ) # Return the step function integral # The following works because the last entry of precision is # guaranteed to be 1, as returned by precision_recall_curve. # Due to numerical error, we can get `-0.0` and we therefore clip it. - return float(max(0.0, -np.sum(np.diff(recall) * np.array(precision)[:-1]))) + return float(max(0.0, -xp.sum(xp.diff(recall) * precision[:-1]))) y_type = type_of_target(y_true, input_name="y_true") - - present_labels = np.unique(y_true) + present_labels = xp.unique_values(y_true) if y_type == "binary": - if len(present_labels) == 2 and pos_label not in present_labels: + if present_labels.shape[0] == 2 and pos_label not in present_labels: raise ValueError( f"pos_label={pos_label} is not a valid label. It should be " f"one of {present_labels}" @@ -270,7 +282,7 @@ def _binary_uninterpolated_average_precision( ) average_precision = partial( - _binary_uninterpolated_average_precision, pos_label=pos_label + _binary_uninterpolated_average_precision, pos_label=pos_label, xp=xp ) return _average_binary_score( average_precision, y_true, y_score, average, sample_weight=sample_weight @@ -686,6 +698,8 @@ class scores must correspond to the order of ``labels``, y_type = type_of_target(y_true, input_name="y_true") y_true = check_array(y_true, ensure_2d=False, dtype=None) y_score = check_array(y_score, ensure_2d=False) + if sample_weight is not None: + sample_weight = column_or_1d(sample_weight) if y_type == "multiclass" or ( y_type == "binary" and y_score.ndim == 2 and y_score.shape[1] > 2 @@ -1142,7 +1156,7 @@ def precision_recall_curve( "No positive class found in y_true, " "recall is set to one for all thresholds." ) - recall = xp.full(tps.shape, 1.0) + recall = xp.full(tps.shape, 1.0, device=device) else: recall = tps / tps[-1] diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 353dfebf93bcf..0b7d8b474cec1 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -2098,6 +2098,18 @@ def check_array_api_multiclass_classification_metric( y_true_np = np.array([0, 1, 2, 3]) y_pred_np = np.array([0, 1, 0, 2]) + if metric.__name__ == "average_precision_score": + # we need y_pred_nd to be of shape (n_samples, n_classes) + y_pred_np = np.array( + [ + [0.7, 0.2, 0.05, 0.05], + [0.1, 0.8, 0.05, 0.05], + [0.1, 0.1, 0.7, 0.1], + [0.05, 0.05, 0.1, 0.8], + ], + dtype=dtype_name, + ) + additional_params = { "average": ("micro", "macro", "weighted"), "beta": (0.2, 0.5, 0.8), @@ -2299,6 +2311,11 @@ def check_array_api_metric_pairwise(metric, array_namespace, device, dtype_name) check_array_api_multiclass_classification_metric, check_array_api_multilabel_classification_metric, ], + average_precision_score: [ + check_array_api_binary_classification_metric, + check_array_api_multiclass_classification_metric, + check_array_api_multilabel_classification_metric, + ], balanced_accuracy_score: [ check_array_api_binary_classification_metric, check_array_api_multiclass_classification_metric, From e154bfc206df908bae5cf3c115a7f8edcaaa53af Mon Sep 17 00:00:00 2001 From: Bodhi Russell Silberling Date: Thu, 22 Jan 2026 18:30:08 -0800 Subject: [PATCH 148/462] Fix inconsistent string formatting in validation.py (#33121) --- sklearn/utils/validation.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index 531ff66995b87..7b39ef4952169 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -77,7 +77,7 @@ def inner_f(*args, **kwargs): # extra_args > 0 args_msg = [ - "{}={}".format(name, arg) + f"{name}={arg}" for name, arg in zip(kwonly_args[:extra_args], args[-extra_args:]) ] args_msg = ", ".join(args_msg) @@ -437,7 +437,7 @@ def check_memory(memory): raise ValueError( "'memory' should be None, a string or have the same" " interface as joblib.Memory." - " Got memory='{}' instead.".format(memory) + f" Got memory='{memory}' instead." ) return memory @@ -1465,7 +1465,7 @@ def check_random_state(seed): if isinstance(seed, np.random.RandomState): return seed raise ValueError( - "%r cannot be used to seed a numpy.random.RandomState instance" % seed + f"{seed!r} cannot be used to seed a numpy.random.RandomState instance" ) From d172c6cce82d562f5ff311ae6376cc9a5555f5c6 Mon Sep 17 00:00:00 2001 From: Bodhi Russell Silberling Date: Sat, 24 Jan 2026 14:29:32 -0800 Subject: [PATCH 149/462] Fix typo in test_docstrings.py comment (#33128) --- sklearn/tests/test_docstrings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/tests/test_docstrings.py b/sklearn/tests/test_docstrings.py index ea625ac076a01..47b8052b31998 100644 --- a/sklearn/tests/test_docstrings.py +++ b/sklearn/tests/test_docstrings.py @@ -51,7 +51,7 @@ def filter_errors(errors, method, Klass=None): # We ignore following error code, # - RT02: The first line of the Returns section # should contain only the type, .. - # (as we may need refer to the name of the returned + # (as we may need to refer to the name of the returned # object) # - GL01: Docstring text (summary) should start in the line # immediately after the opening quotes (not in the same line, From ef03de501248ace9cf45498cf3f7f68d713b053e Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 26 Jan 2026 04:26:36 -0500 Subject: [PATCH 150/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33132) Co-authored-by: Lock file bot --- build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 22e24424493e4..556c57caf6966 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -34,7 +34,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 # pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c # pip charset-normalizer @ https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 -# pip coverage @ https://files.pythonhosted.org/packages/82/2b/783ded568f7cd6b677762f780ad338bf4b4750205860c17c25f7c708995e/coverage-7.13.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=d3c9f051b028810f5a87c88e5d6e9af3c0ff32ef62763bf15d29f740453ca909 +# pip coverage @ https://files.pythonhosted.org/packages/ba/49/f54ec02ed12be66c8d8897270505759e057b0c68564a65c429ccdd1f139e/coverage-7.13.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=a7fc042ba3c7ce25b8a9f097eb0f32a5ce1ccdb639d9eec114e26def98e1f8a4 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea @@ -43,7 +43,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip markupsafe @ https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 # pip meson @ https://files.pythonhosted.org/packages/9c/d5/582789135863eec7c8c1fa31fbde401b3d5d82dbbb4a0973351a1698f738/meson-1.10.1-py3-none-any.whl#sha256=fe43d1cc2e6de146fbea78f3a062194bcc0e779efc8a0f0d7c35544dfb86731f # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa -# pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 +# pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 # pip platformdirs @ https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl#sha256=d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b From 78f0bd33573c0d76ddb2c977b963fae52ddd01ec Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 26 Jan 2026 04:27:10 -0500 Subject: [PATCH 151/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33133) Co-authored-by: Lock file bot --- .../azure/pylatest_free_threaded_linux-64_conda.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index e7203672de4fb..7990c4e8e47f8 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -40,12 +40,12 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.con https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d @@ -54,7 +54,7 @@ https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#61 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py314hd4f4903_0.conda#66c5cfbc84524e3eb553503b80874087 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.2-h92d6c8b_0.conda#f4db4d53331f31ec695670d5b3cedabb -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py314h529d2a9_0.conda#5c2d81fe28dd2bdcf502a070c58abc40 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py314h529d2a9_1.conda#2548681b651d007d01368d98b3f8536e https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.2-pyhd8ed1ab_0.conda#288250b7e539cddf52f39616deae278d From e2d2cdee04b37efb4d51969a381bc2d696ed16c1 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 26 Jan 2026 05:20:37 -0500 Subject: [PATCH 152/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33134) Co-authored-by: Lock file bot Co-authored-by: Olivier Grisel --- build_tools/azure/debian_32bit_lock.txt | 4 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 100 +++++++++--------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 20 ++-- .../pylatest_conda_forge_osx-arm64_conda.lock | 38 ++++--- ...st_pip_openblas_pandas_linux-64_conda.lock | 10 +- ...nblas_min_dependencies_linux-64_conda.lock | 18 ++-- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 17 ++- ...min_conda_forge_openblas_win-64_conda.lock | 22 ++-- build_tools/azure/ubuntu_atlas_lock.txt | 2 +- build_tools/circle/doc_linux-64_conda.lock | 39 ++++--- .../doc_min_dependencies_linux-64_conda.lock | 24 ++--- ...n_conda_forge_arm_linux-aarch64_conda.lock | 24 ++--- doc/modules/preprocessing.rst | 2 +- 13 files changed, 155 insertions(+), 165 deletions(-) diff --git a/build_tools/azure/debian_32bit_lock.txt b/build_tools/azure/debian_32bit_lock.txt index f8b8381a20a94..616fd261661a2 100644 --- a/build_tools/azure/debian_32bit_lock.txt +++ b/build_tools/azure/debian_32bit_lock.txt @@ -4,7 +4,7 @@ # # pip-compile --output-file=build_tools/azure/debian_32bit_lock.txt build_tools/azure/debian_32bit_requirements.txt # -coverage[toml]==7.13.1 +coverage[toml]==7.13.2 # via pytest-cov cython==3.2.4 # via -r build_tools/azure/debian_32bit_requirements.txt @@ -20,7 +20,7 @@ meson-python==0.19.0 # via -r build_tools/azure/debian_32bit_requirements.txt ninja==1.13.0 # via -r build_tools/azure/debian_32bit_requirements.txt -packaging==25.0 +packaging==26.0 # via # meson-python # pyproject-metadata diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index d7198fd604eb7..c3dff27c3c0cb 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -59,6 +59,7 @@ https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717 https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda#f7d7a4104082b39e3b3473fbd4a38229 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d +https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20250512.1-cxx17_hba17884_0.conda#83b160d4da3e1e847bf044997621ed63 https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 @@ -70,7 +71,6 @@ https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -94,7 +94,6 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.cond https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 -https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 @@ -103,8 +102,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_4.conda#07479fc04ba3ddd5d9f760ef1635cfa7 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h7b12aa8_0.conda#a30848ebf39327ea078cf26d114cff53 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 +https://conda.anaconda.org/conda-forge/linux-64/nodejs-22.21.1-h273caaf_1.conda#2306549f0179b16be2e9e40e5396456e https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 @@ -121,11 +123,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 -https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.12.0-h36edbcc_0.conda#adc6bd7e0e0ccd769227344712e80b28 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.1-hd747db4_0.conda#ddab8b2af55b88d63469c040377bd37e +https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-h19cb568_0.conda#a98b8d7cfdd20004f1bdd1a51cb22c58 +https://conda.anaconda.org/conda-forge/linux-64/playwright-1.58.0-h0bd9c3d_0.conda#2ed0eabd4c852ea6538a2b9ce549b24c https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_0.conda#0227d04521bc3d28c7995c7e1f99a721 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 @@ -148,7 +150,7 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda#2cfaaccf085c133a477f0a7a8657afe9 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.1.0-pyhd8ed1ab_0.conda#1daaf94a304a27ba3446a306235a37ea -https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.0-py313h7033f15_0.conda#2b1cf80423628afd34b4c66b767d7f6b +https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.1-py313h7033f15_0.conda#6eab2180bbbe36de88df9ed3fc579eb9 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -156,27 +158,27 @@ https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda#ff63bb12ac31c176ff257e3289f20770 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 +https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py313h80991f8_0.conda#183fe6b9e99e5c2b464c1573ec78eac8 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 -https://conda.anaconda.org/conda-forge/linux-64/playwright-1.57.0-h5585027_0.conda#0a2e773b5c3f67325d1733d2b7ca0ffb https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 -https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda#23b4ba5619c4752976eb7ba1f5acb7e8 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f @@ -193,8 +195,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0. https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.3-h06ab39a_1.conda#3689a4290319587e3b54a4f9e68f70c8 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda#4e921d9c85e6559c60215497978b3cdb -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.11.0-h3d7a050_1.conda#89985ba2a3742f34be6aafd6a8f3af8c -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.1-py313h3dea7bd_0.conda#82315acb438e857f809f556e2dcdb822 +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-h3d7a050_0.conda#e6f12de3a9b016cea81a87db04d85ff3 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.2-py313h3dea7bd_0.conda#df05169cc886aaf53dc560db634519f8 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py313h3dea7bd_0.conda#c0f36dfbb130da4f6ce2df31f6b25ea8 @@ -202,73 +204,69 @@ https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.cond https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_2.conda#3c71daed530c0c26671a1b1b7010e746 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_2.conda#0ad9019bb10eda915fb0ce5f78fef13b https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 -https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.0-pyhd8ed1ab_0.conda#ec33a030c3bc90f0131305a8eba5f8a3 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.11-h4df99d1_100.conda#d1461b2e63b1909f4f5b41c823bd90ae https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda#a4059bc12930bddeb41aef71537ffaed +https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.4-h8824e59_0.conda#113b9d9913280474c0868b0e290c0326 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.15.0-h2a74896_1.conda#ffd553ff98ce5d74d3d89ac269153149 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_1.conda#e933f92cedca212eb2916f24823cf90b -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_1.conda#e00afd65b88a3258212661b32c1469cb +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-h75daedc_0.conda#e88f8e816ae46c12cbe912c8f4d9d3bc +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.57.0-pyhcf101f3_0.conda#a61bfabd06f24469454086deb7f8166e https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10.conda#937d1d4c233adc6eeb2ac3d6e9a73e53 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.13.0-hf38f1be_1.conda#f10b9303c7239fbce3580a60a92bcf97 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-hd454692_0.conda#55986e49b7aafe9aa09d7f4c70a56a18 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.0-h6083320_0.conda#1ea5ed29aea252072b975a232b195146 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.1-py310hffdcd12_0.conda#732a536c6ce768f096f5340121e10cc5 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-22.0.0-hb6ed5f4_6_cpu.conda#fbaa3742ccca0f7096216c0832137b72 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad -https://conda.anaconda.org/conda-forge/noarch/polars-1.37.1-pyh6a1acc5_0.conda#1894d4373da653406c91e20ef89f05c8 -https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-h6f76662_3.conda#f134a496ef494f2b6c5a26e5d739acc6 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-22.0.0-h8c2c5c3_6_cpu.conda#d2cd924b5f451a7c258001cb1c14155d +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h2c50142_0_cpu.conda#ef47efe8884347ab96f0d26399e83229 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 -https://conda.anaconda.org/conda-forge/linux-64/libparquet-22.0.0-h7376487_6_cpu.conda#83fd8f55f38ac972947c9eca12dc4657 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py313h85046ba_0.conda#2c5d21d466ef1ff0c0a98cfdbaf5c64b -https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-22.0.0-h635bf11_6_cpu.conda#5a8f878ca313083960ab819a009848b3 +https://conda.anaconda.org/conda-forge/noarch/polars-1.37.1-pyh6a1acc5_0.conda#1894d4373da653406c91e20ef89f05c8 +https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-hb82b983_4.conda#f4dfd61ec958d420bebdcefeb805d658 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h8c2c5c3_0_cpu.conda#fa2c484e95ba37950f926bd797c51dc4 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.9.1-cpu_mkl_hfee2a32_103.conda#c39901fc181701c54648a8580d027bcb +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_0_cpu.conda#be2161a27537cb288a5634daf768af00 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_hfee2a32_100.conda#bc597665767a73ca870b4ad32e07f570 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py313hf6604e3_0.conda#7d51e3bef1a4b00bde1861d85ba2f874 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-22.0.0-py313he109ebe_0_cpu.conda#0b4a0a9ab270b275eb6da8671edb9458 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py313h85046ba_0.conda#2c5d21d466ef1ff0c0a98cfdbaf5c64b +https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda#6186382cb34a9953bf2a18fc763dc346 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-22.0.0-h635bf11_6_cpu.conda#579bdb829ab093d048e49a289d3c9883 -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_2.conda#8a69ea71fdd37bfe42a28f0967dbb75a -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.9.1-cpu_mkl_py313_hf5c6997_103.conda#0246272db9858e29f2cf4e1d16316faf -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py313h4b8bb8b_0.conda#6cf603754566f66ff2be27f7f038b83a +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_0_cpu.conda#0e1d44a4759116c17c77cdead68bb2d6 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py313hbfd7664_0.conda#ab6d05e915ab2ae4c41d275b14592151 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py313he109ebe_0_cpu.conda#9120bf253ebbdb0015069b9a25cf4d36 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py313_hf5c6997_100.conda#120b7f1d7c548044149e0ab80bbfcd69 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py313h4b8bb8b_1.conda#2b18fe5b4b2d1611ddf8c2f080a46563 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.0.1-pyhe01879c_0.conda#303ec962addf1b6016afd536e9db6bc6 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-22.0.0-h3f74fd7_6_cpu.conda#cfc7d2c5a81eb6de3100661a69de5f3d +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_0_cpu.conda#a373b33a7a1c9f57ef6273e886e91fe1 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed -https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.9.1-cpu_mkl_hd61e0f4_103.conda#a402c0472ddad8058ef23fd3ffc10df8 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_100.conda#3081ed71fc4fd81a6cc84938472798e5 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-h3f74fd7_0_cpu.conda#618c4d7d323f9b3ec4fdb0b3a5e5df1d https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-22.0.0-py313h78bf25f_0.conda#dfe7289ae9ad7aa091979a7c5e6a55c7 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.0-py313h78bf25f_0.conda#a6e89cb214f318db9548b791ba27f862 diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index fc79165b1eb94..37559ff83d529 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -58,17 +58,15 @@ https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.18-h90db99b_0.conda#753acc https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.1-h694c41f_0.conda#e0e2edaf5e0c71b843e25a7ecc451cc9 https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_15.conda#c2a6149bf7f82774a0118b9efef966dd https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h87e8dc5_0.conda#a67d3517ebbf615b91ef9fdc99934e0c -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 -https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -76,7 +74,7 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.4-py314h3d180e3_0.conda#e9dfcd5b883e35aebe6dbe2c197dddbe https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.0-py314h6482030_1.conda#d69097de15cbad36f1eaafda0bad598a -https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.1-py314h10d0514_0.conda#66abbb27b2ed5b9797c5d686bbf97446 +https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.2-py314h10d0514_0.conda#8a0d5bba423473595e51a29b1336f636 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.1-h694c41f_0.conda#ca641fdf8b7803f4b7212b6d66375930 @@ -86,7 +84,7 @@ https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.0-py314hf9dbaa9_0.cond https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.13.0-h06b67a2_5.conda#f3e5cd2b56a3c866214b1d2529a54730 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/osx-64/mkl-2023.2.0-h694c41f_50502.conda#0bdfc939c8542e0bc6041cbd9a900219 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-20_osx64_mkl.conda#160fdc97a51d66d51dc782fb67d35205 @@ -98,9 +96,9 @@ https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-20_osx64_mkl.conda https://conda.anaconda.org/conda-forge/osx-64/liblapacke-3.9.0-20_osx64_mkl.conda#124ae8e384268a8da66f1d64114a1eda https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.1-py314hfc4c462_0.conda#73bc04c55ef4911075790db9fcce921b https://conda.anaconda.org/conda-forge/osx-64/blas-devel-3.9.0-20_osx64_mkl.conda#cc3260179093918b801e373c6e888e02 -https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h00ed6fe_3.conda#761aa19f97a0dd5dedb9a0a6003707c1 -https://conda.anaconda.org/conda-forge/osx-64/pandas-2.3.3-py314hc4308db_2.conda#b082e18eb2696625aa09c80e0fbd1997 -https://conda.anaconda.org/conda-forge/osx-64/scipy-1.17.0-py314h6328ba2_0.conda#7e11a5f8d57512cbf80c45d146b72640 +https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h22a2ed9_4.conda#511f02f632e1fb0555da3cb4261851d9 +https://conda.anaconda.org/conda-forge/osx-64/pandas-3.0.0-py314h550b3c8_0.conda#6c2fa7e6dc0b23634f2f19d7054516b1 +https://conda.anaconda.org/conda-forge/osx-64/scipy-1.17.0-py314h6328ba2_1.conda#e519933e2e628d7cd159147c224366bf https://conda.anaconda.org/conda-forge/osx-64/blas-2.120-mkl.conda#b041a7677a412f3d925d8208936cb1e2 https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.8-py314hd47142c_0.conda#91d76a5937b47f7f0894857ce88feb9f https://conda.anaconda.org/conda-forge/osx-64/pyamg-5.3.0-py314h81027db_1.conda#47390f4299f43bcdae539d454178596e diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock index 4d920f2ce7884..c6659312b0021 100644 --- a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock @@ -6,7 +6,7 @@ https://conda.anaconda.org/conda-forge/noarch/libgfortran-devel_osx-arm64-14.3.0 https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a66894dfd07c4510beb6b3f9672ccc0 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 -https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-hc6f8731_5.conda#a3d76f9e9e3f49dc8bf03f1ef8d4757e +https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_6.conda#4cd4e8d9e11f08dfba7b48f6b3eae8cb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda#58fd217444c2a5701a44244faf518206 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 @@ -79,21 +79,19 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.c https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_16.conda#265a9d03461da24884ecc8eb58396d57 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h7d74516_0.conda#3df5979cc0b761dda0053ffdb0bca3ea -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.3.1-h8f1351a_1.conda#a5635df796b71f6ca400fc7026f50701 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hbfb3c88_0.conda#6bf3d24692c157a41c01ce0bd17daeea -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 -https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda#ade77ad7513177297b1d75e351e136ce https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f @@ -101,14 +99,14 @@ https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py313h6535dbc_0.conda#67a85c1b5c17124eaf9194206afd5159 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.1-py313h65a2061_0.conda#3283d95f985c7f293cb13bb7e33500a5 +https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.2-py313h65a2061_0.conda#310642d43db19e0bf5e499f29c76a124 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.61.1-py313h7d74516_0.conda#894eb0c3e9a17643906a6da3209bf045 https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.1-hce30654_0.conda#1ec9a1ee7a2c9339774ad9bb6fe6caec https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.2.1-py313hc1c22ca_2.conda#08bbc47d90ccee895465f61b8692e236 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_h6922315_3.conda#a9527064ed0ed4514de7a7d35ab28c97 +https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_4.conda#eaf3d06e3a8a10dee7565e8d76ae618d https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_7.conda#5600ae1b88144099572939e773f4b20b https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_16.conda#11e09edf0dde4c288508501fe621bab4 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef @@ -118,33 +116,33 @@ https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_7.conda#3b992d143f0008588ca26df8a324eee9 -https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_3.conda#fac8bcc3f72041318061b92c1f269aa4 +https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_4.conda#22eb76f8d98f4d3b8319d40bda9174de https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h8d724d3_accelerate.conda#c32b3b0d73d5cb1ab2a095a69bf3a7bd https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.18.0-py313ha61f8ec_0.conda#08c825d0a6cde154eb8c4729563114e7 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_h8c76c84_3.conda#972e9ed0155a9f563d1bd7a0a4ffeb28 +https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_he8a363d_4.conda#76c651b923e048f3f3e0ecb22c966f70 https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_h752f6bc_accelerate.conda#e5733907c1c77e6db5012c299e42a5ad https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hcb0d94e_accelerate.conda#3b5a735865842f8d6bf8b78b376ca9e1 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_3.conda#7b0ea95f0288f1a25f692800b407daf2 -https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_3.conda#d197a4b2169c054aa91252e1f95d7b08 +https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_4.conda#caf7c8e48827c2ad0c402716159fe0a2 +https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_4.conda#df5cd5c925df1412426e3db71d31363f https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-5_hbdd07e9_accelerate.conda#29c7d09cbe6d342ced64b0447e1f3792 -https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.9.1-cpu_generic_h812a54d_3.conda#7f333017d415d7104592feeac90e5f61 +https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.10.0-cpu_generic_h593a70c_0.conda#8100d227aad1ce35cb00f3a4f69cd5c3 https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.1-py313h16eae64_0.conda#527abeb3c3f65345d9c337fb49e32d51 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-5_h55bc449_accelerate.conda#6696b095e91860523bcc97303e11d30d -https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313ha61f8ec_3.conda#5643cff3e9ab77999fba139465156e35 -https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.3.3-py313h7d16b84_2.conda#03771a1c710d15974372ae791811bcde -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.9.1-cpu_generic_py313_hf9b77c4_3.conda#2578f6b6a8bde43e10755b85b09516db -https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.0-py313hc753a45_0.conda#9820f8f7d2f7b973e0b71c00adb32172 +https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313h2af2deb_4.conda#afd3e394d14e627be0de6e8ee3553dae +https://conda.anaconda.org/conda-forge/osx-arm64/pandas-3.0.0-py313h6974306_0.conda#ae2e72c47ce95ec8c489cffa0592f492 +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.10.0-cpu_generic_py313_hca44352_0.conda#4190280441d934739891072f82b02cc3 +https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.0-py313hc753a45_1.conda#5b73b1e6d191aac48960c50d65372f19 https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.305-accelerate.conda#5f941c90faaca70599ef8302d0c2738f https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py313h58042b9_0.conda#745c18472bc6d3dc9146c3dec18bb740 https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py313h28ea3aa_1.conda#51a353d043e612a8f520627cf0e73653 -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.9.1-cpu_generic_hcc7c195_3.conda#cd865dffd904fb755c5633facf59926b +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.10.0-cpu_generic_hcc7c195_0.conda#031007adf47afe42e6ef38bcfc16f15d https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py313h39782a4_0.conda#bae471007cbebf097a19e851c219d56a https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda#148516e0c9edf4e9331a4d53ae806a9b https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_7.conda#13150cdd8e6bc61aa68b55d1a2a69083 diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index 9c968f1bc40b4..70d8c5a93f3f5 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -34,7 +34,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 # pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c # pip charset-normalizer @ https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 -# pip coverage @ https://files.pythonhosted.org/packages/12/da/91a52516e9d5aea87d32d1523f9cdcf7a35a3b298e6be05d6509ba3cfab2/coverage-7.13.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=fa3edde1aa8807de1d05934982416cb3ec46d1d4d91e280bcce7cca01c507992 +# pip coverage @ https://files.pythonhosted.org/packages/8e/78/befa6640f74092b86961f957f26504c8fba3d7da57cc2ab7407391870495/coverage-7.13.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=7be4d613638d678b2b3773b8f687537b284d7074695a43fe2fbbfc0e31ceaed1 # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 # pip cython @ https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de @@ -49,12 +49,11 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip meson @ https://files.pythonhosted.org/packages/9c/d5/582789135863eec7c8c1fa31fbde401b3d5d82dbbb4a0973351a1698f738/meson-1.10.1-py3-none-any.whl#sha256=fe43d1cc2e6de146fbea78f3a062194bcc0e779efc8a0f0d7c35544dfb86731f # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip numpy @ https://files.pythonhosted.org/packages/ba/87/d341e519956273b39d8d47969dd1eaa1af740615394fe67d06f1efa68773/numpy-2.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8 -# pip packaging @ https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl#sha256=29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 +# pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 # pip pillow @ https://files.pythonhosted.org/packages/01/9a/632e58ec89a32738cabfd9ec418f0e9898a2b4719afc581f07c04a05e3c9/pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b -# pip pyparsing @ https://files.pythonhosted.org/packages/8b/40/2614036cdd416452f5bf98ec037f38a1afb17f327cb8e6b652d4729e0af8/pyparsing-3.3.1-py3-none-any.whl#sha256=023b5e7e5520ad96642e2c6db4cb683d3970bd640cdf7115049a6e9c3682df82 -# pip pytz @ https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl#sha256=5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 +# pip pyparsing @ https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl#sha256=850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d # pip roman-numerals @ https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl#sha256=647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7 # pip six @ https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl#sha256=4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 # pip snowballstemmer @ https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl#sha256=6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 @@ -65,7 +64,6 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip sphinxcontrib-qthelp @ https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl#sha256=b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb # pip sphinxcontrib-serializinghtml @ https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl#sha256=6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb -# pip tzdata @ https://files.pythonhosted.org/packages/c7/b0/003792df09decd6849a5e39c28b513c06e84436a54440380862b5aeff25d/tzdata-2025.3-py2.py3-none-any.whl#sha256=06a47e5700f3081aab02b2e513160914ff0694bce9947d6b76ebd6bf57cfc5d1 # pip urllib3 @ https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl#sha256=bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 # pip array-api-strict @ https://files.pythonhosted.org/packages/e1/7b/81bef4348db9705d829c58b9e563c78eddca24438f1ce1108d709e6eed55/array_api_strict-2.4.1-py3-none-any.whl#sha256=22198ceb47cd3d9c0534c50650d265848d0da6ff71707171215e6678ce811ca5 # pip contourpy @ https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 @@ -78,7 +76,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip lightgbm @ https://files.pythonhosted.org/packages/42/86/dabda8fbcb1b00bcfb0003c3776e8ade1aa7b413dff0a2c08f457dace22f/lightgbm-4.6.0-py3-none-manylinux_2_28_x86_64.whl#sha256=cb19b5afea55b5b61cbb2131095f50538bd608a00655f23ad5d25ae3e3bf1c8d # pip matplotlib @ https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486 # pip meson-python @ https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl#sha256=67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298 -# pip pandas @ https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac +# pip pandas @ https://files.pythonhosted.org/packages/f7/a3/51e02ebc2a14974170d51e2410dfdab58870ea9bcd37cda15bd553d24dc4/pandas-3.0.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=95683af6175d884ee89471842acfca29172a85031fccdabc35e50c0984470a0e # pip pyamg @ https://files.pythonhosted.org/packages/63/f3/c13ae1422434baeefe4d4f306a1cc77f024fe96d2abab3c212cfa1bf3ff8/pyamg-5.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=5cc223c66a7aca06fba898eb5e8ede6bb7974a9ddf7b8a98f56143c829e63631 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 450dc8568f1bb..802233c60d309 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -156,11 +156,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openbla https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -168,9 +168,9 @@ https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062 https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda#978d03388b62173b8e6f79162cf52b86 https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -178,14 +178,13 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.0-h435f46f_0.conda#c7726f96aab024855ede05e0ca6e94a0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.8.13-hd4f18eb_5.conda#860fb8c0efec64a4a678eb2ea066ff65 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.1-py311h3778330_0.conda#9d38ee59f3535da3ee59652dcef8fd96 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.2-py311h3778330_0.conda#b25c1e3463dde575d6701b8dee76d965 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 @@ -197,18 +196,19 @@ https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openb https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad +https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_1.conda#e933f92cedca212eb2916f24823cf90b -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_1.conda#e00afd65b88a3258212661b32c1469cb +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_2.conda#3c71daed530c0c26671a1b1b7010e746 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_2.conda#0ad9019bb10eda915fb0ce5f78fef13b https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 +https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index fe5f051e42d17..b3e18db04fb6f 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -69,23 +69,21 @@ https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 @@ -93,14 +91,15 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py311h2e04523_0.conda#716357afd11c16214cdac522da447704 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 +https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py311h8032f78_0.conda#78d3e3073a999e662385c9a80d84ecec +https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_0.conda#a1698614a27f4bd96815bac2ab22e1fc +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_1.conda#f4dda6316cc4718cbcab7009b5d60c41 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock index fa74a97d2b340..0e7dbab15f0c8 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock @@ -64,20 +64,20 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py311h275cad7_2.conda#e9eb24a8d111be48179bf82a9e0e13ca https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a8eebe_openblas.conda#1db756824d3aec6a25599c7821cb3e24 -https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_1.conda#2dfbc5aaac3424065eb81ec9a9f49761 +https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_2.conda#511af9070467adf0e8af89ce18d516cf https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda#6e7c5c5ab485057b5d07fd8188ba5c28 https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.3-h0c9aed9_0.conda#c2d5b6b790ef21abac0b5331094ccb56 https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hd232482_openblas.conda#78240c2b4322025a74e7e6edad247103 https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-h779ef1b_1.conda#68dc154b8d415176c07b6995bd3a65d9 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -85,9 +85,8 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py311h3485c13_0.conda#6e8d1faf5c0c08641c151e0fb79cb4db https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.0-py311h3485c13_1.conda#a30a6a70ab7754dbf0b06fe1a96af9cb -https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda#bc58fdbced45bb096364de0fba1637af -https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.1-py311h3f79411_0.conda#2bc1a645fd4c574855277c6ab0061f49 +https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.2-py311h3f79411_0.conda#7483b07166c6fad6544dab8709988180 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/win-64/lcms2-2.18-hf2c6c5f_0.conda#b6c68d6b829b044cd17a41e0a8a23ca1 @@ -96,17 +95,18 @@ https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-5_hbb0e6ff_openb https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.1-py311h80b3fa1_0.conda#387094bb33448f55432ea38cf9b62f1f https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h24db6dd_0.conda#5af852046226bb3cb15c7f61c2ac020a -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 +https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-5_ha590de0_openblas.conda#e19a49b16cf765708e6d8676a50f74e1 -https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h3fd045d_3.conda#5e7e380c470e9f4683b3129fedafbcdf +https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h275cad7_4.conda#9fb1f375c704c5287c97c60f6a88d137 https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py311h3f79411_0.conda#e5445b571c6e2919198c40c6db3d25c5 https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda#d69c21967f35eb2ce7f1f85d6b6022d3 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.0-py311h17b8079_0.conda#da30e4de83b61f936f73660eb4fa3cd5 +https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.0-py311h9c22a71_0.conda#5a37e6e0b88c9fcfd1050ded185d07a1 +https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.0-py311h9c22a71_1.conda#0d03c857517a5db3c1af5b553a528fac https://conda.anaconda.org/conda-forge/win-64/blas-2.305-openblas.conda#19bbf270f61bbef238e16a9509377a52 https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.15.0-h765892d_1.conda#9bb0026a2131b09404c59c4290c697cd https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 diff --git a/build_tools/azure/ubuntu_atlas_lock.txt b/build_tools/azure/ubuntu_atlas_lock.txt index 56a9a13757954..b16443a77e699 100644 --- a/build_tools/azure/ubuntu_atlas_lock.txt +++ b/build_tools/azure/ubuntu_atlas_lock.txt @@ -18,7 +18,7 @@ meson-python==0.19.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt ninja==1.13.0 # via -r build_tools/azure/ubuntu_atlas_requirements.txt -packaging==25.0 +packaging==26.0 # via # meson-python # pyproject-metadata diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 7cd3004e9ed90..53cf905e4e458 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -56,7 +56,7 @@ https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.cond https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.4-h3f801dc_0.conda#01ba04e414e47f95c03d6ddd81fd37be +https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.5-h088129d_0.conda#86f7414544ae606282352fa1e116b41f https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 @@ -92,7 +92,7 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee -https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_7.conda#3a29a37b34dbd06672bdccb63829ec14 +https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-ha09017c_8.conda#6e9bf4ce797d0216bd2a58298b6290b5 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 @@ -141,7 +141,7 @@ https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.14-py311hd8ed1ab_2.co https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2#961b3a227b437d82ad7054484cfa71b2 -https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc +https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-he8b2097_16.conda#d274bf1343507683e6eb2954d1871569 @@ -162,12 +162,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.c https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/narwhals-2.15.0-pyhcf101f3_0.conda#37926bb0db8b04b8b99945076e1442d0 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 @@ -178,7 +178,7 @@ https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.1-py311haee01d2_0.con https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda#7d9daffbb8d8e0af0f769dbbcd173a54 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda#23029aae904a2ba587daba708208012f https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda#a61bf9ec79426938ff785eb69dbb1960 @@ -190,10 +190,10 @@ https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda#3893f7b40738f9fe87510cb4468cdda5 https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_0.conda#645026465469ecd4989188e1c4e24953 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 -https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.2-pyhd8ed1ab_0.conda#fcbe3971b6017792e9b24ff451daa7f5 +https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda#18de09b20462742fe093ba39185d9bac https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b @@ -206,7 +206,6 @@ https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.co https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda#6639b6b0d8b5a284f027a2003669aa65 https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda#2841eb5bfc75ce15e9a0054b98dcd64d https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda#2f1ed718fcd829c184a6d4f0f2e07409 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b @@ -234,8 +233,8 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_1.conda#e933f92cedca212eb2916f24823cf90b -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_1.conda#e00afd65b88a3258212661b32c1469cb +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_2.conda#3c71daed530c0c26671a1b1b7010e746 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_2.conda#0ad9019bb10eda915fb0ce5f78fef13b https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 @@ -244,7 +243,6 @@ https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_ https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b11e360fc4de2b0035fc8aaa74f17fd6 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py311h2e04523_0.conda#716357afd11c16214cdac522da447704 https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.2-pyhd8ed1ab_0.conda#7702bcd70891dd0154d765a69e1afa94 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -252,10 +250,10 @@ https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.14-hd8ed1ab_2.cond https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 -https://conda.anaconda.org/conda-forge/noarch/roman-numerals-py-4.1.0-pyhd8ed1ab_0.conda#28687768633154993d521aecfa4a56ac https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda#17b43cee5cc84969529d5d0b0309b2cb https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.5.1-pyhcf101f3_0.conda#c0d0b883e97906f7524e2aac94be0e0d https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 +https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/noarch/anyio-4.12.1-pyhcf101f3_0.conda#11a2b8c732d215d977998ccd69a9d5e8 @@ -265,7 +263,7 @@ https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-h5f6438b_0.conda#08a03378bc5293c6f97637323802f480 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311hdf67eae_3.conda#c4e2f4d5193e55a70bb67a2aa07006ae +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311h724c32c_4.conda#d04e508f5a03162c8bab4586a65d00bf https://conda.anaconda.org/conda-forge/noarch/doit-0.36.0-pyhd8ed1ab_1.conda#18d4243b3d30352f9dea8e522f6ff4d1 https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_16.conda#dcaf539ffe75649239192101037f1406 @@ -279,11 +277,12 @@ https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0. https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda#7b8bace4943e0dc345fc45938826f2b8 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py311hed34c8f_2.conda#2366b5470cf61614c131e356efe9f74c +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py311h8032f78_0.conda#78d3e3073a999e662385c9a80d84ecec https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 +https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_0.conda#a1698614a27f4bd96815bac2ab22e1fc +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_1.conda#f4dda6316cc4718cbcab7009b5d60c41 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 @@ -314,7 +313,7 @@ https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py311h2a9 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda#f56000b36f09ab7533877e695e4e8cb0 -https://conda.anaconda.org/conda-forge/noarch/jupytext-1.18.1-pyh80e38bb_0.conda#3c85f79f1debe2d2c82ac08f1c1126e1 +https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.0-pyh0398c0e_0.conda#1831f8fcb080707636343f5e1d8994f1 https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py311he4c1a5a_0.conda#6b0c36cdc506dc560538fba50e43dd03 https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 @@ -326,7 +325,7 @@ https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.0-pyhcf101 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda#837aaf71ddf3b27acae0e7e9015eebc6 https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda#bf22cb9c439572760316ce0748af3713 -https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.6.1-pyhd8ed1ab_2.conda#3e6c15d914b03f83fc96344f917e0838 +https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.7.0-pyhd8ed1ab_0.conda#28eddfb8b9ecdd044a6f609f985398a7 https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.20.0-pyhd8ed1ab_0.conda#4cae490c8d142824fb80d9aed672fddd https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.10.1-pyhd8ed1ab_0.conda#bfc047865de18ef2657bd8a95d7b8b49 https://conda.anaconda.org/conda-forge/noarch/sphinx-remove-toctrees-1.0.0.post1-pyhd8ed1ab_1.conda#b275c865b753413caaa8548b9d44c024 @@ -334,7 +333,7 @@ https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda#910f28a05c178feba832f842155cbfff https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_1.conda#e9fb3fe8a5b758b4aff187d434f94f03 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_1.conda#00534ebcc0375929b45c3039b5ba7636 -https://conda.anaconda.org/conda-forge/noarch/sphinx-8.2.3-pyhd8ed1ab_0.conda#f7af826063ed569bb13f7207d6f949b0 +https://conda.anaconda.org/conda-forge/noarch/sphinx-9.0.4-pyhd8ed1ab_0.conda#950eae33376107d143a529d48c363832 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda#3bc61f7161d28137797e038263c04c54 https://conda.anaconda.org/conda-forge/noarch/sphinxext-opengraph-0.13.0-pyhd8ed1ab_0.conda#1a159db0a9774bd77c1ea293bcaf17b7 # pip libsass @ https://files.pythonhosted.org/packages/fd/5a/eb5b62641df0459a3291fc206cf5bd669c0feed7814dded8edef4ade8512/libsass-0.23.0-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.whl#sha256=4a218406d605f325d234e4678bd57126a66a88841cb95bee2caeafdc6f138306 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index df58c6452d0e3..4854bd27124b1 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -59,7 +59,7 @@ https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.cond https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.4-h3f801dc_0.conda#01ba04e414e47f95c03d6ddd81fd37be +https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.5-h088129d_0.conda#86f7414544ae606282352fa1e116b41f https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e @@ -102,7 +102,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hb https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee -https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-hf08fa70_7.conda#3a29a37b34dbd06672bdccb63829ec14 +https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-ha09017c_8.conda#6e9bf4ce797d0216bd2a58298b6290b5 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_3.conda#70d1de6301b58ed99fea01490a9802a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 @@ -156,11 +156,11 @@ https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -168,14 +168,14 @@ https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062 https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.1-py311haee01d2_0.conda#8cc656ea4773e02929cc58745669b116 https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda#3eeeeb9e4827ace8c0c1419c85d590ad -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 -https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.2-pyhd8ed1ab_0.conda#fcbe3971b6017792e9b24ff451daa7f5 +https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda#18de09b20462742fe093ba39185d9bac https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.2-pyhd8ed1ab_0.conda#5d99943f2ae3cc69e1ada12ce9d4d701 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f @@ -184,7 +184,6 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa @@ -209,12 +208,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.cond https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda#9f6a8664f1fe752f79473eeb9bf33a60 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 +https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_16.conda#dcaf539ffe75649239192101037f1406 @@ -223,9 +222,10 @@ https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.con https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h310e576_17.conda#94474857477981fedf74cf7c47c88ba5 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_1.conda#e933f92cedca212eb2916f24823cf90b -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_1.conda#e00afd65b88a3258212661b32c1469cb -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_2.conda#3c71daed530c0c26671a1b1b7010e746 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_2.conda#0ad9019bb10eda915fb0ce5f78fef13b +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 +https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index e12bb662f93d8..4639087c4bf08 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -112,15 +112,15 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00 https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm21-21.1.8-hfd2ba90_0.conda#de59c5148c2a8347c02e437e3ed242a0 https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h30c48ee_0.conda#48f31a61be512ec1929f4b4a9cedf4bd -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.0-py311h8e17b9e_0.conda#c771bf4d9191e68f1a09c573a9de897f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -128,7 +128,6 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.3-py311hb9158a3_0.conda#e3afe76a49a1a9f85e0c5cd42a408e68 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-aarch64/unicodedata2-17.0.0-py311h19352d5_1.conda#4a55814831e0ec9be84ccef6aed798c1 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.45.1-pyhd8ed1ab_1.conda#75cb7132eb58d97896e173ef12ac9986 https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-cursor-0.1.6-he30d5cf_0.conda#8b70063c86f7f9a0b045e78d2d9971f7 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcomposite-0.4.6-h86ecc28_2.conda#86051eee0766c3542be24844a9c3cf36 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcursor-1.2.3-h86ecc28_0.conda#f2054759c2203d12d0007005e1f1296d @@ -136,27 +135,28 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdamage-1.1.6-h86ec https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda#eeee3bdb31c6acde2b81ad1b8c287087 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.4-h86ecc28_0.conda#dd3e74283a082381aa3860312e3c721e https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.6-h86ecc28_0.conda#d745faa2d7c15092652e40a22bb261ed -https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.1-py311h2dad8b0_0.conda#a74e8e0a91d3fbbd8d5edef3ce5fca56 +https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.2-py311h2dad8b0_0.conda#f5b980d16f2bdd10fd1a6b2d902391cb https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.15.0-h8dda3cd_1.conda#112b71b6af28b47c624bcbeefeea685b https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.1-py311h164a683_0.conda#b59452fef1470e7e5c34a7c5deefe853 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_1.conda#3c89c40c8bc018db02008a0a7d1981de -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.8-default_h94a09a5_1.conda#9a517122495f4ba889cac130dd8ce267 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_2.conda#533210c236818b9042aea471585e9ea1 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.8-default_h94a09a5_2.conda#5d79d5dd604ceb8e98f007e6770c379c https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-5_hb558247_openblas.conda#8046d5ae90150f00c8b40455d9b2e180 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.1-hf8816c8_3.conda#e0d7a6cbc0b8a6d05002cb9bd061a4af https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.328.1-h8b8848b_0.conda#e5a3ff3a266b68398bd28ed1d4363e65 https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.1-py311h669026d_0.conda#e6f40fe186c60f1a6c54a8697213c5cd -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 +https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-5_h9678261_openblas.conda#33a0e650392a79b56ae0bfa3db02ddbf https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad -https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311hfca10b7_3.conda#47c305536dbf44cd3e629b6851605a50 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 +https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311h04741b4_4.conda#1eeea54b0c520a475db39f8c711de661 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 +https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.16.3-py311h399493a_2.conda#cacb6fbad878af1122e1301482fbc957 +https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.0-py311h399493a_1.conda#ea481eda36e28a2487d0fe2891d168ff https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.305-openblas.conda#2efe635198609d0d2a122c6a0923b8f8 https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-12.3.0-h1134a53_0.conda#60d635185d9c39e6c8dbd1771e6c7267 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 diff --git a/doc/modules/preprocessing.rst b/doc/modules/preprocessing.rst index 5d1bb9e1836bd..f47aeb91f46af 100644 --- a/doc/modules/preprocessing.rst +++ b/doc/modules/preprocessing.rst @@ -1064,7 +1064,7 @@ For instance, we can use the Pandas function :func:`pandas.cut`:: >>> X = np.array([0.2, 2, 15, 25, 97]) >>> transformer.fit_transform(X) ['infant', 'kid', 'teen', 'adult', 'senior citizen'] - Categories (5, object): ['infant' < 'kid' < 'teen' < 'adult' < 'senior citizen'] + Categories (5, str): ['infant' < 'kid' < 'teen' < 'adult' < 'senior citizen'] .. rubric:: Examples From e2bea55682dc1e7742122836a68dbeafdffc39d5 Mon Sep 17 00:00:00 2001 From: Unique Shrestha <112570655+un1u3@users.noreply.github.com> Date: Mon, 26 Jan 2026 19:12:28 +0545 Subject: [PATCH 153/462] Re-enable compressed cache for fetch_kddcup99 (#33118) --- .../sklearn.datasets/33118.efficiency.rst | 3 +++ sklearn/datasets/_kddcup99.py | 8 ++------ 2 files changed, 5 insertions(+), 6 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.datasets/33118.efficiency.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.datasets/33118.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.datasets/33118.efficiency.rst new file mode 100644 index 0000000000000..8518bcb840196 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.datasets/33118.efficiency.rst @@ -0,0 +1,3 @@ +- Re-enabled compressed caching for :func:`datasets.fetch_kddcup99`, reducing + on-disk cache size without changing the public API. + By :user:`Unique Shrestha `. diff --git a/sklearn/datasets/_kddcup99.py b/sklearn/datasets/_kddcup99.py index 7a8571a3686df..0cc70fc0a2f4c 100644 --- a/sklearn/datasets/_kddcup99.py +++ b/sklearn/datasets/_kddcup99.py @@ -402,12 +402,8 @@ def _fetch_brute_kddcup99( X = Xy[:, :-1] y = Xy[:, -1] - # XXX bug when compress!=0: - # (error: 'Incorrect data length while decompressing[...] the file - # could be corrupted.') - - joblib.dump(X, samples_path, compress=0) - joblib.dump(y, targets_path, compress=0) + joblib.dump(X, samples_path, compress=3) + joblib.dump(y, targets_path, compress=3) else: raise OSError("Data not found and `download_if_missing` is False") From 128c88c4b91e0fad2bcc664e4c2300804859f981 Mon Sep 17 00:00:00 2001 From: Arthur Lacote Date: Tue, 27 Jan 2026 09:56:57 +0100 Subject: [PATCH 154/462] FIX: fix boundary 0-weight edge-case in `_weighted_percentile` (#33127) Co-authored-by: Lucy Liu --- .../upcoming_changes/sklearn.utils/33127.fix.rst | 8 ++++++++ sklearn/utils/stats.py | 2 +- sklearn/utils/tests/test_stats.py | 7 +++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/33127.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/33127.fix.rst b/doc/whats_new/upcoming_changes/sklearn.utils/33127.fix.rst new file mode 100644 index 0000000000000..93beb06bfb8c1 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.utils/33127.fix.rst @@ -0,0 +1,8 @@ +- Fixed ``_weighted_percentile`` with ``average=True`` so zero-weight samples + just before the end of the array are handled correctly. This + can change results when using ``sample_weight`` with + :class:`preprocessing.KBinsDiscretizer` (``strategy="quantile"``, + ``quantile_method="averaged_inverted_cdf"``) and in + :func:`metrics.median_absolute_error`, :func:`metrics.d2_pinball_score`, and + :func:`metrics.d2_absolute_error_score`. + By :user:`Arthur Lacote `. diff --git a/sklearn/utils/stats.py b/sklearn/utils/stats.py index 71fa1418e235e..2d3a689e0e22b 100644 --- a/sklearn/utils/stats.py +++ b/sklearn/utils/stats.py @@ -192,7 +192,7 @@ def _weighted_percentile( ) # Handle case where there are trailing 0 sample weight samples # and `percentile_indices` is already max index - if next_index >= max_idx: + if next_index > max_idx: # use original `percentile_indices` again next_index = percentile_indices[col_idx] diff --git a/sklearn/utils/tests/test_stats.py b/sklearn/utils/tests/test_stats.py index 60e1c2acc0945..bdd2ba242f927 100644 --- a/sklearn/utils/tests/test_stats.py +++ b/sklearn/utils/tests/test_stats.py @@ -130,6 +130,13 @@ def test_weighted_percentile_ignores_zero_weight( assert approx(value[idx]) == expected_value +def test_weighted_percentile_average_zero_weight_plateau(): + """Check zero weights just before `max_index` handled correctly.""" + score_without_zeros = _weighted_percentile([1, 3], [3, 3], average=True) + score_with_zeros = _weighted_percentile([1, 2, 3], [3, 0, 3], average=True) + assert approx(score_without_zeros) == score_with_zeros + + @pytest.mark.parametrize("average", [True, False]) @pytest.mark.parametrize("percentile_rank", [20, 35, 50, 61]) def test_weighted_percentile_frequency_weight_semantics( From 9b4a6951cb6222a3639c3ca5a7f4a53cc96245a7 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Tue, 27 Jan 2026 10:00:18 +0100 Subject: [PATCH 155/462] MAINT Simpler array API lock file config (#33136) --- ...a_forge_cuda_array-api_linux-64_conda.lock | 62 +++++++++---------- ...ge_cuda_array-api_linux-64_environment.yml | 4 +- .../update_environments_and_lock_files.py | 5 +- 3 files changed, 32 insertions(+), 39 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index e508d51d75caa..716a3a16f73de 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 7e08eaf0616843772a915db5f428b96f6455948f620bb0ddddf349ff9b84b200 +# input_hash: 879f64b0534a118cfb4a43da8226771a8abadccd873d0a27980fc1e3b2273d45 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/cuda-version-11.8-h70ddcb2_3.conda#670f0e1593b8c1d84f57ad5fe5256799 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 @@ -8,7 +8,6 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2024.2.2-ha770c72_17.conda#c18fd07c02239a7eb744ea728db39630 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 @@ -100,6 +99,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.b https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.28.2-h5b01275_0.conda#ab0bff36363bec94720275a681af8b83 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2024.07.02-hbbce691_2.conda#b2fede24428726dd867611664fb372e8 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.21.0-h0e7cc3e_0.conda#dcb95c0a98ba9ff737f7ae482aef7833 @@ -117,6 +117,7 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb03c661_4.conda#ea https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.1.4-h7d33bf5_0.conda#93fe78190bc6fe40d5e7a737c8065286 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 @@ -124,6 +125,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.co https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.9-h04c0eec_0.conda#35eeb0a2add53b1e50218ed230fa6a02 https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 +https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.0.3-h97ab989_1.conda#2f46eae652623114e112df13fae311cf https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e @@ -147,29 +149,29 @@ https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.1.0-pyhd8ed1ab_0.conda#1daaf94a304a27ba3446a306235a37ea https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/libcudnn-dev-9.10.1.4-h0fdc2d1_0.conda#a0c0b44d26a4710e6ea577fcddbe09d1 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.67.1-hc2c308b_0.conda#4606a4647bfe857e3cfe21ca12ac3afb https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h3d81e11_1000.conda#d821210ab60be56dd27b5525ed18366d +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.conda#9ad637a7ac380c442be142dfb0b1b955 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda#74e91c36d0eef3557915c68b6c2bef96 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h7a3aeb2_0.conda#31059dc620fa57d787e3899ed0421e6d https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.0-pyhcf101f3_0.conda#58d003cc46fba78516176732d6a19ede +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 -https://conda.anaconda.org/conda-forge/noarch/packaging-25.0-pyh29332c3_1.conda#58335b26c38bf4a20f399384c33cbcf9 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py313h80991f8_0.conda#183fe6b9e99e5c2b464c1573ec78eac8 https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.1-pyhcf101f3_0.conda#d837065e4e0de4962c3462079c23f969 -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 -https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.9.0-pyhff2d567_0.conda#4de79c071274a53dcaf2a8c749d1499e +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -186,7 +188,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.7.7-hf454442_0.conda#947c82025693bebd557f782bb5d6b469 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.10.0-h113e628_0.conda#73f73f60854f325a55f1d31459f2ab73 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.8.0-h736e048_1.conda#13de36be8de3ae3f05ba127631599213 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.1-py313h3dea7bd_0.conda#82315acb438e857f809f556e2dcdb822 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.2-py313h3dea7bd_0.conda#df05169cc886aaf53dc560db634519f8 https://conda.anaconda.org/conda-forge/linux-64/cudnn-9.10.1.4-haad7af6_0.conda#8382d957333e0d3280dcbf5691516dc1 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee @@ -197,56 +199,52 @@ https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#61 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.0-default_h99862b1_1.conda#d599b346638b9216c1e8f9146713df05 https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.0-default_h746c552_1.conda#327c78a8ce710782425a89df851392f7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.32.0-h804f50b_0.conda#3d96df4d6b1c88455e05b94ce8a14a53 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 +https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.8.0-h9ddd185_2.conda#8de40c4f75d36bb00a5870f682457f1d https://conda.anaconda.org/conda-forge/linux-64/libpq-17.7-h5c52fec_1.conda#a4769024afeab4b32ac8167c2f92c7ac +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py313hf6604e3_0.conda#7d51e3bef1a4b00bde1861d85ba2f874 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.11-h4df99d1_100.conda#d1461b2e63b1909f4f5b41c823bd90ae https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-h8d10470_4.conda#e6d46d70c68d0eb69b9a040ebe3acddf https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f +https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.29.7-hd92328a_7.conda#02b95564257d5c3db9c06beccf711f95 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.13.0-h3cf044e_1.conda#7eb66060455c7a47d9dcdbfa9f46579b +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 +https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.4.1-py313hc2a895b_0.conda#46dd595e816b278b178e3bef8a6acf71 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.32.0-h0121fbd_0.conda#877a5ec0431a5af83bf0cd0522bfe661 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh613fae4_0.conda#cb08e589220418a0b894d515a406aec8 +https://conda.anaconda.org/conda-forge/linux-64/libmagma_sparse-2.8.0-h9ddd185_0.conda#f4eb3cfeaf9d91e72d5b2b8706bf059f +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha770c72_17.conda#e4ab075598123e783b788b995afbdad0 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py313hbfd7664_0.conda#ab6d05e915ab2ae4c41d275b14592151 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py313h4b8bb8b_1.conda#2b18fe5b4b2d1611ddf8c2f080a46563 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.458-hc430e4a_4.conda#aeefac461bea1f126653c1285cf5af08 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.12.0-ha633028_1.conda#7c1980f89dd41b097549782121a73490 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 +https://conda.anaconda.org/conda-forge/linux-64/cupy-13.4.1-py313h66a2ee2_0.conda#784d6bd149ef2b5d9c733ea3dd4d15ad https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-37_h5875eb1_mkl.conda#888c2ae634bce09709dffd739ba9f1bc -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2024.2.2-ha770c72_17.conda#e67269e07e58be5672f06441316f05f2 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.5.1-cuda118_hb34f2e8_303.conda#da799bf557ff6376a1a58f40bddfb293 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.1-py310hffdcd12_0.conda#732a536c6ce768f096f5340121e10cc5 +https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/libarrow-18.1.0-h44a453e_6_cpu.conda#2cf6d608d6e66506f69797d5c6944c35 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-37_hfef963f_mkl.conda#f66eb9a9396715013772b8a3ef7396be -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-37_h5e43f62_mkl.conda#0c4af651539e79160cd3f0783391e918 https://conda.anaconda.org/conda-forge/noarch/polars-1.37.1-pyh6a1acc5_0.conda#1894d4373da653406c91e20ef89f05c8 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.5.1-cuda118_py313h40cdc2d_303.conda#19ad990954a4ed89358d91d0a3e7016d https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.2-h5bd77bc_1.conda#f7bfe5b8e7641ce7d11ea10cfd9f33cc https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-18.1.0-hcb10f89_6_cpu.conda#143f9288b64759a6427563f058c62f2b -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-37_hdba1596_mkl.conda#4e76080972d13c913f178c90726b21ce -https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.8.0-h9ddd185_2.conda#8de40c4f75d36bb00a5870f682457f1d https://conda.anaconda.org/conda-forge/linux-64/libparquet-18.1.0-h081d1f1_6_cpu.conda#68788df49ce7480187eb6387f15b2b67 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py313hf6604e3_0.conda#7d51e3bef1a4b00bde1861d85ba2f874 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-18.1.0-py313he5f92c8_0_cpu.conda#5380e12f4468e891911dbbd4248b521a https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.2-py313ha3f37dd_1.conda#e2ec46ec4c607b97623e7b691ad31c54 -https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-37_hcf00494_mkl.conda#3a3a2906daecd117aad30e4d68276394 -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313h7037e92_3.conda#6186382cb34a9953bf2a18fc763dc346 -https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.4.1-py313hc2a895b_0.conda#46dd595e816b278b178e3bef8a6acf71 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.5.1-cuda126hf7c78f0_303.conda#afaf760e55725108ae78ed41198c49bb https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-18.1.0-hcb10f89_6_cpu.conda#20ca46a6bc714a6ab189d5b3f46e66d8 -https://conda.anaconda.org/conda-forge/linux-64/libmagma_sparse-2.8.0-h9ddd185_0.conda#f4eb3cfeaf9d91e72d5b2b8706bf059f -https://conda.anaconda.org/conda-forge/linux-64/pandas-2.3.3-py313h08cd8bf_2.conda#8a69ea71fdd37bfe42a28f0967dbb75a -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py313h4b8bb8b_1.conda#2b18fe5b4b2d1611ddf8c2f080a46563 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.137-mkl.conda#9deb2d32720cc73c9991dbd9e24b499e -https://conda.anaconda.org/conda-forge/linux-64/cupy-13.4.1-py313h66a2ee2_0.conda#784d6bd149ef2b5d9c733ea3dd4d15ad -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-18.1.0-h3ee7192_6_cpu.conda#aa313b3168caf98d00b3753f5ba27650 -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.5.1-cuda118_hb34f2e8_303.conda#da799bf557ff6376a1a58f40bddfb293 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 -https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-18.1.0-h3ee7192_6_cpu.conda#aa313b3168caf98d00b3753f5ba27650 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-18.1.0-py313h78bf25f_0.conda#a11d880ceedc33993c6f5c14a80ea9d3 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.5.1-cuda118_py313h40cdc2d_303.conda#19ad990954a4ed89358d91d0a3e7016d -https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.5.1-cuda126hf7c78f0_303.conda#afaf760e55725108ae78ed41198c49bb diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml index 709c8e4a5fad0..50450c7236066 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml @@ -3,12 +3,10 @@ # build_tools/update_environments_and_lock_files.py channels: - conda-forge - - pytorch - - nvidia dependencies: - python - numpy - - blas[build=mkl] + - blas - scipy - cython - joblib diff --git a/build_tools/update_environments_and_lock_files.py b/build_tools/update_environments_and_lock_files.py index 77954dee43239..02c08aa4eca85 100644 --- a/build_tools/update_environments_and_lock_files.py +++ b/build_tools/update_environments_and_lock_files.py @@ -101,7 +101,7 @@ def remove_from(alist, to_remove): "tag": "cuda", "folder": "build_tools/github", "platform": "linux-64", - "channels": ["conda-forge", "pytorch", "nvidia"], + "channels": ["conda-forge"], "conda_dependencies": common_dependencies + [ "ccache", @@ -111,9 +111,6 @@ def remove_from(alist, to_remove): "cupy", "array-api-strict", ], - "package_constraints": { - "blas": "[build=mkl]", - }, }, { "name": "pylatest_conda_forge_mkl_linux-64", From 2efd6ad77b97fbd1d5fb7889d45d4dcc09aa8b56 Mon Sep 17 00:00:00 2001 From: Levente Csibi <74991597+leweex95@users.noreply.github.com> Date: Tue, 27 Jan 2026 10:00:54 +0100 Subject: [PATCH 156/462] FIX: Fixed duplicate column error appearing with FeatureUnion polars (#32853) Co-authored-by: leweex95 Co-authored-by: Olivier Grisel --- .../sklearn.pipeline/32853.fix.rst | 1 + sklearn/pipeline.py | 2 +- sklearn/tests/test_pipeline.py | 12 ++++++---- sklearn/utils/_set_output.py | 23 +++++++++++++++---- 4 files changed, 28 insertions(+), 10 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.pipeline/32853.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.pipeline/32853.fix.rst b/doc/whats_new/upcoming_changes/sklearn.pipeline/32853.fix.rst new file mode 100644 index 0000000000000..558d2afd2838e --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.pipeline/32853.fix.rst @@ -0,0 +1 @@ +- Fixed :class:`pipeline.FeatureUnion` to properly handle column renaming when using Polars output, preventing duplicate column names. By :user:`Levente Csibi `. :pr:`32853` \ No newline at end of file diff --git a/sklearn/pipeline.py b/sklearn/pipeline.py index 32dc4dd187d84..3896beb6b70d8 100644 --- a/sklearn/pipeline.py +++ b/sklearn/pipeline.py @@ -1995,7 +1995,7 @@ def _hstack(self, Xs): adapter = _get_container_adapter("transform", self) if adapter and all(adapter.is_supported_container(X) for X in Xs): - return adapter.hstack(Xs) + return adapter.hstack(Xs, self.get_feature_names_out()) if any(sparse.issparse(f) for f in Xs): return sparse.hstack(Xs).tocsr() diff --git a/sklearn/tests/test_pipeline.py b/sklearn/tests/test_pipeline.py index 063450f50a162..6abc64b6658d5 100644 --- a/sklearn/tests/test_pipeline.py +++ b/sklearn/tests/test_pipeline.py @@ -1850,20 +1850,22 @@ def test_pipeline_set_output_integration(): assert_array_equal(feature_names_in_, log_reg_feature_names) -def test_feature_union_set_output(): +@pytest.mark.parametrize("df_library", ["pandas", "polars"]) +def test_feature_union_set_output(df_library): """Test feature union with set_output API.""" - pd = pytest.importorskip("pandas") + lib = pytest.importorskip(df_library) X, _ = load_iris(as_frame=True, return_X_y=True) X_train, X_test = train_test_split(X, random_state=0) union = FeatureUnion([("scalar", StandardScaler()), ("pca", PCA())]) - union.set_output(transform="pandas") + union.set_output(transform=df_library) union.fit(X_train) X_trans = union.transform(X_test) - assert isinstance(X_trans, pd.DataFrame) + assert isinstance(X_trans, lib.DataFrame) assert_array_equal(X_trans.columns, union.get_feature_names_out()) - assert_array_equal(X_trans.index, X_test.index) + if df_library == "pandas": + assert_array_equal(X_trans.index, X_test.index) def test_feature_union_getitem(): diff --git a/sklearn/utils/_set_output.py b/sklearn/utils/_set_output.py index 3b4fb6b546a3c..220dc69f3390d 100644 --- a/sklearn/utils/_set_output.py +++ b/sklearn/utils/_set_output.py @@ -95,7 +95,7 @@ def rename_columns(self, X, columns): Container with new names. """ - def hstack(self, Xs): + def hstack(self, Xs, feature_names=None): """Stack containers horizontally (column-wise). Parameters @@ -103,6 +103,10 @@ def hstack(self, Xs): Xs : list of containers List of containers to stack. + feature_names : array-like of str, default=None + The feature names for the stacked container. If provided, the + columns of the result will be renamed to these names. + Returns ------- stacked_Xs : container @@ -147,9 +151,12 @@ def rename_columns(self, X, columns): X.columns = columns return X - def hstack(self, Xs): + def hstack(self, Xs, feature_names=None): pd = check_library_installed("pandas") - return pd.concat(Xs, axis=1) + result = pd.concat(Xs, axis=1) + if feature_names is not None: + self.rename_columns(result, feature_names) + return result class PolarsAdapter: @@ -178,8 +185,16 @@ def rename_columns(self, X, columns): X.columns = columns return X - def hstack(self, Xs): + def hstack(self, Xs, feature_names=None): pl = check_library_installed("polars") + if feature_names is not None: + # Rename columns in each X before concat to avoid duplicates + start = 0 + for X in Xs: + n_features = X.shape[1] + names = feature_names[start : start + n_features] + self.rename_columns(X, names) + start += n_features return pl.concat(Xs, how="horizontal") From 07d060efecdcc7cccc5e505af465563659276d6e Mon Sep 17 00:00:00 2001 From: Tim Head Date: Tue, 27 Jan 2026 10:11:14 +0100 Subject: [PATCH 157/462] DOC Add statement on supported versions for array API (#33139) Co-authored-by: Lucy Liu --- doc/modules/array_api.rst | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index 03daabf933149..0c5254002f4f0 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -12,17 +12,6 @@ Scikit-learn vendors pinned copies of `array-api-compat `__ and `array-api-extra `__. -Scikit-learn's support for the array API standard requires the environment variable -`SCIPY_ARRAY_API` to be set to `1` before importing `scipy` and `scikit-learn`: - -.. prompt:: bash $ - - export SCIPY_ARRAY_API=1 - -Please note that this environment variable is intended for temporary use. -For more details, refer to SciPy's `Array API documentation -`_. - Some scikit-learn estimators that primarily rely on NumPy (as opposed to using Cython) to implement the algorithmic logic of their `fit`, `predict` or `transform` methods can be configured to accept any Array API compatible input @@ -52,6 +41,23 @@ Note that in the examples below, we use a context manager (:func:`config_context to avoid having to reset it to `False` at the end of every code snippet, so as to not affect the rest of the documentation. +Scikit-learn's support for the array API standard requires the environment variable +`SCIPY_ARRAY_API` to be set to `1` before importing `scipy` and `scikit-learn`: + +.. prompt:: bash $ + + export SCIPY_ARRAY_API=1 + +Please note that this environment variable is intended for temporary use. +For more details, refer to SciPy's `Array API documentation +`_. + +The array API functionality assumes that the latest versions of scikit-learn's dependencies are +installed. Older versions might work, but we make no promises. While array API support is marked +as experimental, backwards compatibility is not guaranteed. In particular, when a newer version +of a dependency fixes a bug we will not introduce additional code to backport the fix or +maintain compatibility with older versions. + Scikit-learn accepts :term:`array-like` inputs for all :mod:`metrics` and some estimators. When `array_api_dispatch=False`, these inputs are converted into NumPy arrays using :func:`numpy.asarray` (or :func:`numpy.array`). From 3e51c6b0a5cbeaabae1d4c1fb8cd171c20f2635b Mon Sep 17 00:00:00 2001 From: Arthur Lacote Date: Tue, 27 Jan 2026 10:24:13 +0100 Subject: [PATCH 158/462] TST: trees: run `test_min_impurity_decrease` for all criteria (#32699) Co-authored-by: Olivier Grisel --- sklearn/tree/tests/test_tree.py | 87 ++++++++++++--------------------- 1 file changed, 30 insertions(+), 57 deletions(-) diff --git a/sklearn/tree/tests/test_tree.py b/sklearn/tree/tests/test_tree.py index eafdf7febab28..beca79e3c18f8 100644 --- a/sklearn/tree/tests/test_tree.py +++ b/sklearn/tree/tests/test_tree.py @@ -829,76 +829,49 @@ def test_min_weight_fraction_leaf_with_min_samples_leaf_on_sparse_input( ) -def test_min_impurity_decrease(global_random_seed): +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") +@pytest.mark.parametrize( + "TreeEstimator, criterion", + [ + *product(REG_TREES.values(), REG_CRITERIONS), + *product(CLF_TREES.values(), CLF_CRITERIONS), + ], +) +def test_min_impurity_decrease(TreeEstimator, criterion, global_random_seed): # test if min_impurity_decrease ensure that a split is made only if # if the impurity decrease is at least that value X, y = datasets.make_classification(n_samples=100, random_state=global_random_seed) # test both DepthFirstTreeBuilder and BestFirstTreeBuilder # by setting max_leaf_nodes - for max_leaf_nodes, name in product((None, 1000), ALL_TREES.keys()): - TreeEstimator = ALL_TREES[name] - - # Check default value of min_impurity_decrease, 1e-7 - est1 = TreeEstimator(max_leaf_nodes=max_leaf_nodes, random_state=0) - # Check with explicit value of 0.05 - est2 = TreeEstimator( - max_leaf_nodes=max_leaf_nodes, min_impurity_decrease=0.05, random_state=0 - ) - # Check with a much lower value of 0.0001 - est3 = TreeEstimator( - max_leaf_nodes=max_leaf_nodes, min_impurity_decrease=0.0001, random_state=0 - ) - # Check with a much lower value of 0.1 - est4 = TreeEstimator( - max_leaf_nodes=max_leaf_nodes, min_impurity_decrease=0.1, random_state=0 - ) - - for est, expected_decrease in ( - (est1, 1e-7), - (est2, 0.05), - (est3, 0.0001), - (est4, 0.1), - ): - assert est.min_impurity_decrease <= expected_decrease, ( - "Failed, min_impurity_decrease = {0} > {1}".format( - est.min_impurity_decrease, expected_decrease - ) + for max_leaf_nodes in [None, 1000]: + for expected_decrease in [0.05, 0.0001, 0.1]: + est = TreeEstimator( + criterion=criterion, + max_leaf_nodes=max_leaf_nodes, + min_impurity_decrease=expected_decrease, + random_state=global_random_seed, ) est.fit(X, y) - for node in range(est.tree_.node_count): + tree = est.tree_ + weighted_impurity = ( + tree.impurity * tree.weighted_n_node_samples / X.shape[0] + ) + + for node in range(tree.node_count): # If current node is a not leaf node, check if the split was # justified w.r.t the min_impurity_decrease - if est.tree_.children_left[node] != TREE_LEAF: - imp_parent = est.tree_.impurity[node] - wtd_n_node = est.tree_.weighted_n_node_samples[node] + if tree.children_left[node] != TREE_LEAF: + left = tree.children_left[node] + right = tree.children_right[node] - left = est.tree_.children_left[node] - wtd_n_left = est.tree_.weighted_n_node_samples[left] - imp_left = est.tree_.impurity[left] - wtd_imp_left = wtd_n_left * imp_left - - right = est.tree_.children_right[node] - wtd_n_right = est.tree_.weighted_n_node_samples[right] - imp_right = est.tree_.impurity[right] - wtd_imp_right = wtd_n_right * imp_right - - wtd_avg_left_right_imp = wtd_imp_right + wtd_imp_left - wtd_avg_left_right_imp /= wtd_n_node - - fractional_node_weight = ( - est.tree_.weighted_n_node_samples[node] / X.shape[0] + actual_decrease = weighted_impurity[node] - ( + weighted_impurity[left] + weighted_impurity[right] ) - actual_decrease = fractional_node_weight * ( - imp_parent - wtd_avg_left_right_imp - ) - - assert actual_decrease >= expected_decrease, ( - "Failed with {0} expected min_impurity_decrease={1}".format( - actual_decrease, expected_decrease - ) - ) + # Allow a tiny slack to account for floating-point rounding errors: + assert actual_decrease > expected_decrease - 1e-10 def test_pickle(): From 686ea7c5a61cfe8917b44a7eb4994b89f0e7d6c4 Mon Sep 17 00:00:00 2001 From: Bharat Raghunathan Date: Tue, 27 Jan 2026 07:04:32 -0600 Subject: [PATCH 159/462] FEA: Add Array API support to `pairwise_distances_argmin` (#32985) --- doc/modules/array_api.rst | 1 + .../upcoming_changes/array-api/32985.feature.rst | 2 ++ sklearn/metrics/pairwise.py | 13 +++++++------ sklearn/metrics/tests/test_common.py | 2 ++ 4 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/32985.feature.rst diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index 0c5254002f4f0..4e51fd51e1dc5 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -200,6 +200,7 @@ Metrics - :func:`sklearn.metrics.pairwise.cosine_similarity` - :func:`sklearn.metrics.pairwise.cosine_distances` - :func:`sklearn.metrics.pairwise.pairwise_distances` (only supports "cosine", "euclidean", "manhattan" and "l2" metrics) +- :func:`sklearn.metrics.pairwise.pairwise_distances_argmin` - :func:`sklearn.metrics.pairwise.euclidean_distances` (see :ref:`device_support_for_float64`) - :func:`sklearn.metrics.pairwise.laplacian_kernel` - :func:`sklearn.metrics.pairwise.linear_kernel` diff --git a/doc/whats_new/upcoming_changes/array-api/32985.feature.rst b/doc/whats_new/upcoming_changes/array-api/32985.feature.rst new file mode 100644 index 0000000000000..18846bce3def0 --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/32985.feature.rst @@ -0,0 +1,2 @@ +- :func:`sklearn.metrics.pairwise.pairwise_distances_argmin` now supports array API + compatible inputs. By :user:`Bharat Raghunathan `. diff --git a/sklearn/metrics/pairwise.py b/sklearn/metrics/pairwise.py index 79b1c81b9129f..bdc338d3d0948 100644 --- a/sklearn/metrics/pairwise.py +++ b/sklearn/metrics/pairwise.py @@ -650,7 +650,8 @@ def _argmin_reduce(dist, start): # `start` is specified in the signature but not used. This is because the higher # order `pairwise_distances_chunked` function needs reduction functions that are # passed as argument to have a two arguments signature. - return dist.argmin(axis=1) + xp, _ = get_namespace(dist) + return xp.argmin(dist, axis=1) _VALID_METRICS = [ @@ -937,6 +938,7 @@ def pairwise_distances_argmin(X, Y, *, axis=1, metric="euclidean", metric_kwargs """ ensure_all_finite = "allow-nan" if metric == "nan_euclidean" else True X, Y = check_pairwise_arrays(X, Y, ensure_all_finite=ensure_all_finite) + xp, _ = get_namespace(X, Y) if axis == 0: X, Y = Y, X @@ -944,7 +946,7 @@ def pairwise_distances_argmin(X, Y, *, axis=1, metric="euclidean", metric_kwargs if metric_kwargs is None: metric_kwargs = {} - if ArgKmin.is_usable_for(X, Y, metric): + if ArgKmin.is_usable_for(X, Y, metric) and _is_numpy_namespace(xp): # This is an adaptor for one "sqeuclidean" specification. # For this backend, we can directly use "sqeuclidean". if metric_kwargs.get("squared", False) and metric == "euclidean": @@ -972,14 +974,13 @@ def pairwise_distances_argmin(X, Y, *, axis=1, metric="euclidean", metric_kwargs # Turn off check for finiteness because this is costly and because arrays # have already been validated. with config_context(assume_finite=True): - indices = np.concatenate( + indices = xp.concat( list( - # This returns an np.ndarray generator whose arrays we need - # to flatten into one. pairwise_distances_chunked( X, Y, reduce_func=_argmin_reduce, metric=metric, **metric_kwargs ) - ) + ), + axis=0, ) return indices diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 0b7d8b474cec1..d0406c507cf9b 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -74,6 +74,7 @@ paired_euclidean_distances, paired_manhattan_distances, pairwise_distances, + pairwise_distances_argmin, pairwise_kernels, polynomial_kernel, rbf_kernel, @@ -2454,6 +2455,7 @@ def check_array_api_metric_pairwise(metric, array_namespace, device, dtype_name) check_array_api_binary_classification_metric, ], pairwise_distances: [check_array_api_metric_pairwise], + pairwise_distances_argmin: [check_array_api_metric_pairwise], } From 66d314a68b10ac63c38cb6ea9ed8aa1ce29f555a Mon Sep 17 00:00:00 2001 From: Arthur Lacote Date: Tue, 27 Jan 2026 14:53:56 +0100 Subject: [PATCH 160/462] TST: Decision trees: add test for split optimality (#32193) Co-authored-by: Olivier Grisel Co-authored-by: Omar Salman --- .../sklearn.tree/32193.fix.rst | 9 + sklearn/tree/_classes.py | 3 +- sklearn/tree/_utils.pyx | 21 -- sklearn/tree/tests/test_split.py | 243 ++++++++++++++++++ 4 files changed, 253 insertions(+), 23 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/32193.fix.rst create mode 100644 sklearn/tree/tests/test_split.py diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/32193.fix.rst b/doc/whats_new/upcoming_changes/sklearn.tree/32193.fix.rst new file mode 100644 index 0000000000000..6c4b3d4421e21 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.tree/32193.fix.rst @@ -0,0 +1,9 @@ +- Fixed feature-wise NaN detection in trees. + Features could be seen as NaN-free for some edge-case patterns, which led to + not considering splits with NaNs assigned to the left node for those features. + This affects: + - :class:`tree.DecisionTreeRegressor` + - :class:`tree.ExtraTreeRegressor` + - :class:`ensemble.RandomForestRegressor` + - :class:`ensemble.ExtraTreesRegressor` + By :user:`Arthur Lacote ` diff --git a/sklearn/tree/_classes.py b/sklearn/tree/_classes.py index 98936fa5760fd..dc83aa7d3daea 100644 --- a/sklearn/tree/_classes.py +++ b/sklearn/tree/_classes.py @@ -35,7 +35,6 @@ _build_pruned_tree_ccp, ccp_pruning_path, ) -from sklearn.tree._utils import _any_isnan_axis0 from sklearn.utils import ( Bunch, check_random_state, @@ -228,7 +227,7 @@ def _compute_missing_values_in_feature_mask(self, X, estimator_name=None): if not np.isnan(overall_sum): return None - missing_values_in_feature_mask = _any_isnan_axis0(X) + missing_values_in_feature_mask = np.isnan(X.sum(axis=0)) return missing_values_in_feature_mask def _fit( diff --git a/sklearn/tree/_utils.pyx b/sklearn/tree/_utils.pyx index 695a86e9a8f68..af60cdb44a975 100644 --- a/sklearn/tree/_utils.pyx +++ b/sklearn/tree/_utils.pyx @@ -4,10 +4,8 @@ from libc.stdlib cimport free from libc.stdlib cimport realloc from libc.math cimport log as ln -from libc.math cimport isnan from libc.string cimport memset -import numpy as np cimport numpy as cnp cnp.import_array() @@ -67,25 +65,6 @@ cdef inline float64_t log(float64_t x) noexcept nogil: return ln(x) / ln(2.0) -def _any_isnan_axis0(const float32_t[:, :] X): - """Same as np.any(np.isnan(X), axis=0)""" - cdef: - intp_t i, j - intp_t n_samples = X.shape[0] - intp_t n_features = X.shape[1] - uint8_t[::1] isnan_out = np.zeros(X.shape[1], dtype=np.bool_) - - with nogil: - for i in range(n_samples): - for j in range(n_features): - if isnan_out[j]: - continue - if isnan(X[i, j]): - isnan_out[j] = True - break - return np.asarray(isnan_out) - - cdef class WeightedFenwickTree: """ Fenwick tree (Binary Indexed Tree) specialized for maintaining: diff --git a/sklearn/tree/tests/test_split.py b/sklearn/tree/tests/test_split.py new file mode 100644 index 0000000000000..ab1e80a2b6dd9 --- /dev/null +++ b/sklearn/tree/tests/test_split.py @@ -0,0 +1,243 @@ +from dataclasses import dataclass +from itertools import product +from operator import itemgetter + +import numpy as np +import pytest +from numpy.testing import assert_allclose +from scipy.sparse import csc_array +from scipy.special import xlogy + +from sklearn.metrics import mean_poisson_deviance +from sklearn.tree import ( + DecisionTreeClassifier, + DecisionTreeRegressor, + ExtraTreeClassifier, + ExtraTreeRegressor, +) +from sklearn.utils.stats import _weighted_percentile + +CLF_CRITERIONS = ("gini", "log_loss") + +REG_CRITERIONS = ("squared_error", "absolute_error", "poisson") + +CLF_TREES = { + "DecisionTreeClassifier": DecisionTreeClassifier, + "ExtraTreeClassifier": ExtraTreeClassifier, +} + +REG_TREES = { + "DecisionTreeRegressor": DecisionTreeRegressor, + "ExtraTreeRegressor": ExtraTreeRegressor, +} + + +@dataclass +class NaiveSplitter: + criterion: str + n_classes: int = 0 + + def compute_node_value_and_impurity(self, y, w): + sum_weights = np.sum(w) + if sum_weights < 1e-7: + return np.nan, np.inf # invalid split + if self.criterion in ["gini", "entropy", "log_loss"]: + pred = np.bincount(y, weights=w, minlength=self.n_classes) / sum_weights + if self.criterion == "gini": + # 1 - sum(pk^2) + loss = 1.0 - np.sum(pred**2) + else: + # -sum(pk * log2(pk)) + loss = -np.sum(xlogy(pred, pred)) / np.log(2) + elif self.criterion == "squared_error": + pred = np.average(y, weights=w) + loss = np.average((y - pred) ** 2, weights=w) + elif self.criterion == "absolute_error": + pred = _weighted_percentile(y, w, percentile_rank=50, average=True) + loss = np.average(np.abs(y - pred), weights=w) + elif self.criterion == "poisson": + pred = np.average(y, weights=w) + loss = mean_poisson_deviance(y, np.repeat(pred, y.size), sample_weight=w) + loss *= 1 / 2 + else: + raise ValueError(f"Unknown criterion: {self.criterion}") + return pred, loss * sum_weights + + def compute_split_nodes(self, X, y, w, feature, threshold=None, missing_left=False): + x = X[:, feature] + go_left = x <= threshold + if missing_left: + go_left |= np.isnan(x) + return ( + self.compute_node_value_and_impurity(y[go_left], w[go_left]), + self.compute_node_value_and_impurity(y[~go_left], w[~go_left]), + ) + + def compute_split_impurity( + self, X, y, w, feature, threshold=None, missing_left=False + ): + nodes = self.compute_split_nodes(X, y, w, feature, threshold, missing_left) + (_, left_impurity), (_, right_impurity) = nodes + return left_impurity + right_impurity + + def _generate_all_splits(self, X): + for f in range(X.shape[1]): + x = X[:, f] + nan_mask = np.isnan(x) + thresholds = np.unique(x[~nan_mask]) + for th in thresholds: + yield { + "feature": f, + "threshold": th, + "missing_left": False, + } + if not nan_mask.any(): + continue + for th in [*thresholds, -np.inf]: + # include -inf to test the split with only NaNs on the left node + yield { + "feature": f, + "threshold": th, + "missing_left": True, + } + + def best_split_naive(self, X, y, w): + splits = list(self._generate_all_splits(X)) + if len(splits) == 0: + return (np.inf, None) + + split_impurities = [ + self.compute_split_impurity(X, y, w, **split) for split in splits + ] + + return min(zip(split_impurities, splits), key=itemgetter(0)) + + +def make_simple_dataset( + n, + d, + with_nans, + is_sparse, + is_clf, + n_classes, + rng, +): + X_dense = rng.random((n, d)) + y = rng.random(n) + X_dense.sum(axis=1) + w = rng.integers(0, 5, size=n) if rng.uniform() < 0.5 else rng.random(n) + + with_duplicates = rng.integers(2) == 0 + if with_duplicates: + X_dense = X_dense.round(1 if n < 50 else 2) + if with_nans: + nan_density = rng.uniform(0.05, 0.8) + mask = rng.random(X_dense.shape) < nan_density + X_dense[mask] = np.nan + if is_sparse: + density = rng.uniform(0.05, 0.99) + X_dense -= 0.5 + mask = rng.random(X_dense.shape) > density + X_dense[mask] = 0 + X = csc_array(X_dense) + else: + X = X_dense + + if is_clf: + q = np.linspace(0, 1, num=n_classes + 1)[1:-1] + y = np.searchsorted(np.quantile(y, q), y) + + # Trees cast X to float32 internally; match that dtype here to avoid + # routing/impurity mismatches from rounding with `<=`. + return X_dense.astype("float32"), X, y, w + + +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") +@pytest.mark.parametrize( + "Tree, criterion", + [ + *product(REG_TREES.values(), REG_CRITERIONS), + *product(CLF_TREES.values(), CLF_CRITERIONS), + ], +) +@pytest.mark.parametrize( + "sparse, missing_values", + [(False, False), (True, False), (False, True)], + ids=["dense-without_missing", "sparse-without_missing", "dense-with_missing"], +) +def test_split_impurity(Tree, criterion, sparse, missing_values, global_random_seed): + is_clf = criterion in CLF_CRITERIONS + + # TODO: (remove in PR #32119) + if missing_values and criterion == "absolute_error": + pytest.skip("AE + missing values not supported yet") + if missing_values and criterion == "poisson": + pytest.xfail("Poisson criterion is faulty for now") + rng = np.random.default_rng(global_random_seed) + + ns = [5] * 5 + [10] * 5 + [20, 30, 50, 100] + + for it, n in enumerate(ns): + d = rng.integers(1, 4) + n_classes = rng.integers(2, 5) # only used for classification + X_dense, X, y, w = make_simple_dataset( + n, d, missing_values, sparse, is_clf, n_classes, rng + ) + + naive_splitter = NaiveSplitter(criterion, n_classes) + + tree = Tree( + criterion=criterion, + max_depth=1, + random_state=global_random_seed, + ) + tree.fit(X, y, sample_weight=w) + actual_impurity = tree.tree_.impurity * tree.tree_.weighted_n_node_samples + actual_value = tree.tree_.value[:, 0] + + # Check root's impurity: + # The root is 0, left child is 1 and right child is 2. + root_val, root_impurity = naive_splitter.compute_node_value_and_impurity(y, w) + assert_allclose(root_impurity, actual_impurity[0], atol=1e-12) + assert_allclose(root_val, actual_value[0], atol=1e-12) + + if tree.tree_.node_count == 1: + # if no splits was made assert that either: + assert ( + "Extra" in Tree.__name__ + or root_impurity < 1e-12 # root impurity is 0 + # or no valid split can be made: + or naive_splitter.best_split_naive(X_dense, y, w)[0] == np.inf + ) + continue + + # Check children impurity: + actual_split = { + "feature": int(tree.tree_.feature[0]), + "threshold": tree.tree_.threshold[0], + "missing_left": bool(tree.tree_.missing_go_to_left[0]), + } + nodes = naive_splitter.compute_split_nodes(X_dense, y, w, **actual_split) + (left_val, left_impurity), (right_val, right_impurity) = nodes + assert_allclose(left_impurity, actual_impurity[1], atol=1e-12) + assert_allclose(right_impurity, actual_impurity[2], atol=1e-12) + assert_allclose(left_val, actual_value[1], atol=1e-12) + assert_allclose(right_val, actual_value[2], atol=1e-12) + + if "Extra" in Tree.__name__: + # The remainder of the test checks for optimality of the found split. + # However, randomized trees are not guaranteed to find an optimal split + # but only a "better-than-nothing" split. + # Therefore, end the test here for these models. + continue + + # Check that the selected split has the same impurity as the best split + # found by the naive splitter. Note that there could exist multiple splits + # with the same optimal impurity, so the assertion is made on the impurity + # value: the split value is only displayed to help debugging in case + # of assertion failure. + best_impurity, best_split = naive_splitter.best_split_naive(X_dense, y, w) + actual_split_impurity = actual_impurity[1:].sum() + assert np.isclose(best_impurity, actual_split_impurity), ( + best_split, + actual_split, + ) From 7fbe0c256679c635e55be0deeb6c833207149d41 Mon Sep 17 00:00:00 2001 From: Auguste Baum <52001167+augustebaum@users.noreply.github.com> Date: Tue, 27 Jan 2026 13:55:01 +0000 Subject: [PATCH 161/462] CI Port `free-threaded` job from Azure to GHA (#33116) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- .github/workflows/unit-tests.yml | 15 ++++++++++++++- azure-pipelines.yml | 23 ----------------------- sklearn/ensemble/tests/test_bagging.py | 3 +++ 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index f92d242b29cfc..4e91ddbda7647 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -212,7 +212,7 @@ jobs: env: ${{ matrix }} - steps: + steps: &unit-tests-steps - name: Checkout uses: actions/checkout@v6 @@ -281,3 +281,16 @@ jobs: --junit-file $TEST_DIR/$JUNITXML \ --auto-close false \ --job-name "${{ matrix.name }}" + + free-threaded: + name: Linux x86-64 pylatest_free_threaded + runs-on: ubuntu-latest + needs: [lint, retrieve-commit-message, retrieve-selected-tests] + if: ${{ contains(needs.retrieve-commit-message.outputs.message, '[free-threaded]') }} + env: + DISTRIB: conda-free-threaded + LOCK_FILE: ./build_tools/azure/pylatest_free_threaded_linux-64_conda.lock + COVERAGE: false + # Disable pytest-xdist to use multiple cores for stress-testing with pytest-run-parallel + PYTEST_XDIST_VERSION: none + steps: *unit-tests-steps diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 31f797dbde270..359f5f5c46879 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -67,29 +67,6 @@ jobs: SKLEARN_WARNINGS_AS_ERRORS: '1' CHECK_PYTEST_SOFT_DEPENDENCY: 'true' -- template: build_tools/azure/posix.yml - # CPython free-threaded build - parameters: - name: Linux_free_threaded - vmImage: ubuntu-22.04 - dependsOn: [git_commit, linting] - condition: | - and( - succeeded(), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[ci skip]')), - or(eq(variables['Build.Reason'], 'Schedule'), - contains(dependencies['git_commit']['outputs']['commit.message'], '[free-threaded]' - ) - ) - ) - matrix: - pylatest_free_threaded: - DISTRIB: 'conda-free-threaded' - LOCK_FILE: './build_tools/azure/pylatest_free_threaded_linux-64_conda.lock' - COVERAGE: 'false' - # Disable pytest-xdist to use multiple cores for stress-testing with pytest-run-parallel - PYTEST_XDIST_VERSION: 'none' - # Will run all the time regardless of linting outcome. - template: build_tools/azure/posix.yml parameters: diff --git a/sklearn/ensemble/tests/test_bagging.py b/sklearn/ensemble/tests/test_bagging.py index 05789ff63d0e8..b57b294ee0366 100644 --- a/sklearn/ensemble/tests/test_bagging.py +++ b/sklearn/ensemble/tests/test_bagging.py @@ -463,6 +463,9 @@ def test_error(): assert not hasattr(BaggingClassifier(base).fit(X, y), "decision_function") +# TODO: remove mark once loky bug is fixed: +# https://github.com/joblib/loky/issues/458 +@pytest.mark.thread_unsafe def test_parallel_classification(): # Check parallel classification. X_train, X_test, y_train, y_test = train_test_split( From 62b08044bf7d4d8e96b439247c6d8d6ea0445496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Wed, 28 Jan 2026 10:43:09 +0100 Subject: [PATCH 162/462] CI Run free-threaded build on schedule (#33147) --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 4e91ddbda7647..a235ec55e1d3c 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -286,7 +286,7 @@ jobs: name: Linux x86-64 pylatest_free_threaded runs-on: ubuntu-latest needs: [lint, retrieve-commit-message, retrieve-selected-tests] - if: ${{ contains(needs.retrieve-commit-message.outputs.message, '[free-threaded]') }} + if: contains(needs.retrieve-commit-message.outputs.message, '[free-threaded]') || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' env: DISTRIB: conda-free-threaded LOCK_FILE: ./build_tools/azure/pylatest_free_threaded_linux-64_conda.lock From be7ec615c1da54caf8603d9f8d34792c4e10b055 Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Wed, 28 Jan 2026 11:51:01 +0100 Subject: [PATCH 163/462] ENH Add zero division handling to cohen_kappa_score (#31172) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Virgil Chan Co-authored-by: Adrin Jalali Co-authored-by: Jérémie du Boisberranger --- .../sklearn.metrics/31172.enhancement.rst | 4 ++ sklearn/metrics/_classification.py | 61 ++++++++++++++++-- sklearn/metrics/tests/test_classification.py | 62 +++++++++++++++++++ 3 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/31172.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/31172.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/31172.enhancement.rst new file mode 100644 index 0000000000000..426a467226bc9 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.metrics/31172.enhancement.rst @@ -0,0 +1,4 @@ +- :func:`~metrics.cohen_kappa_score` now has a `replace_undefined_by` param, that can be + set to define the function's return value when the metric is undefined (division by + zero). + By :user:`Stefanie Senger ` diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 01d8b93a510d7..894f291eaa4e7 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -883,10 +883,22 @@ def multilabel_confusion_matrix( "labels": ["array-like", None], "weights": [StrOptions({"linear", "quadratic"}), None], "sample_weight": ["array-like", None], + "replace_undefined_by": [ + Interval(Real, -1.0, 1.0, closed="both"), + np.nan, + ], }, prefer_skip_nested_validation=True, ) -def cohen_kappa_score(y1, y2, *, labels=None, weights=None, sample_weight=None): +def cohen_kappa_score( + y1, + y2, + *, + labels=None, + weights=None, + sample_weight=None, + replace_undefined_by=np.nan, +): r"""Compute Cohen's kappa: a statistic that measures inter-annotator agreement. This function computes Cohen's kappa [1]_, a score that expresses the level @@ -927,11 +939,25 @@ class labels [2]_. sample_weight : array-like of shape (n_samples,), default=None Sample weights. + replace_undefined_by : np.nan, float in [-1.0, 1.0], default=np.nan + Sets the return value when the metric is undefined. This can happen when no + label of interest (as defined in the `labels` param) is assigned by the second + annotator, or when both `y1` and `y2`only have one label in common that is also + in `labels`. In these cases, an + :class:`~sklearn.exceptions.UndefinedMetricWarning` is raised. Can take the + following values: + + - `np.nan` to return `np.nan` + - a floating point value in the range of [-1.0, 1.0] to return a specific value + + .. versionadded:: 1.9 + Returns ------- kappa : float - The kappa statistic, which is a number between -1 and 1. The maximum - value means complete agreement; zero or lower means chance agreement. + The kappa statistic, which is a number between -1.0 and 1.0. The maximum value + means complete agreement; the minimum value means complete disagreement; 0.0 + indicates no agreement beyond what would be expected by chance. References ---------- @@ -974,7 +1000,20 @@ class labels [2]_. confusion = xp.astype(confusion, max_float_dtype, copy=False) sum0 = xp.sum(confusion, axis=0) sum1 = xp.sum(confusion, axis=1) - expected = xp.linalg.outer(sum0, sum1) / xp.sum(sum0) + + numerator = xp.linalg.outer(sum0, sum1) + denominator = xp.sum(sum0) + msg_zero_division = ( + "`y2` contains no labels that are present in both `y1` and `labels`." + "`cohen_kappa_score` is undefined and set to the value defined by " + f"the `replace_undefined_by` param, which is set to {replace_undefined_by}." + ) + # exact equality is safe here, since denominator is a sum of positive terms: + if denominator == 0: + warnings.warn(msg_zero_division, UndefinedMetricWarning, stacklevel=2) + return replace_undefined_by + + expected = numerator / denominator if weights is None: w_mat = xp.ones([n_classes, n_classes], dtype=max_float_dtype, device=device_) @@ -987,7 +1026,19 @@ class labels [2]_. else: w_mat = (w_mat - w_mat.T) ** 2 - k = xp.sum(w_mat * confusion) / xp.sum(w_mat * expected) + numerator = xp.sum(w_mat * confusion) + denominator = xp.sum(w_mat * expected) + msg_zero_division = ( + "`y1`, `y2` and `labels` have only one label in common. " + "`cohen_kappa_score` is undefined and set to the value defined by the " + f"the `replace_undefined_by` param, which is set to {replace_undefined_by}." + ) + # exact equality is safe here, since denominator is a sum of positive terms: + if denominator == 0: + warnings.warn(msg_zero_division, UndefinedMetricWarning, stacklevel=2) + return replace_undefined_by + + k = numerator / denominator return float(1 - k) diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index eb267ccf5e696..9a42b8a5acaf4 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -895,6 +895,68 @@ def test_cohen_kappa(): ) +@ignore_warnings(category=UndefinedMetricWarning) +@pytest.mark.parametrize( + "test_case", + [ + # annotator y2 does not assign any label specified in `labels` (note: also + # applicable if `labels` is default and `y2` does not contain any label that is + # in `y1`): + ([1] * 5 + [2] * 5, [3] * 10, [1, 2], None), + # both inputs (`y1` and `y2`) only have one label: + ([3] * 10, [3] * 10, None, None), + # both inputs only have one label in common that is also in `labels`: + ([1] * 5 + [2] * 5, [1] * 5 + [3] * 5, [1, 2], None), + # like the last test case, but with `weights="linear"` (note that + # weights="linear" and weights="quadratic" are different branches, though the + # latter is so similar to the former that the test case is skipped here): + ([1] * 5 + [2] * 5, [1] * 5 + [3] * 5, [1, 2], "linear"), + ], +) +@pytest.mark.parametrize("replace_undefined_by", [0.0, np.nan]) +def test_cohen_kappa_undefined(test_case, replace_undefined_by): + """Test that cohen_kappa_score handles divisions by 0 correctly by returning the + `replace_undefined_by` param. (The first test case covers the first possible + location in the function for an occurrence of a division by zero, the last three + test cases cover a zero division in the the second possible location in the + function.""" + + y1, y2, labels, weights = test_case + y1, y2 = np.array(y1), np.array(y2) + + score = cohen_kappa_score( + y1, + y2, + labels=labels, + weights=weights, + replace_undefined_by=replace_undefined_by, + ) + assert_allclose(score, replace_undefined_by, equal_nan=True) + + +def test_cohen_kappa_zero_division_warning(): + """Test that cohen_kappa_score raises UndefinedMetricWarning when a division by 0 + occurs.""" + + labels = [1, 2] + y1 = np.array([1] * 5 + [2] * 5) + y2 = np.array([3] * 10) + with pytest.warns( + UndefinedMetricWarning, + match="`y2` contains no labels that are present in both `y1` and `labels`.", + ): + cohen_kappa_score(y1, y2, labels=labels) + + labels = [1, 2] + y1 = np.array([1] * 5 + [2] * 5) + y2 = np.array([1] * 5 + [3] * 5) + with pytest.warns( + UndefinedMetricWarning, + match="`y1`, `y2` and `labels` have only one label in common.", + ): + cohen_kappa_score(y1, y2, labels=labels) + + def test_cohen_kappa_score_error_wrong_label(): """Test that correct error is raised when users pass labels that are not in y1.""" labels = [1, 2] From e1fcf673a81460357cc92884da83f94d736377fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:19:02 +0100 Subject: [PATCH 164/462] CI Migrate Linux_Nightly build to GHA (#33123) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivier Grisel Co-authored-by: Loïc Estève --- .github/workflows/unit-tests.yml | 14 +++++++++++++- azure-pipelines.yml | 22 ---------------------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index a235ec55e1d3c..9426aa4060eb7 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -289,8 +289,20 @@ jobs: if: contains(needs.retrieve-commit-message.outputs.message, '[free-threaded]') || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' env: DISTRIB: conda-free-threaded - LOCK_FILE: ./build_tools/azure/pylatest_free_threaded_linux-64_conda.lock + LOCK_FILE: build_tools/azure/pylatest_free_threaded_linux-64_conda.lock COVERAGE: false # Disable pytest-xdist to use multiple cores for stress-testing with pytest-run-parallel PYTEST_XDIST_VERSION: none steps: *unit-tests-steps + + scipy-dev: + name: Linux x86-64 pylatest_pip_scipy_dev + runs-on: ubuntu-22.04 + needs: [lint, retrieve-commit-message, retrieve-selected-tests] + if: contains(needs.retrieve-commit-message.outputs.message, '[scipy-dev]') || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + env: + DISTRIB: conda-pip-scipy-dev + LOCK_FILE: build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock + SKLEARN_WARNINGS_AS_ERRORS: 1 + CHECK_PYTEST_SOFT_DEPENDENCY: true + steps: *unit-tests-steps diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 359f5f5c46879..98f9c9760a026 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -45,28 +45,6 @@ jobs: python build_tools/check-meson-openmp-dependencies.py displayName: Run Meson OpenMP checks - -- template: build_tools/azure/posix.yml - parameters: - name: Linux_Nightly - vmImage: ubuntu-22.04 - dependsOn: [git_commit, linting] - condition: | - and( - succeeded(), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[ci skip]')), - or(eq(variables['Build.Reason'], 'Schedule'), - contains(dependencies['git_commit']['outputs']['commit.message'], '[scipy-dev]' - ) - ) - ) - matrix: - pylatest_pip_scipy_dev: - DISTRIB: 'conda-pip-scipy-dev' - LOCK_FILE: './build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock' - SKLEARN_WARNINGS_AS_ERRORS: '1' - CHECK_PYTEST_SOFT_DEPENDENCY: 'true' - # Will run all the time regardless of linting outcome. - template: build_tools/azure/posix.yml parameters: From 5cbb0bd3f57c3e4737f9f2fc936c6bacc8625bf6 Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Wed, 28 Jan 2026 15:35:36 +0100 Subject: [PATCH 165/462] DOC fix typos in `plot_confusion_matrix.py` (#33141) --- .../model_selection/plot_confusion_matrix.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/model_selection/plot_confusion_matrix.py b/examples/model_selection/plot_confusion_matrix.py index 71ee654c5f5fb..d9df933e30b53 100644 --- a/examples/model_selection/plot_confusion_matrix.py +++ b/examples/model_selection/plot_confusion_matrix.py @@ -74,12 +74,12 @@ # Binary Classification # ===================== # -# For binary problems, :func:`sklearn.metrics.confusion_matrix` has the `ravel` method -# we can use get counts of true negatives, false positives, false negatives and -# true positives. +# For binary classification, use :func:`sklearn.metrics.confusion_matrix` with +# the `ravel` method to get counts of true negatives, false positives, false +# negatives, and true positives. # -# To obtain true negatives, false positives, false negatives and true -# positives counts at different thresholds, one can use +# To obtain counts of true negatives, false positives, false negatives, and true +# positives at different thresholds, one can use # :func:`sklearn.metrics.confusion_matrix_at_thresholds`. # This is fundamental for binary classification # metrics like :func:`~sklearn.metrics.roc_auc_score` and @@ -106,15 +106,15 @@ y_score = classifier.predict_proba(X_test)[:, 1] -tns, fps, fns, tps, threshold = confusion_matrix_at_thresholds(y_test, y_score) +tns, fps, fns, tps, thresholds = confusion_matrix_at_thresholds(y_test, y_score) # Plot TNs, FPs, FNs and TPs vs Thresholds plt.figure(figsize=(10, 6)) -plt.plot(threshold, tns, label="True Negatives (TNs)") -plt.plot(threshold, fps, label="False Positives (FPs)") -plt.plot(threshold, fns, label="False Negatives (FNs)") -plt.plot(threshold, tps, label="True Positives (TPs)") +plt.plot(thresholds, tns, label="True Negatives (TNs)") +plt.plot(thresholds, fps, label="False Positives (FPs)") +plt.plot(thresholds, fns, label="False Negatives (FNs)") +plt.plot(thresholds, tps, label="True Positives (TPs)") plt.xlabel("Thresholds") plt.ylabel("Count") plt.title("TNs, FPs, FNs and TPs vs Thresholds") From 3d936d512428f77d7f2bd65815b66549e93dcbb3 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Wed, 28 Jan 2026 16:31:11 +0100 Subject: [PATCH 166/462] Improve contribution guidelines to make it easier for maintainers to assess the user facing value of issues/PRs (#33140) Co-authored-by: Tim Head Co-authored-by: Anne Beyer --- .github/ISSUE_TEMPLATE/bug_report.yml | 20 ++++++++-- doc/developers/contributing.rst | 57 +++++++++++++++++++-------- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index bc8e5b5ff70d1..5ee5ad58b1889 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -10,9 +10,11 @@ body: addressed by searching through [the past issues](https://github.com/scikit-learn/scikit-learn/issues). - type: textarea attributes: - label: Describe the bug + label: Describe the bug and give evidence about its user-facing impact description: > - A clear and concise description of what the bug is. + A clear and concise description of what the bug is and **how it affects you as a scikit-learn user**. Please give a few details about the context of the discovery, why you care about getting it fixed. Please do not create issues for problems you don't actually care about. + + The scikit-learn issue tracker is swamped by reports and pull-requests. Stating the expected user impact is critical to help maintainers and other contributors focus time and effort to review meaningful contributions. validations: required: true - type: textarea @@ -36,13 +38,15 @@ body: model = lda_model.fit(lda_features) ``` + If possible, craft a reproducer that only uses the public scikit-learn API or justify why you had to use some private API to trigger the problem. This helps us assess the user-facing impact of the bug. + If the code is too long, feel free to put it in a public gist and link it in the issue: https://gist.github.com. - In short, **we are going to copy-paste your code** to run it and we expect to get the same result as you. + In short, **we need to be able to quickly copy-paste your code** to run it without modification and we expect to get the same result as you. We acknowledge that crafting a [minimal reproducible code example](https://scikit-learn.org/dev/developers/minimal_reproducer.html) requires some effort on your side but it really helps the maintainers quickly reproduce the problem and analyze its cause without any ambiguity. Ambiguous bug reports tend to be slower to fix because they will require more effort and back and forth discussion between the maintainers and the reporter to pin-point the precise conditions necessary to reproduce the problem. placeholder: | - ``` + ```python Sample code to reproduce the problem ``` validations: @@ -89,6 +93,14 @@ body: ``` validations: required: true +- type: textarea + attributes: + label: Interest in fixing the bug + description: > + If your issue is triaged by project maintainers as a bug that can be reproduced, would you be interested in working on a PR to resolve it? + And if you already have an idea, please explain your analysis of the root cause of the bug and a strategy for a possible fix, but please do not open a PR as long as the issue has not been triaged. + validations: + required: true - type: markdown attributes: value: > diff --git a/doc/developers/contributing.rst b/doc/developers/contributing.rst index 20017f7d3746e..56ed850fbc3e7 100644 --- a/doc/developers/contributing.rst +++ b/doc/developers/contributing.rst @@ -241,6 +241,23 @@ feedback: `_ for more details. +- Please be explicit **how this issue impacts you as a scikit-learn user**. Giving + some details (a short paragraph) about how you use scikit-learn and why you need + this issue resolved will help the project maintainers invest time and effort + on issues that actually impact users. + +- Please tell us if you would be interested in opening a PR to resolve your issue + once triaged by a project maintainer. + +Note that the scikit-learn tracker receives `daily reports +`_ by +GitHub accounts that are mostly interested in increasing contribution +statistics and show little interest in the expected end-user impact of their +contributions. As project maintainers we want to be able to assess if our +efforts are likely to have a meaningful and positive impact to our end users. +Therefore, we ask you to avoid opening issues for things you don't actually +care about. + If you want to help curate issues, read about :ref:`bug_triaging`. Contributing code and documentation @@ -387,7 +404,25 @@ complies with the following rules before marking a PR as "ready for review". The cases "Fix " is enough. "Fix #" is never a good title. -2. **Make sure your code passes the tests**. The whole test suite can be run +2. **Pull requests are expected to resolve one or more issues**. + Please **do not open PRs for issues that are labeled as "Needs triage"** + (see :ref:`issues_tagged_needs_triage`) or with other kinds of "Needs ..." + labels. Please do not open PRs for issues for which: + + - the discussion has not settled down to an explicit resolution plan, + - the reporter has already expressed interest in opening a PR, + - there already exists cross-referenced and active PRs. + + If merging your pull request means that some other issues/PRs should be closed, + you should `use keywords to create link to them + `_ + (e.g., ``Fixes #1234``; multiple issues/PRs are allowed as long as each + one is preceded by a keyword). Upon merging, those issues/PRs will + automatically be closed by GitHub. If your pull request is simply + related to some other issues/PRs, or it only partially resolves the target + issue, create a link to them without using the keywords (e.g., ``Towards #1234``). + +3. **Make sure your code passes the tests**. The whole test suite can be run with `pytest`, but it is usually not recommended since it takes a long time. It is often enough to only run the test related to your changes: for example, if you changed something in @@ -410,12 +445,12 @@ complies with the following rules before marking a PR as "ready for review". The you don't need to run the whole test suite locally. For guidelines on how to use ``pytest`` efficiently, see the :ref:`pytest_tips`. -3. **Make sure your code is properly commented and documented**, and **make +4. **Make sure your code is properly commented and documented**, and **make sure the documentation renders properly**. To build the documentation, please refer to our :ref:`contribute_documentation` guidelines. The CI will also build the docs: please refer to :ref:`generated_doc_CI`. -4. **Tests are necessary for enhancements to be +5. **Tests are necessary for enhancements to be accepted**. Bug-fixes or new features should be provided with non-regression tests. These tests verify the correct behavior of the fix or feature. In this manner, further modifications on the code base are granted to be consistent with the @@ -423,27 +458,17 @@ complies with the following rules before marking a PR as "ready for review". The non-regression tests should fail for the code base in the ``main`` branch and pass for the PR code. -5. If your PR is likely to affect users, you need to add a changelog entry describing +6. If your PR is likely to affect users, you need to add a changelog entry describing your PR changes. See the `README `_ for more details. -6. Follow the :ref:`coding-guidelines`. +7. Follow the :ref:`coding-guidelines`. -7. When applicable, use the validation tools and scripts in the :mod:`sklearn.utils` +8. When applicable, use the validation tools and scripts in the :mod:`sklearn.utils` module. A list of utility routines available for developers can be found in the :ref:`developers-utils` page. -8. Often pull requests resolve one or more other issues (or pull requests). - If merging your pull request means that some other issues/PRs should - be closed, you should `use keywords to create link to them - `_ - (e.g., ``Fixes #1234``; multiple issues/PRs are allowed as long as each - one is preceded by a keyword). Upon merging, those issues/PRs will - automatically be closed by GitHub. If your pull request is simply - related to some other issues/PRs, or it only partially resolves the target - issue, create a link to them without using the keywords (e.g., ``Towards #1234``). - 9. PRs should often substantiate the change, through benchmarks of performance and efficiency (see :ref:`monitoring_performances`) or through examples of usage. Examples also illustrate the features and intricacies of From b0bf5d7280e8768e3add0d9c83ae950436a1b878 Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Wed, 28 Jan 2026 16:35:43 +0100 Subject: [PATCH 167/462] ENH Turn `TargetEncoder` into a metadata router and route `groups` to `cv` object (#33089) Co-authored-by: Adrin Jalali --- doc/metadata_routing.rst | 1 + .../metadata-routing/33089.enhancement.rst | 5 + sklearn/model_selection/_split.py | 19 ++- sklearn/preprocessing/_target_encoder.py | 135 +++++++++++++++--- .../tests/test_target_encoder.py | 20 +++ sklearn/tests/metadata_routing_common.py | 7 +- .../test_metaestimators_metadata_routing.py | 14 +- 7 files changed, 177 insertions(+), 24 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/metadata-routing/33089.enhancement.rst diff --git a/doc/metadata_routing.rst b/doc/metadata_routing.rst index 79e0dcc1bb362..20dd142ec1bbe 100644 --- a/doc/metadata_routing.rst +++ b/doc/metadata_routing.rst @@ -317,6 +317,7 @@ Meta-estimators and functions supporting metadata routing: - :class:`sklearn.multioutput.MultiOutputClassifier` - :class:`sklearn.multioutput.MultiOutputRegressor` - :class:`sklearn.multioutput.RegressorChain` +- :class:`sklearn.preprocessing.TargetEncoder` - :class:`sklearn.pipeline.FeatureUnion` - :class:`sklearn.pipeline.Pipeline` - :class:`sklearn.semi_supervised.SelfTrainingClassifier` diff --git a/doc/whats_new/upcoming_changes/metadata-routing/33089.enhancement.rst b/doc/whats_new/upcoming_changes/metadata-routing/33089.enhancement.rst new file mode 100644 index 0000000000000..c7588da78f75b --- /dev/null +++ b/doc/whats_new/upcoming_changes/metadata-routing/33089.enhancement.rst @@ -0,0 +1,5 @@ +- :class:`~preprocessing.TargetEncoder` now routes `groups` to the :term:`CV splitter` + internally used for :term:`cross fitting` in its + :meth:`~preprocessing.TargetEncoder.fit_transform`. + By :user:`Samruddhi Baviskar ` and + :user:`Stefanie Senger `. diff --git a/sklearn/model_selection/_split.py b/sklearn/model_selection/_split.py index c9a3a5bfaea92..0719fbd2b11f1 100644 --- a/sklearn/model_selection/_split.py +++ b/sklearn/model_selection/_split.py @@ -2687,7 +2687,7 @@ def split(self, X=None, y=None, groups=None): yield train, test -def check_cv(cv=5, y=None, *, classifier=False): +def check_cv(cv=5, y=None, *, classifier=False, shuffle=False, random_state=None): """Input checker utility for building a cross-validator. Parameters @@ -2719,6 +2719,19 @@ def check_cv(cv=5, y=None, *, classifier=False): or multiclass; otherwise :class:`KFold` is used. Ignored if `cv` is a cross-validator instance or iterable. + shuffle : bool, default=False + Whether to shuffle the data before splitting into batches. Note that the samples + within each split will not be shuffled. Only applies if `cv` is an int or + `None`. If `cv` is a cross-validation generator or an iterable, `shuffle` is + ignored. + + random_state : int, RandomState instance or None, default=None + When `shuffle` is True and `cv` is an integer or `None`, `random_state` affects + the ordering of the indices, which controls the randomness of each fold. + Otherwise, this parameter has no effect. + Pass an int for reproducible output across multiple function calls. + See :term:`Glossary `. + Returns ------- checked_cv : a cross-validator instance. @@ -2740,9 +2753,9 @@ def check_cv(cv=5, y=None, *, classifier=False): and (y is not None) and (type_of_target(y, input_name="y") in ("binary", "multiclass")) ): - return StratifiedKFold(cv) + return StratifiedKFold(cv, shuffle=shuffle, random_state=random_state) else: - return KFold(cv) + return KFold(cv, shuffle=shuffle, random_state=random_state) if not hasattr(cv, "split") or isinstance(cv, str): if not isinstance(cv, Iterable) or isinstance(cv, str): diff --git a/sklearn/preprocessing/_target_encoder.py b/sklearn/preprocessing/_target_encoder.py index 5d8fc97f2a1bd..c5a927d9ddca6 100644 --- a/sklearn/preprocessing/_target_encoder.py +++ b/sklearn/preprocessing/_target_encoder.py @@ -1,7 +1,7 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause -from numbers import Integral, Real +from numbers import Real import numpy as np @@ -11,6 +11,14 @@ _fit_encoding_fast, _fit_encoding_fast_auto_smooth, ) +from sklearn.utils import Bunch, indexable +from sklearn.utils._metadata_requests import ( + MetadataRouter, + MethodMapping, + _raise_for_params, + _routing_enabled, + process_routing, +) from sklearn.utils._param_validation import Interval, StrOptions from sklearn.utils.multiclass import type_of_target from sklearn.utils.validation import ( @@ -41,7 +49,7 @@ class TargetEncoder(OneToOneFeatureMixin, _BaseEncoder): that are not seen during :meth:`fit` are encoded with the target mean, i.e. `target_mean_`. - For a demo on the importance of the `TargetEncoder` internal cross-fitting, + For a demo on the importance of the `TargetEncoder` internal :term:`cross fitting`, see :ref:`sphx_glr_auto_examples_preprocessing_plot_target_encoder_cross_val.py`. For a comparison of different encoders, refer to @@ -94,14 +102,33 @@ class TargetEncoder(OneToOneFeatureMixin, _BaseEncoder): more weight on the global target mean. If `"auto"`, then `smooth` is set to an empirical Bayes estimate. - cv : int, default=5 - Determines the number of folds in the :term:`cross fitting` strategy used in - :meth:`fit_transform`. For classification targets, `StratifiedKFold` is used - and for continuous targets, `KFold` is used. + cv : int, cross-validation generator or an iterable, default=None + Determines the splitting strategy used in the internal :term:`cross fitting` + during :meth:`fit_transform`. Splitters where each sample index doesn't appear + in the validation fold exactly once, raise a `ValueError`. + Possible inputs for cv are: + + - `None`, to use a 5-fold cross-validation chosen internally based on + `target_type`, + - integer, to specify the number of folds for the cross-validation chosen + internally based on `target_type`, + - :term:`CV splitter` that does not repeat samples across validation folds, + - an iterable yielding (train, test) splits as arrays of indices. + + For integer/None inputs, if `target_type` is `"continuous"`, :class:`KFold` is + used, otherwise :class:`StratifiedKFold` is used. + + Refer :ref:`User Guide ` for more information on + cross-validation strategies. + + .. versionchanged:: 1.9 + Cross-validation generators and iterables can also be passed as `cv`. shuffle : bool, default=True Whether to shuffle the data in :meth:`fit_transform` before splitting into - folds. Note that the samples within each split will not be shuffled. + folds. Note that the samples within each split will not be shuffled. Only + applies if `cv` is an int or `None`. If `cv` is a cross-validation generator or + an iterable, `shuffle` is ignored. random_state : int, RandomState instance or None, default=None When `shuffle` is True, `random_state` affects the ordering of the @@ -193,7 +220,7 @@ class TargetEncoder(OneToOneFeatureMixin, _BaseEncoder): "categories": [StrOptions({"auto"}), list], "target_type": [StrOptions({"auto", "continuous", "binary", "multiclass"})], "smooth": [StrOptions({"auto"}), Interval(Real, 0, None, closed="left")], - "cv": [Interval(Integral, 2, None, closed="left")], + "cv": ["cv_object"], "shuffle": ["boolean"], "random_state": ["random_state"], } @@ -243,7 +270,7 @@ def fit(self, X, y): return self @_fit_context(prefer_skip_nested_validation=True) - def fit_transform(self, X, y): + def fit_transform(self, X, y, **params): """Fit :class:`TargetEncoder` and transform `X` with the target encoding. This method uses a :term:`cross fitting` scheme to prevent target leakage @@ -263,28 +290,71 @@ def fit_transform(self, X, y): y : array-like of shape (n_samples,) The target data used to encode the categories. + **params : dict + Parameters to route to the internal CV object. + + Can only be used in conjunction with a cross-validation generator as CV + object. + + For instance, `groups` (array-like of shape `(n_samples,)`) can be routed to + a CV splitter that accepts `groups`, such as :class:`GroupKFold` or + :class:`StratifiedGroupKFold`. + + .. versionadded:: 1.9 + Only available if `enable_metadata_routing=True`, which can be + set by using ``sklearn.set_config(enable_metadata_routing=True)``. + See :ref:`Metadata Routing User Guide ` for + more details. + Returns ------- X_trans : ndarray of shape (n_samples, n_features) or \ (n_samples, (n_features * n_classes)) Transformed input. """ - from sklearn.model_selection import ( # avoid circular import + # avoid circular imports + from sklearn.model_selection import ( + GroupKFold, KFold, + StratifiedGroupKFold, StratifiedKFold, ) + from sklearn.model_selection._split import check_cv + + _raise_for_params(params, self, "fit_transform") X_ordinal, X_known_mask, y_encoded, n_categories = self._fit_encodings_all(X, y) - # The cv splitter is voluntarily restricted to *KFold to enforce non - # overlapping validation folds, otherwise the fit_transform output will - # not be well-specified. - if self.target_type_ == "continuous": - cv = KFold(self.cv, shuffle=self.shuffle, random_state=self.random_state) + cv = check_cv( + self.cv, + y, + classifier=self.target_type_ != "continuous", + shuffle=self.shuffle, + random_state=self.random_state, + ) + + if _routing_enabled(): + if params["groups"] is not None: + X, y, params["groups"] = indexable(X, y, params["groups"]) + routed_params = process_routing(self, "fit_transform", **params) else: - cv = StratifiedKFold( - self.cv, shuffle=self.shuffle, random_state=self.random_state - ) + routed_params = Bunch(splitter=Bunch(split={})) + + # The internal cross-fitting is only well-defined when each sample index + # appears in exactly one validation fold. Skip the validation check for + # known non-overlapping splitters in scikit-learn: + if not isinstance( + cv, (GroupKFold, KFold, StratifiedKFold, StratifiedGroupKFold) + ): + seen_count = np.zeros(X.shape[0]) + for _, test_idx in cv.split(X, y, **routed_params.splitter.split): + seen_count[test_idx] += 1 + if not np.all(seen_count == 1): + raise ValueError( + "Validation indices from `cv` must cover each sample index exactly " + "once with no overlap. Pass a splitter with non-overlapping " + "validation folds as `cv` or refer to the docs for other options." + ) # If 'multiclass' multiply axis=1 by num classes else keep shape the same if self.target_type_ == "multiclass": @@ -295,7 +365,7 @@ def fit_transform(self, X, y): else: X_out = np.empty_like(X_ordinal, dtype=np.float64) - for train_idx, test_idx in cv.split(X, y): + for train_idx, test_idx in cv.split(X, y, **routed_params.splitter.split): X_train, y_train = X_ordinal[train_idx, :], y_encoded[train_idx] y_train_mean = np.mean(y_train, axis=0) @@ -546,6 +616,33 @@ def get_feature_names_out(self, input_features=None): else: return feature_names + def get_metadata_routing(self): + """Get metadata routing of this object. + + Please check :ref:`User Guide ` on how the routing + mechanism works. + + .. versionadded:: 1.9 + + Returns + ------- + routing : MetadataRouter + A :class:`~sklearn.utils.metadata_routing.MetadataRouter` encapsulating + routing information. + """ + + router = MetadataRouter(owner=self) + + router.add( + # This works, since none of {None, int, iterable} request any metadata + # and the machinery here would assign an empty MetadataRequest + # to it. + splitter=self.cv, + method_mapping=MethodMapping().add(caller="fit_transform", callee="split"), + ) + + return router + def __sklearn_tags__(self): tags = super().__sklearn_tags__() tags.target_tags.required = True diff --git a/sklearn/preprocessing/tests/test_target_encoder.py b/sklearn/preprocessing/tests/test_target_encoder.py index fca0df3f16d55..6965df1779080 100644 --- a/sklearn/preprocessing/tests/test_target_encoder.py +++ b/sklearn/preprocessing/tests/test_target_encoder.py @@ -5,6 +5,7 @@ import pytest from numpy.testing import assert_allclose, assert_array_equal +from sklearn.datasets import make_regression from sklearn.ensemble import RandomForestRegressor from sklearn.linear_model import Ridge from sklearn.model_selection import ( @@ -732,3 +733,22 @@ def test_pandas_copy_on_write(): with pd.option_context("mode.copy_on_write", True): df = pd.DataFrame({"x": ["a", "b", "b"], "y": [4.0, 5.0, 6.0]}) TargetEncoder(target_type="continuous").fit(df[["x"]], df["y"]) + + +def test_target_encoder_raises_cv_overlap(global_random_seed): + """ + Test that `TargetEncoder` raises if `cv` has overlapping splits. + """ + X, y = make_regression(n_samples=100, n_features=3, random_state=0) + + non_overlapping_iterable = KFold().split(X, y) + encoder = TargetEncoder(cv=non_overlapping_iterable) + encoder.fit_transform(X, y) + + overlapping_iterable = ShuffleSplit( + n_splits=5, random_state=global_random_seed + ).split(X, y) + encoder = TargetEncoder(cv=overlapping_iterable) + msg = "Validation indices from `cv` must cover each sample index exactly once" + with pytest.raises(ValueError, match=msg): + encoder.fit_transform(X, y) diff --git a/sklearn/tests/metadata_routing_common.py b/sklearn/tests/metadata_routing_common.py index a0e2c07b5e07e..3c56dbca2da58 100644 --- a/sklearn/tests/metadata_routing_common.py +++ b/sklearn/tests/metadata_routing_common.py @@ -15,7 +15,7 @@ ) from sklearn.metrics._scorer import _Scorer, mean_squared_error from sklearn.model_selection import BaseCrossValidator -from sklearn.model_selection._split import GroupsConsumerMixin +from sklearn.model_selection._split import GroupKFold, GroupsConsumerMixin from sklearn.utils._metadata_requests import ( SIMPLE_METHODS, ) @@ -480,6 +480,11 @@ def _iter_test_indices(self, X=None, y=None, groups=None): yield train_indices +class ConsumingSplitterInheritingFromGroupKFold(ConsumingSplitter, GroupKFold): + """Helper class that can be used to test TargetEncoder, that only takes specific + splitters.""" + + class MetaRegressor(MetaEstimatorMixin, RegressorMixin, BaseEstimator): """A meta-regressor which is only a router.""" diff --git a/sklearn/tests/test_metaestimators_metadata_routing.py b/sklearn/tests/test_metaestimators_metadata_routing.py index 02899ad32fb2b..ecd9808bd9749 100644 --- a/sklearn/tests/test_metaestimators_metadata_routing.py +++ b/sklearn/tests/test_metaestimators_metadata_routing.py @@ -63,12 +63,14 @@ MultiOutputRegressor, RegressorChain, ) +from sklearn.preprocessing import TargetEncoder from sklearn.semi_supervised import SelfTrainingClassifier from sklearn.tests.metadata_routing_common import ( ConsumingClassifier, ConsumingRegressor, ConsumingScorer, ConsumingSplitter, + ConsumingSplitterInheritingFromGroupKFold, NonConsumingClassifier, NonConsumingRegressor, _Registry, @@ -448,6 +450,13 @@ "X": X, "y": y, }, + { + "metaestimator": TargetEncoder, + "X": X, + "y": y, + "cv_name": "cv", + "cv_routing_methods": ["fit_transform"], + }, ] """List containing all metaestimators to be tested and their settings @@ -560,7 +569,10 @@ def get_init_args(metaestimator_info, sub_estimator_consumes): if "cv_name" in metaestimator_info: cv_name = metaestimator_info["cv_name"] cv_registry = _Registry() - cv = ConsumingSplitter(registry=cv_registry) + if metaestimator_info["metaestimator"] is TargetEncoder: + cv = ConsumingSplitterInheritingFromGroupKFold(registry=cv_registry) + else: + cv = ConsumingSplitter(registry=cv_registry) kwargs[cv_name] = cv return ( From a86c639e21f24ac5488366f9ec4746354264177d Mon Sep 17 00:00:00 2001 From: GarimaGarg222 <151461599+GarimaGarg222@users.noreply.github.com> Date: Thu, 29 Jan 2026 16:18:33 +0530 Subject: [PATCH 168/462] DOC Improve clarity and reproducibility in classification probability example (#33124) --- .../classification/plot_classification_probability.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/classification/plot_classification_probability.py b/examples/classification/plot_classification_probability.py index 050afc2377669..737587c1f7596 100644 --- a/examples/classification/plot_classification_probability.py +++ b/examples/classification/plot_classification_probability.py @@ -63,14 +63,14 @@ # the classifier in regions where it is not certain of its prediction. classifiers = { - "Logistic regression\n(C=0.01)": LogisticRegression(C=0.1), - "Logistic regression\n(C=1)": LogisticRegression(C=100), + "Logistic regression\n(C=0.1)": LogisticRegression(C=0.1), + "Logistic regression\n(C=100)": LogisticRegression(C=100), "Gaussian Process": GaussianProcessClassifier(kernel=1.0 * RBF([1.0, 1.0])), "Logistic regression\n(RBF features)": make_pipeline( Nystroem(kernel="rbf", gamma=5e-1, n_components=50, random_state=1), LogisticRegression(C=10), ), - "Gradient Boosting": HistGradientBoostingClassifier(), + "Gradient Boosting": HistGradientBoostingClassifier(random_state=42), "Logistic regression\n(binned features)": make_pipeline( KBinsDiscretizer(n_bins=5, quantile_method="averaged_inverted_cdf"), PolynomialFeatures(interaction_only=True), @@ -136,7 +136,7 @@ cmap="Blues", levels=levels, ) - axes[classifier_idx, label].set_title(f"Class {label}") + axes[classifier_idx, label].set_title(f"Class {iris.target_names[label]}") # plot data predicted to belong to given class mask_y_pred = y_pred == label axes[classifier_idx, label].scatter( @@ -157,7 +157,8 @@ ) for label in y_unique: mask_label = y_test == label - axes[classifier_idx, 3].scatter( + max_col = len(y_unique) + axes[classifier_idx, max_col].scatter( X_test[mask_label, 0], X_test[mask_label, 1], c=max_class_disp.multiclass_colors_[[label], :], From b7e29dfcc427e41f3e8546d6ea03a190be066ae8 Mon Sep 17 00:00:00 2001 From: Mohammad Ahmadullah Khan <115063771+MAUK9086@users.noreply.github.com> Date: Fri, 30 Jan 2026 14:37:50 +0530 Subject: [PATCH 169/462] DOC Add note about startup overhead in parallelism (#33153) --- doc/computing/parallelism.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/computing/parallelism.rst b/doc/computing/parallelism.rst index bd24ace621c4e..de7dbfbde70d0 100644 --- a/doc/computing/parallelism.rst +++ b/doc/computing/parallelism.rst @@ -34,6 +34,15 @@ When the underlying implementation uses joblib, the number of workers (threads or processes) that are spawned in parallel can be controlled via the ``n_jobs`` parameter. +.. note:: + + **Startup Overhead** + + When using ``n_jobs > 1`` (or ``n_jobs=-1``), you may observe a delay + the first time a parallel function is called. This is expected behavior + caused by the overhead of starting the Python worker processes. + Subsequent calls will be faster as they reuse the existing pool of workers. + .. note:: Where (and how) parallelization happens in the estimators using joblib by From 351280bd1d79dc5de598776e8bb2da98c1f74b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Fri, 30 Jan 2026 10:11:43 +0100 Subject: [PATCH 170/462] CI Migrate pylatest_conda_forge_mkl build to GHA (#33155) --- .github/workflows/unit-tests.yml | 11 +++++++++++ azure-pipelines.yml | 23 ----------------------- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 9426aa4060eb7..4f5b64f83b518 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -127,6 +127,17 @@ jobs: DISTRIB: conda LOCK_FILE: build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock + - name: Linuw x86-64 pylatest_conda_forge_mkl + os: ubuntu-22.04 + DISTRIB: conda + LOCK_FILE: build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock + COVERAGE: true + SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 42 # default global random seed + SCIPY_ARRAY_API: 1 + # Tests that require large downloads over the networks are skipped in CI. + # Here we make sure, that they are still run on a regular basis. + SKLEARN_SKIP_NETWORK_TESTS: ${{ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && '0' || '1' }} + # Check compilation with Ubuntu 22.04 LTS (Jammy Jellyfish) and scipy from conda-forge - name: Linux x86-64 pymin_conda_forge_openblas_ubuntu_2204 os: ubuntu-22.04 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 98f9c9760a026..233fea5e3dcd6 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -45,29 +45,6 @@ jobs: python build_tools/check-meson-openmp-dependencies.py displayName: Run Meson OpenMP checks -# Will run all the time regardless of linting outcome. -- template: build_tools/azure/posix.yml - parameters: - name: Linux_Runs - vmImage: ubuntu-22.04 - dependsOn: [git_commit] - condition: | - and( - succeeded(), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[ci skip]')) - ) - matrix: - pylatest_conda_forge_mkl: - DISTRIB: 'conda' - LOCK_FILE: './build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock' - COVERAGE: 'true' - SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '42' # default global random seed - # Tests that require large downloads over the networks are skipped in CI. - # Here we make sure, that they are still run on a regular basis. - ${{ if eq(variables['Build.Reason'], 'Schedule') }}: - SKLEARN_SKIP_NETWORK_TESTS: '0' - SCIPY_ARRAY_API: '1' - - template: build_tools/azure/posix-docker.yml parameters: name: Linux_Docker From cb7e82dd443aa1eb24bb70a3188b067536320a40 Mon Sep 17 00:00:00 2001 From: pomrakna Date: Sun, 1 Feb 2026 11:20:38 +0000 Subject: [PATCH 171/462] MNT Fix small typo in convergence warning for NewtonSolver (#33164) --- sklearn/linear_model/_glm/_newton_solver.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sklearn/linear_model/_glm/_newton_solver.py b/sklearn/linear_model/_glm/_newton_solver.py index 5979791f3ae2a..61d75ffbcfd50 100644 --- a/sklearn/linear_model/_glm/_newton_solver.py +++ b/sklearn/linear_model/_glm/_newton_solver.py @@ -289,8 +289,8 @@ def line_search(self, X, y, sample_weight): warnings.warn( ( f"Line search of Newton solver {self.__class__.__name__} at" - f" iteration #{self.iteration} did no converge after 21 line search" - " refinement iterations. It will now resort to lbfgs instead." + f" iteration #{self.iteration} did not converge after 21 line " + "search refinement iterations. It will now resort to lbfgs instead." ), ConvergenceWarning, ) From 0f2f3b6b035a48f661171e4293aa34f5cbf9b68c Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Mon, 2 Feb 2026 07:38:51 +0100 Subject: [PATCH 172/462] ENH speedup gap safe screening (#33161) --- .../33161.enhancement.rst | 9 ++ sklearn/linear_model/_cd_fast.pyx | 100 ++++++++++-------- 2 files changed, 63 insertions(+), 46 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33161.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33161.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33161.enhancement.rst new file mode 100644 index 0000000000000..4d15cdaf269b2 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33161.enhancement.rst @@ -0,0 +1,9 @@ +- |Efficiency| :class:`linear_model.ElasticNet`, :class:`linear_model.ElasticNetCV`, + :class:`linear_model.Lasso`, :class:`linear_model.LassoCV`, + :class:`linear_model.MultiTaskElasticNet`, :class:`linear_model.MultiTaskElasticNetCV` + :class:`linear_model.MultiTaskLasso`, :class:`linear_model.MultiTaskLassoCV` + as well as + :func:`linear_model.lasso_path` and :func:`linear_model.enet_path` are now faster when + fit with strong L1 penalty and many features. During gap safe screening of features, + the update of the residual is now only performed if the coefficient is not zero. + By :user:`Christian Lorentzen `. diff --git a/sklearn/linear_model/_cd_fast.pyx b/sklearn/linear_model/_cd_fast.pyx index ffb44e9c992fb..3eb260eb7e279 100644 --- a/sklearn/linear_model/_cd_fast.pyx +++ b/sklearn/linear_model/_cd_fast.pyx @@ -378,9 +378,10 @@ def enet_coordinate_descent( excluded_set[j] = 0 n_active += 1 else: - # R += w[j] * X[:,j] - _axpy(n_samples, w[j], &X[0, j], 1, &R[0], 1) - w[j] = 0 + if w[j] != 0: + # R += w[j] * X[:,j] + _axpy(n_samples, w[j], &X[0, j], 1, &R[0], 1) + w[j] = 0 excluded_set[j] = 1 for n_iter in range(max_iter): @@ -448,9 +449,10 @@ def enet_coordinate_descent( excluded_set[j] = 0 n_active += 1 else: - # R += w[j] * X[:,j] - _axpy(n_samples, w[j], &X[0, j], 1, &R[0], 1) - w[j] = 0 + if w[j] != 0: + # R += w[j] * X[:,j] + _axpy(n_samples, w[j], &X[0, j], 1, &R[0], 1) + w[j] = 0 excluded_set[j] = 1 else: @@ -809,21 +811,22 @@ def sparse_enet_coordinate_descent( excluded_set[j] = 0 n_active += 1 else: - # R += w[j] * X[:,j] - R_plus_wj_Xj( - n_samples, - R, - X_data, - X_indices, - X_indptr, - X_mean, - center, - sample_weight, - no_sample_weights, - w[j], - j, - ) - w[j] = 0 + if w[j] != 0: + # R += w[j] * X[:,j] + R_plus_wj_Xj( + n_samples, + R, + X_data, + X_indices, + X_indptr, + X_mean, + center, + sample_weight, + no_sample_weights, + w[j], + j, + ) + w[j] = 0 excluded_set[j] = 1 for n_iter in range(max_iter): @@ -925,21 +928,22 @@ def sparse_enet_coordinate_descent( excluded_set[j] = 0 n_active += 1 else: - # R += w[j] * X[:,j] - R_plus_wj_Xj( - n_samples, - R, - X_data, - X_indices, - X_indptr, - X_mean, - center, - sample_weight, - no_sample_weights, - w[j], - j, - ) - w[j] = 0 + if w[j] != 0: + # R += w[j] * X[:,j] + R_plus_wj_Xj( + n_samples, + R, + X_data, + X_indices, + X_indptr, + X_mean, + center, + sample_weight, + no_sample_weights, + w[j], + j, + ) + w[j] = 0 excluded_set[j] = 1 else: @@ -1150,9 +1154,10 @@ def enet_coordinate_descent_gram( excluded_set[j] = 0 n_active += 1 else: - # Qw -= w[j] * Q[j] # Update Qw = Q @ w - _axpy(n_features, -w[j], &Q[j, 0], 1, &Qw[0], 1) - w[j] = 0 + if w[j] != 0: + # Qw -= w[j] * Q[j] # Update Qw = Q @ w + _axpy(n_features, -w[j], &Q[j, 0], 1, &Qw[0], 1) + w[j] = 0 excluded_set[j] = 1 for n_iter in range(max_iter): @@ -1221,9 +1226,10 @@ def enet_coordinate_descent_gram( excluded_set[j] = 0 n_active += 1 else: - # Qw -= w[j] * Q[j] # Update Qw = Q @ w - _axpy(n_features, -w[j], &Q[j, 0], 1, &Qw[0], 1) - w[j] = 0 + if w[j] != 0: + # Qw -= w[j] * Q[j] # Update Qw = Q @ w + _axpy(n_features, -w[j], &Q[j, 0], 1, &Qw[0], 1) + w[j] = 0 excluded_set[j] = 1 else: @@ -1462,8 +1468,9 @@ def enet_coordinate_descent_multi_task( else: # R += W[:, 1] * X[:, 1][:, None] for t in range(n_tasks): - _axpy(n_samples, W[t, j], &X[0, j], 1, &R[0, t], 1) - W[t, j] = 0 + if W[t, j] != 0: + _axpy(n_samples, W[t, j], &X[0, j], 1, &R[0, t], 1) + W[t, j] = 0 excluded_set[j] = 1 for n_iter in range(max_iter): @@ -1559,8 +1566,9 @@ def enet_coordinate_descent_multi_task( else: # R += W[:, 1] * X[:, 1][:, None] for t in range(n_tasks): - _axpy(n_samples, W[t, j], &X[0, j], 1, &R[0, t], 1) - W[t, j] = 0 + if W[t, j] != 0: + _axpy(n_samples, W[t, j], &X[0, j], 1, &R[0, t], 1) + W[t, j] = 0 excluded_set[j] = 1 else: From d05e742ef8a9ad78cbbc740ae9592f80d534fdcd Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 2 Feb 2026 03:32:34 -0500 Subject: [PATCH 173/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33171) Co-authored-by: Lock file bot --- .../pylatest_pip_scipy_dev_linux-64_conda.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 556c57caf6966..53bcc07b0de2a 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -11,27 +11,27 @@ https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 -https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 +https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-h32b2ec7_100_cp314.conda#1cef1236a05c3a98f68c33ae9425f656 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-h32b2ec7_101_cp314.conda#051f60a9d1e3aae7160d173aeb7029f8 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda#f08a17c938eb6bc1b928bd8cdd37e20f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b -# pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 +# pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c # pip charset-normalizer @ https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 # pip coverage @ https://files.pythonhosted.org/packages/ba/49/f54ec02ed12be66c8d8897270505759e057b0c68564a65c429ccdd1f139e/coverage-7.13.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=a7fc042ba3c7ce25b8a9f097eb0f32a5ce1ccdb639d9eec114e26def98e1f8a4 @@ -64,7 +64,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 # pip meson-python @ https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl#sha256=67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298 -# pip pooch @ https://files.pythonhosted.org/packages/a8/87/77cc11c7a9ea9fd05503def69e3d18605852cd0d4b0d3b8f15bbeb3ef1d1/pooch-1.8.2-py3-none-any.whl#sha256=3529a57096f7198778a5ceefd5ac3ef0e4d06a6ddaf9fc2d609b806f25302c47 +# pip pooch @ https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl#sha256=f265597baa9f760d25ceb29d0beb8186c243d6607b0f60b83ecf14078dbc703b # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 # pip sphinx @ https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl#sha256=c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978 From 52d70d337bcbc2f9931fe6976c4440f699f9e373 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 2 Feb 2026 03:33:10 -0500 Subject: [PATCH 174/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33172) Co-authored-by: Lock file bot --- .../pylatest_free_threaded_linux-64_conda.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index 7990c4e8e47f8..c57a46ae4cc6a 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -11,41 +11,41 @@ https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 -https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 +https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-he1279bd_0_cp314t.conda#08a2a24f4e6907bea0ebfe22eecae6be +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-he1279bd_1_cp314t.conda#9c01f87c0150322d53879878aa478c0c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.2-py314hd8ed1ab_0.conda#d0ce45508dd9dffaec3795252897bd7a +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.2-py314hd8ed1ab_1.conda#437c7e7fabfe4274ae0e652298a013c6 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.conda#cc2fcbfdf0628b5ad05b319866187bbc https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda#f08a17c938eb6bc1b928bd8cdd37e20f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda#7b446fcbb6779ee479debb4fd7453e6c https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d @@ -53,7 +53,7 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py314hd4f4903_0.conda#66c5cfbc84524e3eb553503b80874087 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 -https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.2-h92d6c8b_0.conda#f4db4d53331f31ec695670d5b3cedabb +https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.2-h92d6c8b_1.conda#b1c229bbdd39ba06315b15c0ed7f3946 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py314h529d2a9_1.conda#2548681b651d007d01368d98b3f8536e From 41f1f34791bf72d40e70462d92ac50469b38192e Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Mon, 2 Feb 2026 10:35:15 +0100 Subject: [PATCH 175/462] FIX `predict` to also use `multiclass_colors` in DecisionBoundaryDisplay (#33015) Co-authored-by: Olivier Grisel Co-authored-by: Lucy Liu --- .../sklearn.inspection/33015.fix.rst | 3 + sklearn/inspection/_plot/decision_boundary.py | 159 ++++++++++++------ .../tests/test_boundary_decision_display.py | 96 +++++++++-- 3 files changed, 199 insertions(+), 59 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.inspection/33015.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/33015.fix.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/33015.fix.rst new file mode 100644 index 0000000000000..393f15198d4e1 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.inspection/33015.fix.rst @@ -0,0 +1,3 @@ +- In :class:`inspection.DecisionBoundaryDisplay`, `multiclass_colors` is now also used + for multiclass plotting when `response_method="predict"`. + By :user:`Anne Beyer `. diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index ab7728739604c..2f7175fbd7446 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -5,7 +5,7 @@ import numpy as np -from sklearn.base import is_regressor +from sklearn.base import is_classifier, is_clusterer, is_outlier_detector, is_regressor from sklearn.preprocessing import LabelEncoder from sklearn.utils import _safe_indexing from sklearn.utils._dataframe import is_pandas_df, is_polars_df @@ -77,27 +77,46 @@ class DecisionBoundaryDisplay: xx1 : ndarray of shape (grid_resolution, grid_resolution) Second output of :func:`meshgrid `. + n_classes : int + Expected number of unique classes or labels if `response` was generated by a + :term:`classifier` or a :term:`clusterer`. + + For :term:`outlier detectors`, `n_classes` should be set to 2 by definition + (inlier or outlier). + + For :term:`regressors`, `n_classes` should also be set to 2 by convention + (continuous responses are displayed the same way as unthresholded binary + responses). + + .. versionadded:: 1.9 + response : ndarray of shape (grid_resolution, grid_resolution) or \ (grid_resolution, grid_resolution, n_classes) Values of the response function. multiclass_colors : list of str or str, default=None - Specifies how to color each class when plotting all classes of multiclass - problem. Ignored for binary problems and multiclass problems when plotting a - single prediction value per point. + Specifies how to color each class when plotting all classes of + :term:`multiclass` problems. + Possible inputs are: * list: list of Matplotlib `color `_ strings, of length `n_classes` * str: name of :class:`matplotlib.colors.Colormap` - * None: 'viridis' colormap is used to sample colors + * None: 'tab10' colormap is used to sample colors if the number of + classes is less than or equal to 10, otherwise 'gist_rainbow' colormap. + + Single color (fading to white) colormaps will be generated from the colors in + the list or colors taken from the colormap, and passed to the `cmap` parameter + of the `plot_method`. - Single color colormaps will be generated from the colors in the list or - colors taken from the colormap and passed to the `cmap` parameter of - the `plot_method`. + For :term:`binary` problems, this is ignored and `cmap` or `colors` can be + passed as kwargs instead, otherwise, the default colormap ('viridis') is used. .. versionadded:: 1.7 + .. versionchanged:: 1.9 + `multiclass_colors` is now also used when `response_method="predict"` xlabel : str, default=None Default label to place on x axis. @@ -115,7 +134,7 @@ class DecisionBoundaryDisplay: multiclass_colors_ : array of shape (n_classes, 4) Colors used to plot each class in multiclass problems. - Only defined when `color_of_interest` is None. + Only defined when `n_classes` > 2. .. versionadded:: 1.7 @@ -131,6 +150,7 @@ class DecisionBoundaryDisplay: Examples -------- + >>> import matplotlib as mpl >>> import matplotlib.pyplot as plt >>> import numpy as np >>> from sklearn.datasets import load_iris @@ -145,22 +165,35 @@ class DecisionBoundaryDisplay: >>> tree = DecisionTreeClassifier().fit(iris.data[:, :2], iris.target) >>> y_pred = np.reshape(tree.predict(grid), feature_1.shape) >>> display = DecisionBoundaryDisplay( - ... xx0=feature_1, xx1=feature_2, response=y_pred + ... xx0=feature_1, xx1=feature_2, n_classes=len(tree.classes_), response=y_pred ... ) >>> display.plot() <...> >>> display.ax_.scatter( - ... iris.data[:, 0], iris.data[:, 1], c=iris.target, edgecolor="black" + ... iris.data[:, 0], + ... iris.data[:, 1], + ... c=iris.target, + ... cmap=mpl.colors.ListedColormap(display.multiclass_colors_), + ... edgecolor="black" ... ) <...> >>> plt.show() """ def __init__( - self, *, xx0, xx1, response, multiclass_colors=None, xlabel=None, ylabel=None + self, + *, + xx0, + xx1, + n_classes, + response, + multiclass_colors=None, + xlabel=None, + ylabel=None, ): self.xx0 = xx0 self.xx1 = xx1 + self.n_classes = n_classes self.response = response self.multiclass_colors = multiclass_colors self.xlabel = xlabel @@ -189,7 +222,9 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar Overwrite the y-axis label. **kwargs : dict - Additional keyword arguments to be passed to the `plot_method`. + Additional keyword arguments to be passed to the `plot_method`. For + :term:`binary` problems, `cmap` or `colors` can be set here to specify the + colormap or colors, otherwise the default colormap ('viridis') is used. Returns ------- @@ -210,16 +245,14 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar _, ax = plt.subplots() plot_func = getattr(ax, plot_method) - if self.response.ndim == 2: + if self.n_classes == 2: self.surface_ = plot_func(self.xx0, self.xx1, self.response, **kwargs) - else: # self.response.ndim == 3 - n_responses = self.response.shape[-1] + else: # multiclass for kwarg in ("cmap", "colors"): if kwarg in kwargs: warnings.warn( f"'{kwarg}' is ignored in favor of 'multiclass_colors' " - "in the multiclass case when the response method is " - "'decision_function' or 'predict_proba'." + "in the multiclass case." ) del kwargs[kwarg] @@ -227,22 +260,22 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar self.multiclass_colors, str ): if self.multiclass_colors is None: - cmap = "tab10" if n_responses <= 10 else "gist_rainbow" + cmap = "tab10" if self.n_classes <= 10 else "gist_rainbow" else: cmap = self.multiclass_colors # Special case for the tab10 and tab20 colormaps that encode a # discrete set of colors that are easily distinguishable # contrary to other colormaps that are continuous. - if cmap == "tab10" and n_responses <= 10: - colors = plt.get_cmap("tab10", 10).colors[:n_responses] - elif cmap == "tab20" and n_responses <= 20: - colors = plt.get_cmap("tab20", 20).colors[:n_responses] + if cmap == "tab10" and self.n_classes <= 10: + colors = plt.get_cmap("tab10", 10).colors[: self.n_classes] + elif cmap == "tab20" and self.n_classes <= 20: + colors = plt.get_cmap("tab20", 20).colors[: self.n_classes] else: - cmap = plt.get_cmap(cmap, n_responses) + cmap = plt.get_cmap(cmap, self.n_classes) if not hasattr(cmap, "colors"): - # For LinearSegmentedColormap - colors = cmap(np.linspace(0, 1, n_responses)) + # Get `LinearSegmentedColormap` for non-qualitative cmaps + colors = cmap(np.linspace(0, 1, self.n_classes)) else: colors = cmap.colors elif isinstance(self.multiclass_colors, list): @@ -251,25 +284,37 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar raise ValueError("'multiclass_colors' must be a list or a str.") self.multiclass_colors_ = colors - if plot_method == "contour": - # Plot only argmax map for contour - class_map = self.response.argmax(axis=2) + + if self.response.ndim == 2: # predict + # `pcolormesh` requires cmap, for the others it makes no difference + cmap = mpl.colors.ListedColormap(colors) self.surface_ = plot_func( - self.xx0, self.xx1, class_map, colors=colors, **kwargs + self.xx0, self.xx1, self.response, cmap=cmap, **kwargs + ) + + # predict_proba and decision_function differ for plotting methods + elif plot_method == "contour": + # Plot only integer class values + self.surface_ = plot_func( + self.xx0, + self.xx1, + self.response.argmax(axis=2), + colors=colors, + **kwargs, ) else: multiclass_cmaps = [ mpl.colors.LinearSegmentedColormap.from_list( - f"colormap_{class_idx}", [(1.0, 1.0, 1.0, 1.0), (r, g, b, 1.0)] + f"colormap_{class_idx}", + [(1.0, 1.0, 1.0, 1.0), (r, g, b, 1.0)], ) for class_idx, (r, g, b, _) in enumerate(colors) ] - self.surface_ = [] for class_idx, cmap in enumerate(multiclass_cmaps): response = np.ma.array( self.response[:, :, class_idx], - mask=~(self.response.argmax(axis=2) == class_idx), + mask=(self.response.argmax(axis=2) != class_idx), ) self.surface_.append( plot_func(self.xx0, self.xx1, response, cmap=cmap, **kwargs) @@ -342,20 +387,19 @@ def from_estimator( For multiclass problems, 'auto' no longer defaults to 'predict'. class_of_interest : int, float, bool or str, default=None - The class to be plotted when `response_method` is 'predict_proba' - or 'decision_function'. If None, `estimator.classes_[1]` is considered - the positive class for binary classifiers. For multiclass - classifiers, if None, all classes will be represented in the - decision boundary plot; the class with the highest response value + The class to be plotted. For :term:`binary` classifiers, if None, + `estimator.classes_[1]` is considered the positive class. For + :term:`multiclass` classifiers, if None, all classes will be represented in + the decision boundary plot; when `response_method` is :term:`predict_proba` + or :term:`decision_function`, the class with the highest response value at each point is plotted. The color of each class can be set via `multiclass_colors`. .. versionadded:: 1.4 multiclass_colors : list of str, or str, default=None - Specifies how to color each class when plotting multiclass - 'predict_proba' or 'decision_function' and `class_of_interest` is - None. Ignored in all other cases. + Specifies how to color each class when plotting :term:`multiclass` problems + and `class_of_interest` is None. Possible inputs are: @@ -367,11 +411,17 @@ def from_estimator( classes is less than or equal to 10, otherwise 'gist_rainbow' colormap. - Single color colormaps will be generated from the colors in the list or - colors taken from the colormap, and passed to the `cmap` parameter of - the `plot_method`. + Single color (fading to white) colormaps will be generated from the colors + in the list or colors taken from the colormap, and passed to the `cmap` + parameter of the `plot_method`. + + For :term:`binary` problems, this is ignored and `cmap` or `colors` can be + passed as kwargs instead, otherwise, the default colormap ('viridis') is + used. .. versionadded:: 1.7 + .. versionchanged:: 1.9 + `multiclass_colors` is now also used when `response_method="predict"` xlabel : str, default=None The label used for the x-axis. If `None`, an attempt is made to @@ -388,8 +438,7 @@ def from_estimator( created. **kwargs : dict - Additional keyword arguments to be passed to the - `plot_method`. + Additional keyword arguments to be passed to the `plot_method`. Returns ------- @@ -406,6 +455,7 @@ def from_estimator( Examples -------- + >>> import matplotlib as mpl >>> import matplotlib.pyplot as plt >>> from sklearn.datasets import load_iris >>> from sklearn.linear_model import LogisticRegression @@ -418,7 +468,8 @@ def from_estimator( ... xlabel=iris.feature_names[0], ylabel=iris.feature_names[1], ... alpha=0.5, ... ) - >>> disp.ax_.scatter(X[:, 0], X[:, 1], c=iris.target, edgecolor="k") + >>> cmap = mpl.colors.ListedColormap(disp.multiclass_colors_) + >>> disp.ax_.scatter(X[:, 0], X[:, 1], c=iris.target, edgecolor="k", cmap=cmap) <...> >>> plt.show() """ @@ -512,6 +563,8 @@ def from_estimator( # to our user when interacting with # `DecisionBoundaryDisplay.from_estimator` raise ValueError( + # Note: it is ok to use estimator.classes_ here, as this error will + # only be thrown if estimator is a classifier f"class_of_interest={class_of_interest} is not a valid label: It " f"should be one of {estimator.classes_}" ) from exc @@ -538,6 +591,17 @@ def from_estimator( else: response = response.reshape(*xx0.shape, response.shape[-1]) + if ( + class_of_interest is not None + or is_regressor(estimator) + or is_outlier_detector(estimator) + ): + n_classes = 2 + elif is_classifier(estimator): + n_classes = len(estimator.classes_) + elif is_clusterer(estimator): + n_classes = len(np.unique(estimator.labels_)) + if xlabel is None: xlabel = X.columns[0] if hasattr(X, "columns") else "" @@ -547,6 +611,7 @@ def from_estimator( display = cls( xx0=xx0, xx1=xx1, + n_classes=n_classes, response=response, multiclass_colors=multiclass_colors, xlabel=xlabel, diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index 388b65d199029..4e212e7467384 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -3,10 +3,15 @@ import numpy as np import pytest -from sklearn.base import BaseEstimator, ClassifierMixin +from sklearn.base import ( + BaseEstimator, + ClassifierMixin, +) +from sklearn.cluster import KMeans from sklearn.datasets import ( load_diabetes, load_iris, + make_blobs, make_classification, make_multilabel_classification, ) @@ -232,7 +237,7 @@ def test_decision_boundary_display_classifier( @pytest.mark.parametrize("response_method", ["auto", "predict", "decision_function"]) -@pytest.mark.parametrize("plot_method", ["contourf", "contour"]) +@pytest.mark.parametrize("plot_method", ["contourf", "contour", "pcolormesh"]) def test_decision_boundary_display_outlier_detector( pyplot, response_method, plot_method ): @@ -249,7 +254,10 @@ def test_decision_boundary_display_outlier_detector( eps=eps, ax=ax, ) - assert isinstance(disp.surface_, pyplot.matplotlib.contour.QuadContourSet) + if plot_method == "pcolormesh": + assert isinstance(disp.surface_, pyplot.matplotlib.collections.QuadMesh) + else: + assert isinstance(disp.surface_, pyplot.matplotlib.contour.QuadContourSet) assert disp.ax_ == ax assert disp.figure_ == fig @@ -281,7 +289,12 @@ def test_decision_boundary_display_regressor(pyplot, response_method, plot_metho eps=eps, plot_method=plot_method, ) - assert isinstance(disp.surface_, pyplot.matplotlib.contour.QuadContourSet) + if disp.n_classes == 2 or plot_method == "contour": + assert isinstance(disp.surface_, pyplot.matplotlib.contour.QuadContourSet) + else: + assert isinstance(disp.surface_, list) + for surface in disp.surface_: + assert isinstance(surface, pyplot.matplotlib.contour.QuadContourSet) assert disp.ax_ == ax assert disp.figure_ == fig @@ -611,15 +624,26 @@ def test_multiclass_plot_max_class(pyplot, response_method): @pytest.mark.parametrize( - "multiclass_colors", + "multiclass_colors, n_classes", [ - "plasma", - "Blues", - ["red", "green", "blue"], + (None, 3), + (None, 11), + ("plasma", 3), + ("Blues", 3), + (["red", "green", "blue"], 3), ], ) +@pytest.mark.parametrize( + "response_method", ["decision_function", "predict_proba", "predict"] +) @pytest.mark.parametrize("plot_method", ["contourf", "contour", "pcolormesh"]) -def test_multiclass_colors_cmap(pyplot, plot_method, multiclass_colors): +def test_multiclass_colors_cmap( + pyplot, + n_classes, + response_method, + plot_method, + multiclass_colors, +): """Check correct cmap used for all `multiclass_colors` inputs.""" import matplotlib as mpl @@ -628,17 +652,24 @@ def test_multiclass_colors_cmap(pyplot, plot_method, multiclass_colors): "Matplotlib >= 3.5 is needed for `==` to check equivalence of colormaps" ) - X, y = load_iris_2d_scaled() + X, y = make_blobs(n_samples=150, centers=n_classes, n_features=2, random_state=42) clf = LogisticRegression().fit(X, y) disp = DecisionBoundaryDisplay.from_estimator( clf, X, + response_method=response_method, plot_method=plot_method, multiclass_colors=multiclass_colors, ) - if multiclass_colors == "plasma": + if multiclass_colors is None: + if len(clf.classes_) <= 10: + colors = mpl.pyplot.get_cmap("tab10", 10).colors[: len(clf.classes_)] + else: + cmap = mpl.pyplot.get_cmap("gist_rainbow", len(clf.classes_)) + colors = cmap(np.linspace(0, 1, len(clf.classes_))) + elif multiclass_colors == "plasma": colors = mpl.pyplot.get_cmap(multiclass_colors, len(clf.classes_)).colors elif multiclass_colors == "Blues": cmap = mpl.pyplot.get_cmap(multiclass_colors, len(clf.classes_)) @@ -646,18 +677,59 @@ def test_multiclass_colors_cmap(pyplot, plot_method, multiclass_colors): else: colors = [mpl.colors.to_rgba(color) for color in multiclass_colors] - if plot_method != "contour": + # Make sure the colormap has enough distinct colors. + assert disp.n_classes == len(np.unique(colors, axis=0)) + + if response_method == "predict": + cmap = mpl.colors.ListedColormap(colors) + assert disp.surface_.cmap == cmap + elif plot_method != "contour": cmaps = [ mpl.colors.LinearSegmentedColormap.from_list( f"colormap_{class_idx}", [(1.0, 1.0, 1.0, 1.0), (r, g, b, 1.0)] ) for class_idx, (r, g, b, _) in enumerate(colors) ] + # Make sure every class has its own surface. + assert len(disp.surface_) == disp.n_classes + for idx, quad in enumerate(disp.surface_): assert quad.cmap == cmaps[idx] else: assert_allclose(disp.surface_.colors, colors) + # non-regression test for issue #32866 (currently still fails) + # if hasattr(disp.surface_, "levels"): + # assert len(disp.surface_.levels) >= disp.n_classes + + +@pytest.mark.parametrize( + "estimator, n_blobs, expected_n_classes", + [ + (DecisionTreeClassifier(random_state=0), 7, 7), + (DecisionTreeClassifier(random_state=0), 2, 2), + (KMeans(n_clusters=7, random_state=0), 7, 7), + (KMeans(n_clusters=2, random_state=0), 2, 2), + (DecisionTreeRegressor(random_state=0), 7, 2), + (IsolationForest(random_state=0), 7, 2), + ], +) +def test_n_classes_attribute(pyplot, estimator, n_blobs, expected_n_classes): + """Check that `n_classes` is set correctly. + + Introduced in https://github.com/scikit-learn/scikit-learn/pull/33015""" + + X, y = make_blobs(n_samples=150, centers=n_blobs, n_features=2, random_state=42) + clf = estimator.fit(X, y) + disp = DecisionBoundaryDisplay.from_estimator(clf, X, response_method="predict") + assert disp.n_classes == expected_n_classes + + # Test that setting class_of_interest always converts to a binary problem. + disp_coi = DecisionBoundaryDisplay.from_estimator( + clf, X, class_of_interest=y[0], response_method="predict" + ) + assert disp_coi.n_classes == 2 + def test_cmap_and_colors_logic(pyplot): """Check the handling logic for `cmap` and `colors`.""" From 839d1445e8bf5a3a4f8b31e017890bbd421bf76b Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Mon, 2 Feb 2026 11:19:47 +0100 Subject: [PATCH 176/462] FIX _predict_proba_lr in LinearClassifierMixin (#33168) Co-authored-by: Omar Salman --- .../sklearn.linear_model/33168.fix.rst | 4 +++ sklearn/linear_model/_base.py | 9 ++++++- sklearn/linear_model/tests/test_base.py | 27 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33168.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33168.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33168.fix.rst new file mode 100644 index 0000000000000..d918df1e36ae4 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33168.fix.rst @@ -0,0 +1,4 @@ +- Fixed a bug in :class:`linear_model.SGDClassifier` for multiclass settings where + large negative values of :method:`decision_function` could lead to NaN values. In + this case, this fix assigns equal probability for each class. + By :user:`Christian Lorentzen `. diff --git a/sklearn/linear_model/_base.py b/sklearn/linear_model/_base.py index b46d6a4f0a20b..04704c713c99b 100644 --- a/sklearn/linear_model/_base.py +++ b/sklearn/linear_model/_base.py @@ -405,7 +405,14 @@ def _predict_proba_lr(self, X): return np.vstack([1 - prob, prob]).T else: # OvR normalization, like LibLinear's predict_probability - prob /= prob.sum(axis=1).reshape((prob.shape[0], -1)) + prob_sum = prob.sum(axis=1) + all_zero = prob_sum == 0 + if np.any(all_zero): + # The above might assign zero to all classes, which doesn't + # normalize neatly; work around this to produce uniform probabilities. + prob[all_zero, :] = 1 + prob_sum[all_zero] = prob.shape[1] # n_classes + prob /= prob_sum.reshape((prob.shape[0], -1)) return prob diff --git a/sklearn/linear_model/tests/test_base.py b/sklearn/linear_model/tests/test_base.py index 504ae6f024d65..0839d98144b7c 100644 --- a/sklearn/linear_model/tests/test_base.py +++ b/sklearn/linear_model/tests/test_base.py @@ -7,9 +7,11 @@ import pytest from scipy import linalg, sparse +from sklearn.base import BaseEstimator from sklearn.datasets import load_iris, make_regression, make_sparse_uncorrelated from sklearn.linear_model import LinearRegression from sklearn.linear_model._base import ( + LinearClassifierMixin, _preprocess_data, _rescale_data, make_dataset, @@ -844,3 +846,28 @@ def test_linear_regression_sample_weight_consistency( assert_allclose(reg1.coef_, reg2.coef_, rtol=1e-6) if fit_intercept: assert_allclose(reg1.intercept_, reg2.intercept_) + + +def test_predict_proba_lr_large_values(): + """Test that _predict_proba_lr of LinearClassifierMixin deals with large + negative values. + + Note that exp(-1000) = 0. + """ + + class MockClassifier(LinearClassifierMixin, BaseEstimator): + def __init__(self): + pass + + def fit(self, X, y): + self.__sklearn_is_fitted__ = True + + def decision_function(self, X): + n_samples = X.shape[0] + return np.tile([-1000.0] * 4, [n_samples, 1]) + + clf = MockClassifier() + clf.fit(X=None, y=None) + + proba = clf._predict_proba_lr(np.ones(5)) + assert_allclose(np.sum(proba, axis=1), 1) From 680faf4c4b4721a325092b5419e074fb0c40f8d3 Mon Sep 17 00:00:00 2001 From: "Christine P. Chai" Date: Mon, 2 Feb 2026 02:34:45 -0800 Subject: [PATCH 177/462] DOC: Add reference links to hinge loss API documentation (#33169) --- sklearn/metrics/_classification.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 894f291eaa4e7..77fc49bb63622 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -3499,14 +3499,15 @@ def hinge_loss(y_true, pred_decision, *, labels=None, sample_weight=None): .. [1] `Wikipedia entry on the Hinge loss `_. - .. [2] Koby Crammer, Yoram Singer. On the Algorithmic + .. [2] `Koby Crammer, Yoram Singer. On the Algorithmic Implementation of Multiclass Kernel-based Vector Machines. Journal of Machine Learning Research 2, - (2001), 265-292. + (2001), 265-292 + `_. - .. [3] `L1 AND L2 Regularization for Multiclass Hinge Loss Models + .. [3] `L1 and L2 Regularization for Multiclass Hinge Loss Models by Robert C. Moore, John DeNero - `_. + `_. Examples -------- From cedf994f1e0c113bb5f905fb39cb56df9d86f3b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Feb 2026 12:01:17 +0100 Subject: [PATCH 178/462] Bump pypa/cibuildwheel from 3.3.0 to 3.3.1 in the actions group (#33166) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cuda-ci.yml | 2 +- .github/workflows/emscripten.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cuda-ci.yml b/.github/workflows/cuda-ci.yml index f67b774ecbe7c..76d0041763909 100644 --- a/.github/workflows/cuda-ci.yml +++ b/.github/workflows/cuda-ci.yml @@ -18,7 +18,7 @@ jobs: - uses: actions/checkout@v6 - name: Build wheels - uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 + uses: pypa/cibuildwheel@298ed2fb2c105540f5ed055e8a6ad78d82dd3a7e # v3.3.1 env: CIBW_BUILD: cp313-manylinux_x86_64 CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index 590aed14afcde..dc1a7a08f2a0a 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -67,7 +67,7 @@ jobs: with: persist-credentials: false - - uses: pypa/cibuildwheel@63fd63b352a9a8bdcc24791c9dbee952ee9a8abc # v3.3.0 + - uses: pypa/cibuildwheel@298ed2fb2c105540f5ed055e8a6ad78d82dd3a7e # v3.3.1 env: CIBW_PLATFORM: pyodide SKLEARN_SKIP_OPENMP_TEST: "true" From 951e8dd1e1c6e8091298a1a66ccba02714ec0c94 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Mon, 2 Feb 2026 14:53:20 +0100 Subject: [PATCH 179/462] FIX Fix pip-tools error in automatic main lock-file update (#33179) --- build_tools/update_environments_and_lock_files.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build_tools/update_environments_and_lock_files.py b/build_tools/update_environments_and_lock_files.py index 02c08aa4eca85..21129400d0004 100644 --- a/build_tools/update_environments_and_lock_files.py +++ b/build_tools/update_environments_and_lock_files.py @@ -647,6 +647,9 @@ def write_pip_lock_file(build_metadata): "-n", f"pip-tools-python{python_version}", f"python={python_version}", + # TODO remove the following line once pip-tools is compatible with pip 26.0, + # see https://github.com/jazzband/pip-tools/issues/2319 + "pip=25.3", "pip-tools", "-y", ] From 0da13ec15b37e60db9935a23e4f3b48526cb5c5b Mon Sep 17 00:00:00 2001 From: Agnus Paul <74678373+agnuspaul98@users.noreply.github.com> Date: Wed, 4 Feb 2026 13:28:07 +0530 Subject: [PATCH 180/462] DOC: Fix typo in API reference description (#33204) --- doc/api_reference.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api_reference.py b/doc/api_reference.py index 340f75ce941b7..1afc689dc837c 100644 --- a/doc/api_reference.py +++ b/doc/api_reference.py @@ -41,8 +41,8 @@ def _get_submodule(module_name, submodule_name): components: short_summary (required) - The text to be printed on the index page; it has nothing to do the API reference - page of each module. + The text to be printed on the index page; it has nothing to do with + the API reference page of each module. description (required, `None` if not needed) The additional description for the module to be placed under the module docstring, before the sections start. From a60f4fe3445ca050008114e18d00d660889be9b2 Mon Sep 17 00:00:00 2001 From: Tim Head Date: Wed, 4 Feb 2026 16:30:26 +0100 Subject: [PATCH 181/462] CI Use a virtual package spec file for `conda-lock` solving (#33175) --- build_tools/github/create_gpu_environment.sh | 7 + ...a_forge_cuda_array-api_linux-64_conda.lock | 249 +++++++++++------- ...ge_cuda_array-api_linux-64_environment.yml | 1 + ...rray-api_linux-64_virtual_package_spec.yml | 9 + .../update_environments_and_lock_files.py | 48 ++-- .../utils/_test_common/instance_generator.py | 4 + 6 files changed, 209 insertions(+), 109 deletions(-) create mode 100644 build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_virtual_package_spec.yml diff --git a/build_tools/github/create_gpu_environment.sh b/build_tools/github/create_gpu_environment.sh index 96a62d7678566..35a7a4c79f441 100755 --- a/build_tools/github/create_gpu_environment.sh +++ b/build_tools/github/create_gpu_environment.sh @@ -12,6 +12,13 @@ source "${HOME}/conda/etc/profile.d/conda.sh" source build_tools/shared.sh conda activate base +# Run these debug commands before installing our specific conda environment. +# We want to see what is available on the runner before we make changes. But +# we need to install miniforge before being able to look at the output of the +# conda commands. +conda info --json | python -c "import sys, json; print('Conda virtual packages versions:', json.load(sys.stdin).get('virtual_pkgs', []));" +nvidia-smi + CONDA_ENV_NAME=sklearn LOCK_FILE=build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock create_conda_environment_from_lock_file $CONDA_ENV_NAME $LOCK_FILE diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 716a3a16f73de..7e18aeb5d3018 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -1,145 +1,192 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 879f64b0534a118cfb4a43da8226771a8abadccd873d0a27980fc1e3b2273d45 +# input_hash: 8bd38cbfb6761e42fe9b9ed474c118b28133f54feacf11682feab65d79c6c311 @EXPLICIT -https://conda.anaconda.org/conda-forge/noarch/cuda-version-11.8-h70ddcb2_3.conda#670f0e1593b8c1d84f57ad5fe5256799 +https://conda.anaconda.org/conda-forge/noarch/cuda-version-12.9-h4f385c5_3.conda#b6d5d7f1c171cbd228ea06b556cfa859 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 -https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_1.conda#9e298d76f543deb06eb0f3413675e13a +https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 +https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a66894dfd07c4510beb6b3f9672ccc0 +https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/cuda-cccl_linux-64-12.9.27-ha770c72_0.conda#87ff6381e33b76e5b9b179a2cdd005ec +https://conda.anaconda.org/conda-forge/noarch/cuda-crt-dev_linux-64-12.9.86-ha770c72_2.conda#79d280de61e18010df5997daea4743df +https://conda.anaconda.org/conda-forge/linux-64/cuda-crt-tools-12.9.86-ha770c72_2.conda#503a94e20d2690d534d676a764a1852c +https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-static_linux-64-12.9.79-h3f2d84a_0.conda#b87bf315d81218dd63eb46cc1eaef775 +https://conda.anaconda.org/conda-forge/noarch/cuda-cudart_linux-64-12.9.79-h3f2d84a_0.conda#64508631775fbbf9eca83c84b1df0cae +https://conda.anaconda.org/conda-forge/noarch/cuda-nvvm-dev_linux-64-12.9.86-ha770c72_2.conda#7b386291414c7eea113d25ac28a33772 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 +https://conda.anaconda.org/conda-forge/noarch/libnvptxcompiler-dev_linux-64-12.9.86-ha770c72_2.conda#a66a909acf08924aced622903832a937 https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 -https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 +https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_linux-64-12.9.79-h3f2d84a_0.conda#86e40eb67d83f1a58bdafdd44e5a77c6 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 +https://conda.anaconda.org/conda-forge/linux-64/libnvptxcompiler-dev-12.9.86-ha770c72_2.conda#3fd926c321c6dbf386aa14bd8b125bfb https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb -https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.10.6-hb9d3cd8_0.conda#d7d4680337a14001b0e043e96529409b +https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 +https://conda.anaconda.org/conda-forge/noarch/cuda-nvcc-dev_linux-64-12.9.86-he91c749_2.conda#19d4e090217f0ea89d30bedb7461c048 +https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-impl-12.9.86-h4bc722e_2.conda#82125dd3c0c4aa009faa00e2829b93d8 +https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-tools-12.9.86-h4bc722e_2.conda#f9af26e4079adcd72688a8e8dbecb229 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 -https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb03c661_4.conda#1d29d2e33fe59954af82ef54a8af3fe1 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 -https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 +https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa +https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb9d3cd8_0.conda#db63358239cbe1ff86242406d440e44a https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f -https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.9.0-hb9d3cd8_1.conda#1e936bd23d737aac62a18e9a1e7f8b18 +https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.8.1-h1a47875_3.conda#55a8561fdbbbd34f50f57d9be12ed084 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.0-h4e1184b_5.conda#3f4c1197462a6df2be6dc8241828fe93 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.1-h4e1184b_4.conda#a5126a90e74ac739b00564a4c7ddcc36 -https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.2-h4e1184b_4.conda#74e8c3e4df4ceae34aa2959df4b28101 -https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.3.1-h5888daf_0.conda#bfd56492d8346d669010eccafe0ba058 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.13-h2c9d079_1.conda#3c3d02681058c3d206b562b2e3bc337f +https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h8b1a151_9.conda#f7ec84186dfe7a9e3a9f9e5a4d023e75 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h8b1a151_4.conda#c7e3e08b7b1b285524ab9d74162ce40b +https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h8b1a151_5.conda#68da5b56dde41e172b7b24f071c4b392 +https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-12.9.79-h5888daf_0.conda#cb15315d19b58bd9cd424084e58ad081 +https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-static-12.9.79-h5888daf_0.conda#d3c4ac48f4967f09dd910d9c15d40c81 +https://conda.anaconda.org/conda-forge/linux-64/cuda-cupti-12.9.79-h676940d_1.conda#a2ddf359dcb9e6a3d0173b10f58f4db9 +https://conda.anaconda.org/conda-forge/linux-64/cuda-nvcc-tools-12.9.86-he02047a_2.conda#dc256c9864c2e8e9c817fbca1c84a4bc +https://conda.anaconda.org/conda-forge/linux-64/cuda-nvdisasm-12.9.88-hffce074_1.conda#5e7845d208a5067cb1461a429ff887e0 +https://conda.anaconda.org/conda-forge/linux-64/cuda-nvrtc-12.9.86-hecca717_1.conda#53f0062e2243b26e43ddac0b5267c6a3 +https://conda.anaconda.org/conda-forge/linux-64/cuda-nvtx-12.9.79-hecca717_1.conda#b4a3411fa031c409f98cfbd4b2db9ad7 +https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717_0.conda#dbe3ec0f120af456b3477743ffd99b74 +https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda#f7d7a4104082b39e3b3473fbd4a38229 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d +https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libabseil-20240722.0-cxx17_hbbce691_4.conda#488f260ccda0afaf08acb286db439c2f -https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb03c661_4.conda#5cb5a1c9a94a78f5b23684bcb845338d -https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb03c661_4.conda#2e55011fa483edb8bfe3fd92e860cd79 +https://conda.anaconda.org/conda-forge/linux-64/libabseil-20250512.1-cxx17_hba17884_0.conda#83b160d4da3e1e847bf044997621ed63 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f +https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e +https://conda.anaconda.org/conda-forge/linux-64/libcufft-11.4.1.4-hecca717_1.conda#75ae571353ec92c8f34d4cf6ec6ba264 +https://conda.anaconda.org/conda-forge/linux-64/libcurand-10.3.10.19-h676940d_1.conda#2a91559a9345bedf09af8b7903deb6e6 https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e +https://conda.anaconda.org/conda-forge/linux-64/libnvjitlink-12.9.86-hecca717_2.conda#3461b0f2d5cbb7973d361f9e85241d98 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 +https://conda.anaconda.org/conda-forge/linux-64/nccl-2.29.2.1-h4d09622_1.conda#cda0cd556f99190e28f083c5125be060 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 -https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda#7fa07cb0fb1b625a089ccc01218ee5b1 +https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 +https://conda.anaconda.org/rapidsai/linux-64/rapids-logger-0.1.1-h98325ef_0.conda#e22516a87ac1fb1ea6bf0aa6a18e9d30 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.5.11-h072c03f_0.conda#5e8060d52f676a40edef0006a75c718f +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.2-he8a4886_1.conda#bade189a194e66b93c03021bd36c337b https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 +https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.15.3-h173a860_6.conda#9a063178f1af0a898526cc24ba7be486 -https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb03c661_4.conda#ca4ed8015764937c81b830f7f5b68543 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-hdaf4b65_5.conda#132e8f8f40f0ffc0bbde12bb4e8dd1a1 +https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf -https://conda.anaconda.org/conda-forge/linux-64/cudatoolkit-11.8.0-h4ba93d1_13.conda#eb43f5f1f16e2fad2eba22219c3e499b +https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 +https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_1.conda#55a83761db33f82d92d7d7a4a61662e5 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 -https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 +https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.conda#af0df9bc982b5ed2c67e8f5062d1f8c1 +https://conda.anaconda.org/conda-forge/linux-64/libcurand-dev-10.3.10.19-h676940d_1.conda#fc716aaff5af15b80ccbd28b3e67672c +https://conda.anaconda.org/conda-forge/linux-64/libcusparse-12.5.10.65-hecca717_2.conda#890ebfaad48c887d3d82847ec9d6bc79 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.2-h32235b2_0.conda#0cb0612bc9cb30c62baf41f9d600611b +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 -https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 -https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-5.28.2-h5b01275_0.conda#ab0bff36363bec94720275a681af8b83 -https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2024.07.02-hbbce691_2.conda#b2fede24428726dd867611664fb372e8 -https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.21.0-h0e7cc3e_0.conda#dcb95c0a98ba9ff737f7ae482aef7833 +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-openmp_hd680484_4.conda#c0512e4f60d62ccccb4c3c8333b33608 +https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_4.conda#07479fc04ba3ddd5d9f760ef1635cfa7 +https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h7b12aa8_0.conda#a30848ebf39327ea078cf26d114cff53 +https://conda.anaconda.org/rapidsai/linux-64/librmm-25.08.00-cuda12_250806_63a4d366.conda#8825b9080d25244f21b7fe18ef25f78c +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-258.3-h6569c3e_0.conda#68294614784925a7c1427835dbe217d7 +https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/nccl-2.27.3.1-h03a54cd_0.conda#616e835be8126fab0bf4cec1f40cc4ea +https://conda.anaconda.org/conda-forge/linux-64/libudev1-258.3-h6569c3e_0.conda#dc6d00d149316edb629059671dd8600e +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.0-h7959bf6_11.conda#9b3fb60fe57925a92f399bc3fc42eccf -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.9.2-hefd7a92_4.conda#5ce4df662d32d3123ea8da15571b6f51 -https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb03c661_4.conda#eaf3fbd2aa97c212336de38a51fe404e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.7-h28f887f_1.conda#7b8e3f846353b75db163ad93248e5f9d +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-ha8fc4e3_5.conda#3028f20dacafc00b22b88b324c8956cc +https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 +https://conda.anaconda.org/conda-forge/linux-64/cuda-nvcc-impl-12.9.86-h85509e4_2.conda#67458d2685e7503933efa550f3ee40f3 +https://conda.anaconda.org/conda-forge/linux-64/cuda-profiler-api-12.9.79-h7938cbb_1.conda#90d09865fb37d11d510444e34ebe6a09 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 -https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.1.4-h7d33bf5_0.conda#93fe78190bc6fe40d5e7a737c8065286 +https://conda.anaconda.org/conda-forge/linux-64/libcublas-dev-12.9.1.4-h676940d_1.conda#f90f4ff087ac29005c6989ea0fb2735a +https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.conda#a178a1f3642521f104ecceeefa138d01 +https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_0.conda#d71b1cf78714f31f1264591cdb7ce97d https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 +https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2.conda#bb6e31a0daa64ede76fe8d3fff01c06f +https://conda.anaconda.org/conda-forge/linux-64/libcusparse-dev-12.5.10.65-hecca717_2.conda#db94469fbd554c107acc3afd0af5d8ec https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.13.9-h04c0eec_0.conda#35eeb0a2add53b1e50218ed230fa6a02 +https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-25.08.00-cuda12_250806_2fb92393.conda#ac979638ede39fa80829d6a346405ab2 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 -https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c +https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-openmp_hd77311e_4.conda#525e2455ed342f2aef93c59ac5db2e28 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/orc-2.0.3-h97ab989_1.conda#2f46eae652623114e112df13fae311cf -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e -https://conda.anaconda.org/conda-forge/linux-64/re2-2024.07.02-h9925aae_2.conda#e84ddf12bde691e8ec894b00ea829ddf +https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-h19cb568_0.conda#a98b8d7cfdd20004f1bdd1a51cb22c58 +https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_101_cp313.conda#aa23b675b860f2566af2dfb3ffdf3b8c +https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 +https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_0.conda#0227d04521bc3d28c7995c7e1f99a721 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.8.0-hb921021_15.conda#c79d50f64cffa5ad51ecc1a81057962f -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.11.0-h11f4f37_12.conda#96c3e0221fa2da97619ee82faa341a73 -https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.14.0-h5cfcd09_0.conda#0a8838771cc2e985cd295e01ae83baf1 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.3-hef928c7_0.conda#bdd464b33f6540ed70845b946c11a7b8 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-hc63082f_11.conda#6a653aefdc5d83a4f959869d1759e6e3 +https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda#1d4e0d37da5f3c22ecd44033f673feba https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_101.conda#c74a6b9e8694e5122949f611d1552df5 +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.3.3-pyhcf101f3_0.conda#b08fa4a3478526e33a4c08224398d2e5 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 @@ -150,101 +197,119 @@ https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.1.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 -https://conda.anaconda.org/conda-forge/linux-64/libcudnn-dev-9.10.1.4-h0fdc2d1_0.conda#a0c0b44d26a4710e6ea577fcddbe09d1 +https://conda.anaconda.org/conda-forge/linux-64/libcufile-1.14.1.1-hbc026e6_1.conda#cab1818eada3952ed09c8dcbb7c26af7 +https://conda.anaconda.org/conda-forge/linux-64/libcusolver-dev-11.7.5.82-h676940d_2.conda#0fe12e558abf507458bcec839e29778d https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.67.1-hc2c308b_0.conda#4606a4647bfe857e3cfe21ca12ac3afb -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.1-default_h3d81e11_1000.conda#d821210ab60be56dd27b5525ed18366d +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda#ff63bb12ac31c176ff257e3289f20770 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.0-hecd9e04_0.conda#9ad637a7ac380c442be142dfb0b1b955 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda#74e91c36d0eef3557915c68b6c2bef96 -https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h7a3aeb2_0.conda#31059dc620fa57d787e3899ed0421e6d +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 +https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b +https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-12.575.51-pyhd8ed1ab_0.conda#90600980e7240e1d6fdc97c1f32f57af https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py313h80991f8_0.conda#183fe6b9e99e5c2b464c1573ec78eac8 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda#f08a17c938eb6bc1b928bd8cdd37e20f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e +https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda#7b446fcbb6779ee479debb4fd7453e6c https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py313h07c4f96_0.conda#82da2dcf1ea3e298f2557b50459809e0 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.4-py313hd02dea0_0.conda#442d7ac35e5d6bc89eba2998a9e1de06 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d +https://conda.anaconda.org/conda-forge/linux-64/ucx-1.18.1-h990bcc0_2.conda#15e5ae8dc2c3a57a9cd77aa40dedfd40 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.7.7-hf454442_0.conda#947c82025693bebd557f782bb5d6b469 -https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.10.0-h113e628_0.conda#73f73f60854f325a55f1d31459f2ab73 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.8.0-h736e048_1.conda#13de36be8de3ae3f05ba127631599213 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.3-h06ab39a_1.conda#3689a4290319587e3b54a4f9e68f70c8 +https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda#4e921d9c85e6559c60215497978b3cdb +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-h3d7a050_0.conda#e6f12de3a9b016cea81a87db04d85ff3 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.2-py313h3dea7bd_0.conda#df05169cc886aaf53dc560db634519f8 -https://conda.anaconda.org/conda-forge/linux-64/cudnn-9.10.1.4-haad7af6_0.conda#8382d957333e0d3280dcbf5691516dc1 +https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.5-py313h929d4db_0.conda#f2416964cdb2808dd2ed5be276a8fcdb https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py313h3dea7bd_0.conda#c0f36dfbb130da4f6ce2df31f6b25ea8 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.0-default_h99862b1_1.conda#d599b346638b9216c1e8f9146713df05 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.0-default_h746c552_1.conda#327c78a8ce710782425a89df851392f7 -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.32.0-h804f50b_0.conda#3d96df4d6b1c88455e05b94ce8a14a53 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_2.conda#3c71daed530c0c26671a1b1b7010e746 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_2.conda#0ad9019bb10eda915fb0ce5f78fef13b +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 -https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.8.0-h9ddd185_2.conda#8de40c4f75d36bb00a5870f682457f1d -https://conda.anaconda.org/conda-forge/linux-64/libpq-17.7-h5c52fec_1.conda#a4769024afeab4b32ac8167c2f92c7ac -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py313hf6604e3_0.conda#7d51e3bef1a4b00bde1861d85ba2f874 +https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d +https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.45.01-cuda12_250806_c25d2cdb.conda#84eff90bd9369d4b654434b1ea354ec4 +https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py313hf6604e3_0.conda#a61bd1412975145dd688a71849b63d97 +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff +https://conda.anaconda.org/conda-forge/noarch/pynvml-12.0.0-pyhd8ed1ab_0.conda#27a6f747d629815308c2d7e4f17aca4c https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.11-h4df99d1_100.conda#d1461b2e63b1909f4f5b41c823bd90ae -https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.13.0-h8d10470_4.conda#e6d46d70c68d0eb69b9a040ebe3acddf +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.11-h4df99d1_101.conda#4af7a72062bddcb57dea6b236e1b245e +https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py313h246eb7c_0.conda#932203205c4cf6f661180b98a48f195a +https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.29.7-hd92328a_7.conda#02b95564257d5c3db9c06beccf711f95 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.13.0-h3cf044e_1.conda#7eb66060455c7a47d9dcdbfa9f46579b +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.4-h8824e59_0.conda#113b9d9913280474c0868b0e290c0326 +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-h75daedc_0.conda#e88f8e816ae46c12cbe912c8f4d9d3bc https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 -https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.4.1-py313hc2a895b_0.conda#46dd595e816b278b178e3bef8a6acf71 -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.32.0-h0121fbd_0.conda#877a5ec0431a5af83bf0cd0522bfe661 -https://conda.anaconda.org/conda-forge/linux-64/libmagma_sparse-2.8.0-h9ddd185_0.conda#f4eb3cfeaf9d91e72d5b2b8706bf059f +https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.5-pyh698daf1_0.conda#a4fb0d4ffdac1cf2cda9318d2f789d20 +https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.4.1-py313h2626f57_0.conda#61b65ec6afaf6bf07e50bf32d4363461 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_ha70ccd2_201.conda#8ecb348d9f4c748e79afa17308d23d49 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2024.2.2-ha770c72_17.conda#e4ab075598123e783b788b995afbdad0 +https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py313hbfd7664_0.conda#ab6d05e915ab2ae4c41d275b14592151 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py313h4b8bb8b_1.conda#2b18fe5b4b2d1611ddf8c2f080a46563 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.458-hc430e4a_4.conda#aeefac461bea1f126653c1285cf5af08 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.12.0-ha633028_1.conda#7c1980f89dd41b097549782121a73490 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10.conda#937d1d4c233adc6eeb2ac3d6e9a73e53 +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-hd454692_0.conda#55986e49b7aafe9aa09d7f4c70a56a18 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 -https://conda.anaconda.org/conda-forge/linux-64/cupy-13.4.1-py313h66a2ee2_0.conda#784d6bd149ef2b5d9c733ea3dd4d15ad -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.5.1-cuda118_hb34f2e8_303.conda#da799bf557ff6376a1a58f40bddfb293 +https://conda.anaconda.org/conda-forge/linux-64/cupy-13.4.1-py313hdf5e20e_0.conda#b5bab25cd2f86d0425fbac36b75ea9bc +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.1-py310hffdcd12_0.conda#732a536c6ce768f096f5340121e10cc5 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-18.1.0-h44a453e_6_cpu.conda#2cf6d608d6e66506f69797d5c6944c35 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_h673abb8_201.conda#f8dae51be1b9afdccd70b576b8f73b44 +https://conda.anaconda.org/rapidsai/linux-64/rmm-25.08.00-cuda12_py313_250806_63a4d366.conda#967087ac0c607d3118d4b162978a76f4 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h2c50142_1_cpu.conda#fba261a7ee565b711b45c5bea554e5a0 https://conda.anaconda.org/conda-forge/noarch/polars-1.37.1-pyh6a1acc5_0.conda#1894d4373da653406c91e20ef89f05c8 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.5.1-cuda118_py313h40cdc2d_303.conda#19ad990954a4ed89358d91d0a3e7016d -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.9.2-h5bd77bc_1.conda#f7bfe5b8e7641ce7d11ea10cfd9f33cc -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-18.1.0-hcb10f89_6_cpu.conda#143f9288b64759a6427563f058c62f2b -https://conda.anaconda.org/conda-forge/linux-64/libparquet-18.1.0-h081d1f1_6_cpu.conda#68788df49ce7480187eb6387f15b2b67 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-18.1.0-py313he5f92c8_0_cpu.conda#5380e12f4468e891911dbbd4248b521a -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.9.2-py313ha3f37dd_1.conda#e2ec46ec4c607b97623e7b691ad31c54 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.5.1-cuda126hf7c78f0_303.conda#afaf760e55725108ae78ed41198c49bb -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-18.1.0-hcb10f89_6_cpu.conda#20ca46a6bc714a6ab189d5b3f46e66d8 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_201.conda#fb17e944f1ff5c1ab65822ba1f539b9d +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-hb82b983_4.conda#f4dfd61ec958d420bebdcefeb805d658 +https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.45.01-cuda12_py313_250806_c25d2cdb.conda#f9c5b31a6977929e9aa288feffd6fc7a +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h8c2c5c3_1_cpu.conda#102be5396c7899675268c17993e1a072 +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_1_cpu.conda#e7562d15926b3cea66a6e3546b133c5d +https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-25.08.00-cuda12_250806_2fb92393.conda#cbcb008978b2e7fd29995b8de4b4e7f2 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py313h85046ba_0.conda#2c5d21d466ef1ff0c0a98cfdbaf5c64b +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_1_cpu.conda#8b1290b259b24a4b29b3a3d6dec0fe53 +https://conda.anaconda.org/rapidsai/linux-64/libcuvs-25.08.00-cuda12_250806_9ce11a0f.conda#864f524cef608705031c54db01fb31d9 +https://conda.anaconda.org/rapidsai/linux-64/libraft-25.08.00-cuda12_250806_2fb92393.conda#cf1d59daaaa86e2d5841f6ce9fc2a10d https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-18.1.0-h3ee7192_6_cpu.conda#aa313b3168caf98d00b3753f5ba27650 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-18.1.0-py313h78bf25f_0.conda#a11d880ceedc33993c6f5c14a80ea9d3 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py313he109ebe_0_cpu.conda#9120bf253ebbdb0015069b9a25cf4d36 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_1_cpu.conda#651c34402277a875986db6fa7930d42d +https://conda.anaconda.org/rapidsai/linux-64/pylibraft-25.08.00-cuda12_py313_250806_2fb92393.conda#a4e3e89406631b9c5fe94e1971bdc049 +https://conda.anaconda.org/rapidsai/linux-64/cuvs-25.08.00-cuda12_py313_250806_9ce11a0f.conda#beec28b5e042219ff268caecc852ec2f +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-h3f74fd7_1_cpu.conda#bcf3ca0f04ed703121db4012e8c8bf5a +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.0-py313h78bf25f_0.conda#a6e89cb214f318db9548b791ba27f862 diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml index 50450c7236066..d362ece646955 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml @@ -27,4 +27,5 @@ dependencies: - polars - pyarrow - cupy + - rapidsai::cuvs - array-api-strict diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_virtual_package_spec.yml b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_virtual_package_spec.yml new file mode 100644 index 0000000000000..243e258ab43f8 --- /dev/null +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_virtual_package_spec.yml @@ -0,0 +1,9 @@ +# The versions of the virtual packages here are taken from running +# build_tools/github/create_gpu_environment.sh which outputs +# the versions of the packages used in the CUDA CI runner. +# Do not set them to what you see on your local machine. +subdirs: + linux-64: + packages: + __cuda: "12.8" + __glibc: "2.39" diff --git a/build_tools/update_environments_and_lock_files.py b/build_tools/update_environments_and_lock_files.py index 21129400d0004..f9e439cdb2fe1 100644 --- a/build_tools/update_environments_and_lock_files.py +++ b/build_tools/update_environments_and_lock_files.py @@ -109,8 +109,11 @@ def remove_from(alist, to_remove): "polars", "pyarrow", "cupy", + # cuvs is needed for cupyx.scipy.spatial.distance.cdist and friends + "rapidsai::cuvs", "array-api-strict", ], + "virtual_package_spec": True, }, { "name": "pylatest_conda_forge_mkl_linux-64", @@ -553,22 +556,26 @@ def write_all_conda_environments(build_metadata_list): write_conda_environment(build_metadata) -def conda_lock(environment_path, lock_file_path, platform): - execute_command( - [ - "conda-lock", - "lock", - "--mamba", - "--kind", - "explicit", - "--platform", - platform, - "--file", - str(environment_path), - "--filename-template", - str(lock_file_path), - ] - ) +def conda_lock( + environment_path, lock_file_path, platform, virtual_package_spec_path=None +): + cmd = [ + "conda-lock", + "lock", + "--mamba", + "--kind", + "explicit", + "--platform", + platform, + "--file", + str(environment_path), + "--filename-template", + str(lock_file_path), + ] + if virtual_package_spec_path is not None: + cmd.extend(["--virtual-package-spec", str(virtual_package_spec_path)]) + + execute_command(cmd) def create_conda_lock_file(build_metadata): @@ -581,7 +588,14 @@ def create_conda_lock_file(build_metadata): lock_file_basename = f"{lock_file_basename}_{platform}" lock_file_path = folder_path / f"{lock_file_basename}_conda.lock" - conda_lock(environment_path, lock_file_path, platform) + + virtual_package_spec_path = None + if build_metadata.get("virtual_package_spec"): + virtual_package_spec_path = ( + folder_path / f"{lock_file_basename}_virtual_package_spec.yml" + ) + + conda_lock(environment_path, lock_file_path, platform, virtual_package_spec_path) def write_all_conda_lock_files(build_metadata_list): diff --git a/sklearn/utils/_test_common/instance_generator.py b/sklearn/utils/_test_common/instance_generator.py index 76ddbc94342da..cdd9c78881695 100644 --- a/sklearn/utils/_test_common/instance_generator.py +++ b/sklearn/utils/_test_common/instance_generator.py @@ -1143,6 +1143,10 @@ def _yield_instances_for_check(check, estimator_orig): "sample_weight is not equivalent to removing/repeating samples." ), }, + PCA: { + # TODO: see gh-33205 for details + "check_array_api_input": "`linalg.inv` fails because input is singular", + }, Perceptron: { # TODO: replace by a statistical test, see meta-issue #16298 "check_sample_weight_equivalence_on_dense_data": ( From 9c367528b0447cb6dd39062fdf31661ceee2d1ba Mon Sep 17 00:00:00 2001 From: Varun Agnihotri Date: Thu, 5 Feb 2026 09:46:06 +0530 Subject: [PATCH 182/462] MAINT: Remove broken bench_multilabel_metrics.py (#33120) --- benchmarks/bench_multilabel_metrics.py | 227 ------------------------- 1 file changed, 227 deletions(-) delete mode 100755 benchmarks/bench_multilabel_metrics.py diff --git a/benchmarks/bench_multilabel_metrics.py b/benchmarks/bench_multilabel_metrics.py deleted file mode 100755 index 1b8449a24da51..0000000000000 --- a/benchmarks/bench_multilabel_metrics.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/env python -""" -A comparison of multilabel target formats and metrics over them -""" - -import argparse -import itertools -import sys -from functools import partial -from timeit import timeit - -import matplotlib.pyplot as plt -import numpy as np -import scipy.sparse as sp - -from sklearn.datasets import make_multilabel_classification -from sklearn.metrics import ( - accuracy_score, - f1_score, - hamming_loss, - jaccard_similarity_score, -) -from sklearn.utils._testing import ignore_warnings - -METRICS = { - "f1": partial(f1_score, average="micro"), - "f1-by-sample": partial(f1_score, average="samples"), - "accuracy": accuracy_score, - "hamming": hamming_loss, - "jaccard": jaccard_similarity_score, -} - -FORMATS = { - "sequences": lambda y: [list(np.flatnonzero(s)) for s in y], - "dense": lambda y: y, - "csr": sp.csr_matrix, - "csc": sp.csc_matrix, -} - - -@ignore_warnings -def benchmark( - metrics=tuple(v for k, v in sorted(METRICS.items())), - formats=tuple(v for k, v in sorted(FORMATS.items())), - samples=1000, - classes=4, - density=0.2, - n_times=5, -): - """Times metric calculations for a number of inputs - - Parameters - ---------- - metrics : array-like of callables (1d or 0d) - The metric functions to time. - - formats : array-like of callables (1d or 0d) - These may transform a dense indicator matrix into multilabel - representation. - - samples : array-like of ints (1d or 0d) - The number of samples to generate as input. - - classes : array-like of ints (1d or 0d) - The number of classes in the input. - - density : array-like of ints (1d or 0d) - The density of positive labels in the input. - - n_times : int - Time calling the metric n_times times. - - Returns - ------- - array of floats shaped like (metrics, formats, samples, classes, density) - Time in seconds. - """ - metrics = np.atleast_1d(metrics) - samples = np.atleast_1d(samples) - classes = np.atleast_1d(classes) - density = np.atleast_1d(density) - formats = np.atleast_1d(formats) - out = np.zeros( - (len(metrics), len(formats), len(samples), len(classes), len(density)), - dtype=float, - ) - it = itertools.product(samples, classes, density) - for i, (s, c, d) in enumerate(it): - _, y_true = make_multilabel_classification( - n_samples=s, n_features=1, n_classes=c, n_labels=d * c, random_state=42 - ) - _, y_pred = make_multilabel_classification( - n_samples=s, n_features=1, n_classes=c, n_labels=d * c, random_state=84 - ) - for j, f in enumerate(formats): - f_true = f(y_true) - f_pred = f(y_pred) - for k, metric in enumerate(metrics): - t = timeit(partial(metric, f_true, f_pred), number=n_times) - - out[k, j].flat[i] = t - return out - - -def _tabulate(results, metrics, formats): - """Prints results by metric and format - - Uses the last ([-1]) value of other fields - """ - column_width = max(max(len(k) for k in formats) + 1, 8) - first_width = max(len(k) for k in metrics) - head_fmt = "{:<{fw}s}" + "{:>{cw}s}" * len(formats) - row_fmt = "{:<{fw}s}" + "{:>{cw}.3f}" * len(formats) - print(head_fmt.format("Metric", *formats, cw=column_width, fw=first_width)) - for metric, row in zip(metrics, results[:, :, -1, -1, -1]): - print(row_fmt.format(metric, *row, cw=column_width, fw=first_width)) - - -def _plot( - results, - metrics, - formats, - title, - x_ticks, - x_label, - format_markers=("x", "|", "o", "+"), - metric_colors=("c", "m", "y", "k", "g", "r", "b"), -): - """ - Plot the results by metric, format and some other variable given by - x_label - """ - fig = plt.figure("scikit-learn multilabel metrics benchmarks") - plt.title(title) - ax = fig.add_subplot(111) - for i, metric in enumerate(metrics): - for j, format in enumerate(formats): - ax.plot( - x_ticks, - results[i, j].flat, - label="{}, {}".format(metric, format), - marker=format_markers[j], - color=metric_colors[i % len(metric_colors)], - ) - ax.set_xlabel(x_label) - ax.set_ylabel("Time (s)") - ax.legend() - plt.show() - - -if __name__ == "__main__": - ap = argparse.ArgumentParser() - ap.add_argument( - "metrics", - nargs="*", - default=sorted(METRICS), - help="Specifies metrics to benchmark, defaults to all. Choices are: {}".format( - sorted(METRICS) - ), - ) - ap.add_argument( - "--formats", - nargs="+", - choices=sorted(FORMATS), - help="Specifies multilabel formats to benchmark (defaults to all).", - ) - ap.add_argument( - "--samples", type=int, default=1000, help="The number of samples to generate" - ) - ap.add_argument("--classes", type=int, default=10, help="The number of classes") - ap.add_argument( - "--density", - type=float, - default=0.2, - help="The average density of labels per sample", - ) - ap.add_argument( - "--plot", - choices=["classes", "density", "samples"], - default=None, - help=( - "Plot time with respect to this parameter varying up to the specified value" - ), - ) - ap.add_argument( - "--n-steps", default=10, type=int, help="Plot this many points for each metric" - ) - ap.add_argument( - "--n-times", default=5, type=int, help="Time performance over n_times trials" - ) - args = ap.parse_args() - - if args.plot is not None: - max_val = getattr(args, args.plot) - if args.plot in ("classes", "samples"): - min_val = 2 - else: - min_val = 0 - steps = np.linspace(min_val, max_val, num=args.n_steps + 1)[1:] - if args.plot in ("classes", "samples"): - steps = np.unique(np.round(steps).astype(int)) - setattr(args, args.plot, steps) - - if args.metrics is None: - args.metrics = sorted(METRICS) - if args.formats is None: - args.formats = sorted(FORMATS) - - results = benchmark( - [METRICS[k] for k in args.metrics], - [FORMATS[k] for k in args.formats], - args.samples, - args.classes, - args.density, - args.n_times, - ) - - _tabulate(results, args.metrics, args.formats) - - if args.plot is not None: - print("Displaying plot", file=sys.stderr) - title = "Multilabel metrics with %s" % ", ".join( - "{0}={1}".format(field, getattr(args, field)) - for field in ["samples", "classes", "density"] - if args.plot != field - ) - _plot(results, args.metrics, args.formats, title, steps, args.plot) From c27576ba8a69672817f026ebc2fbfeead9da3a8f Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Thu, 5 Feb 2026 06:33:37 +0100 Subject: [PATCH 183/462] FIX `n_classes` in DecisionBoundaryDisplay with custom estimators (#33202) Co-authored-by: Lucy Liu --- .../sklearn.inspection/33202.fix.rst | 4 + examples/cluster/plot_inductive_clustering.py | 12 ++- sklearn/inspection/_plot/decision_boundary.py | 37 ++++--- .../tests/test_boundary_decision_display.py | 99 ++++++++++++++++++- 4 files changed, 136 insertions(+), 16 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.inspection/33202.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/33202.fix.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/33202.fix.rst new file mode 100644 index 0000000000000..998fd48b78f22 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.inspection/33202.fix.rst @@ -0,0 +1,4 @@ +- In :class:`inspection.DecisionBoundaryDisplay`, `n_classes` is now inferred more + robustly from the estimator. If it fails for custom estimators, a comprehensive error + message is shown. + By :user:`Anne Beyer `. diff --git a/examples/cluster/plot_inductive_clustering.py b/examples/cluster/plot_inductive_clustering.py index 29846b15cdb60..c4d168afecd58 100644 --- a/examples/cluster/plot_inductive_clustering.py +++ b/examples/cluster/plot_inductive_clustering.py @@ -25,7 +25,7 @@ import matplotlib.pyplot as plt -from sklearn.base import BaseEstimator, clone +from sklearn.base import BaseEstimator, ClusterMixin, clone from sklearn.cluster import AgglomerativeClustering from sklearn.datasets import make_blobs from sklearn.ensemble import RandomForestClassifier @@ -50,7 +50,7 @@ def _classifier_has(attr): ) -class InductiveClusterer(BaseEstimator): +class InductiveClusterer(ClusterMixin, BaseEstimator): def __init__(self, clusterer, classifier): self.clusterer = clusterer self.classifier = classifier @@ -60,6 +60,7 @@ def fit(self, X, y=None): self.classifier_ = clone(self.classifier) y = self.clusterer_.fit_predict(X) self.classifier_.fit(X, y) + self.labels_ = y return self @available_if(_classifier_has("predict")) @@ -122,7 +123,12 @@ def plot_scatter(X, color, alpha=0.5): # Plotting decision regions DecisionBoundaryDisplay.from_estimator( - inductive_learner, X, response_method="predict", alpha=0.4, ax=ax + inductive_learner, + X, + response_method="predict", + multiclass_colors="viridis", + alpha=0.4, + ax=ax, ) plt.title("Classify unknown instances") diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index 2f7175fbd7446..224f30bc96ca3 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -12,6 +12,7 @@ from sklearn.utils._optional_dependencies import check_matplotlib_support from sklearn.utils._response import _get_response_values from sklearn.utils._set_output import _get_adapter_from_container +from sklearn.utils.multiclass import type_of_target from sklearn.utils.validation import ( _is_arraylike_not_scalar, _num_features, @@ -576,6 +577,31 @@ def from_estimator( encoder.classes_ = estimator.classes_ response = encoder.transform(response) + # infer n_classes from the estimator + if ( + class_of_interest is not None + or is_regressor(estimator) + or is_outlier_detector(estimator) + ): + n_classes = 2 + elif is_classifier(estimator) and hasattr(estimator, "classes_"): + n_classes = len(estimator.classes_) + elif is_clusterer(estimator) and hasattr(estimator, "labels_"): + n_classes = len(np.unique(estimator.labels_)) + else: + target_type = type_of_target(response) + if target_type in ("binary", "continuous"): + n_classes = 2 + elif target_type == "multiclass": + n_classes = len(np.unique(response)) + else: + raise ValueError( + "Number of classes or labels cannot be inferred from " + f"{estimator.__class__.__name__}. Please make sure your estimator " + "follows scikit-learn's estimator API as described here: " + "https://scikit-learn.org/stable/developers/develop.html#rolling-your-own-estimator" + ) + if response.ndim == 1: response = response.reshape(*xx0.shape) else: @@ -591,17 +617,6 @@ def from_estimator( else: response = response.reshape(*xx0.shape, response.shape[-1]) - if ( - class_of_interest is not None - or is_regressor(estimator) - or is_outlier_detector(estimator) - ): - n_classes = 2 - elif is_classifier(estimator): - n_classes = len(estimator.classes_) - elif is_clusterer(estimator): - n_classes = len(np.unique(estimator.labels_)) - if xlabel is None: xlabel = X.columns[0] if hasattr(X, "columns") else "" diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index 4e212e7467384..cbc1a377aa971 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -19,7 +19,8 @@ from sklearn.inspection import DecisionBoundaryDisplay from sklearn.inspection._plot.decision_boundary import _check_boundary_response_method from sklearn.linear_model import LogisticRegression -from sklearn.preprocessing import scale +from sklearn.pipeline import Pipeline +from sklearn.preprocessing import StandardScaler, scale from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor from sklearn.utils._testing import ( _convert_container, @@ -703,6 +704,34 @@ def test_multiclass_colors_cmap( # assert len(disp.surface_.levels) >= disp.n_classes +# estimator classes for non-regression test cases for issue #33194 +class CustomBinaryEstimator(BaseEstimator): + def fit(self, X, y): + self.fitted_ = True + return self + + def predict(self, X): + return np.arange(X.shape[0]) % 2 + + +class CustomMulticlassEstimator(BaseEstimator): + def fit(self, X, y): + self.fitted_ = True + return self + + def predict(self, X): + return np.arange(X.shape[0]) % 7 + + +class CustomContinuousEstimator(BaseEstimator): + def fit(self, X, y): + self.fitted_ = True + return self + + def predict(self, X): + return np.arange(X.shape[0]) * 0.5 + + @pytest.mark.parametrize( "estimator, n_blobs, expected_n_classes", [ @@ -712,12 +741,57 @@ def test_multiclass_colors_cmap( (KMeans(n_clusters=2, random_state=0), 2, 2), (DecisionTreeRegressor(random_state=0), 7, 2), (IsolationForest(random_state=0), 7, 2), + (CustomBinaryEstimator(), 2, 2), + (CustomMulticlassEstimator(), 7, 7), + (CustomContinuousEstimator(), 7, 2), + ( + Pipeline( + [ + ("scale", StandardScaler()), + ("dt", DecisionTreeClassifier(random_state=0)), + ] + ), + 7, + 7, + ), + # non-regression test case for issue #33194 + ( + Pipeline( + [ + ("scale", StandardScaler()), + ("kmeans", KMeans(n_clusters=7, random_state=0)), + ] + ), + 7, + 7, + ), + ( + Pipeline( + [ + ("scale", StandardScaler()), + ("reg", DecisionTreeRegressor(random_state=0)), + ] + ), + 7, + 2, + ), + ( + Pipeline( + [ + ("scale", StandardScaler()), + ("kmeans", IsolationForest(random_state=0)), + ] + ), + 7, + 2, + ), ], ) def test_n_classes_attribute(pyplot, estimator, n_blobs, expected_n_classes): """Check that `n_classes` is set correctly. - Introduced in https://github.com/scikit-learn/scikit-learn/pull/33015""" + Introduced in https://github.com/scikit-learn/scikit-learn/pull/33015. + """ X, y = make_blobs(n_samples=150, centers=n_blobs, n_features=2, random_state=42) clf = estimator.fit(X, y) @@ -731,6 +805,27 @@ def test_n_classes_attribute(pyplot, estimator, n_blobs, expected_n_classes): assert disp_coi.n_classes == 2 +def test_n_classes_raises_if_not_inferrable(pyplot): + """Check behaviour if `n_classes` can't be inferred. + + Non-regression test for issue #33194. + """ + + class CustomUnknownEstimator(BaseEstimator): + def fit(self, X, y): + self.fitted_ = True + return self + + def predict(self, X): + return np.array(0) + + X, y = load_iris_2d_scaled() + est = CustomUnknownEstimator().fit(X, y) + msg = "Number of classes or labels cannot be inferred from CustomUnknownEstimator" + with pytest.raises(ValueError, match=msg): + DecisionBoundaryDisplay.from_estimator(est, X, response_method="predict") + + def test_cmap_and_colors_logic(pyplot): """Check the handling logic for `cmap` and `colors`.""" X, y = load_iris_2d_scaled() From 73b45d8e0034994151ce21156bcda2484a884ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quentin=20Barth=C3=A9lemy?= Date: Thu, 5 Feb 2026 13:33:18 +0100 Subject: [PATCH 184/462] ENH update code to check response values of an estimator (#33126) Co-authored-by: Anne Beyer --- .../sklearn.utils/33126.enhancement.rst | 3 + .../tests/test_boundary_decision_display.py | 14 --- sklearn/utils/_response.py | 33 +++---- sklearn/utils/tests/test_response.py | 87 ++++++++++--------- 4 files changed, 57 insertions(+), 80 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/33126.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/33126.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.utils/33126.enhancement.rst new file mode 100644 index 0000000000000..b3bd130028a91 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.utils/33126.enhancement.rst @@ -0,0 +1,3 @@ +- ``sklearn.utils._response._get_response_values`` now provides a clearer error message + when estimator does not implement the given ``response_method``. + By :user:`Quentin Barthélemy `. diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index cbc1a377aa971..19c75407c2ddf 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -397,20 +397,6 @@ def test_multioutput_regressor_error(pyplot): DecisionBoundaryDisplay.from_estimator(tree, X, response_method="predict") -@pytest.mark.parametrize( - "response_method", - ["predict_proba", "decision_function", ["predict_proba", "predict"]], -) -def test_regressor_unsupported_response(pyplot, response_method): - """Check that we can display the decision boundary for a regressor.""" - X, y = load_diabetes(return_X_y=True) - X = X[:, :2] - tree = DecisionTreeRegressor().fit(X, y) - err_msg = "should either be a classifier to be used with response_method" - with pytest.raises(ValueError, match=err_msg): - DecisionBoundaryDisplay.from_estimator(tree, X, response_method=response_method) - - @pytest.mark.filterwarnings( # We expect to raise the following warning because the classifier is fit on a # NumPy array diff --git a/sklearn/utils/_response.py b/sklearn/utils/_response.py index 1344a532c777f..7711f24d0aaae 100644 --- a/sklearn/utils/_response.py +++ b/sklearn/utils/_response.py @@ -120,7 +120,8 @@ def _get_response_values( pos_label=None, return_response_method_used=False, ): - """Compute the response values of a classifier, an outlier detector, or a regressor. + """Compute the response values of a classifier, an outlier detector, a regressor + or a clusterer. The response values are predictions such that it follows the following shape: @@ -129,8 +130,8 @@ def _get_response_values( - with response_method="predict", it is a 1d array of shape `(n_samples,)`; - otherwise, it is a 2d array of shape `(n_samples, n_classes)`; - for multilabel classification, it is a 2d array of shape `(n_samples, n_outputs)`; - - for outlier detection, it is a 1d array of shape `(n_samples,)`; - - for regression, it is a 1d array of shape `(n_samples,)`. + - for outlier detection, a regressor or a clusterer, it is a 1d array of shape + `(n_samples,)`. If `estimator` is a binary classifier, also return the label for the effective positive class. @@ -142,9 +143,9 @@ def _get_response_values( Parameters ---------- estimator : estimator instance - Fitted classifier, outlier detector, or regressor or a + Fitted classifier, outlier detector, regressor, clusterer or a fitted :class:`~sklearn.pipeline.Pipeline` in which the last estimator is a - classifier, an outlier detector, or a regressor. + classifier, an outlier detector, a regressor or a clusterer. X : {array-like, sparse matrix} of shape (n_samples, n_features) Input values. @@ -180,8 +181,8 @@ def _get_response_values( pos_label : int, float, bool, str or None The class considered as the positive class when computing - the metrics. Returns `None` if `estimator` is a regressor or an outlier - detector. + the metrics. Returns `None` if `estimator` is a regressor, an outlier + detector or a clusterer. response_method_used : str The response method used to compute the response values. Only returned @@ -194,13 +195,10 @@ def _get_response_values( ValueError If `pos_label` is not a valid label. If the shape of `y_pred` is not consistent for binary classifier. - If the response method can be applied to a classifier only and - `estimator` is a regressor. """ - from sklearn.base import is_classifier, is_outlier_detector + prediction_method = _check_response_method(estimator, response_method) if is_classifier(estimator): - prediction_method = _check_response_method(estimator, response_method) classes = estimator.classes_ target_type = type_of_target(classes) @@ -229,18 +227,7 @@ def _get_response_values( classes=classes, pos_label=pos_label, ) - elif is_outlier_detector(estimator): - prediction_method = _check_response_method(estimator, response_method) - y_pred, pos_label = prediction_method(X), None - else: # estimator is a regressor - if response_method != "predict": - raise ValueError( - f"{estimator.__class__.__name__} should either be a classifier to be " - f"used with response_method={response_method} or the response_method " - "should be 'predict'. Got a regressor with response_method=" - f"{response_method} instead." - ) - prediction_method = estimator.predict + else: y_pred, pos_label = prediction_method(X), None if return_response_method_used: diff --git a/sklearn/utils/tests/test_response.py b/sklearn/utils/tests/test_response.py index 199ed7f1beb4b..59896a06ed2f2 100644 --- a/sklearn/utils/tests/test_response.py +++ b/sklearn/utils/tests/test_response.py @@ -4,21 +4,17 @@ import pytest from sklearn.base import clone +from sklearn.cluster import DBSCAN, KMeans from sklearn.datasets import ( load_iris, make_classification, make_multilabel_classification, - make_regression, ) from sklearn.ensemble import IsolationForest -from sklearn.linear_model import ( - LinearRegression, - LogisticRegression, -) +from sklearn.linear_model import LinearRegression, LogisticRegression from sklearn.multioutput import ClassifierChain from sklearn.preprocessing import scale from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor -from sklearn.utils._mocking import _MockEstimatorOnOffPrediction from sklearn.utils._response import _get_response_values, _get_response_values_binary from sklearn.utils._testing import assert_allclose, assert_array_equal @@ -29,48 +25,51 @@ @pytest.mark.parametrize( - "response_method", ["decision_function", "predict_proba", "predict_log_proba"] + "estimator, response_method", + [ + (DecisionTreeRegressor(), "predict_proba"), + (DecisionTreeRegressor(), ["predict_proba", "decision_function"]), + (KMeans(n_clusters=2, n_init=1), "predict_proba"), + (KMeans(n_clusters=2, n_init=1), ["predict_proba", "decision_function"]), + (DBSCAN(), "predict"), + (IsolationForest(random_state=0), "predict_proba"), + (IsolationForest(random_state=0), ["predict_proba", "score"]), + ], ) -def test_get_response_values_regressor_error(response_method): - """Check the error message with regressor an not supported response - method.""" - my_estimator = _MockEstimatorOnOffPrediction(response_methods=[response_method]) - X = "mocking_data", "mocking_target" - err_msg = f"{my_estimator.__class__.__name__} should either be a classifier" - with pytest.raises(ValueError, match=err_msg): - _get_response_values(my_estimator, X, response_method=response_method) - - -@pytest.mark.parametrize("return_response_method_used", [True, False]) -def test_get_response_values_regressor(return_response_method_used): - """Check the behaviour of `_get_response_values` with regressor.""" - X, y = make_regression(n_samples=10, random_state=0) - regressor = LinearRegression().fit(X, y) - results = _get_response_values( - regressor, - X, - response_method="predict", - return_response_method_used=return_response_method_used, - ) - assert_array_equal(results[0], regressor.predict(X)) - assert results[1] is None - if return_response_method_used: - assert results[2] == "predict" +def test_estimator_unsupported_response(pyplot, estimator, response_method): + """Check the error message with not supported response method.""" + X, y = np.random.RandomState(0).randn(10, 2), np.array([0, 1] * 5) + estimator.fit(X, y) + err_msg = "has none of the following attributes:" + with pytest.raises(AttributeError, match=err_msg): + _get_response_values( + estimator, + X, + response_method=response_method, + ) @pytest.mark.parametrize( - "response_method", - ["predict", "decision_function", ["decision_function", "predict"]], + "estimator, response_method", + [ + (LinearRegression(), "predict"), + (KMeans(n_clusters=2, n_init=1), "predict"), + (KMeans(n_clusters=2, n_init=1), "score"), + (KMeans(n_clusters=2, n_init=1), ["predict", "score"]), + (IsolationForest(random_state=0), "predict"), + (IsolationForest(random_state=0), "decision_function"), + (IsolationForest(random_state=0), ["decision_function", "predict"]), + ], ) @pytest.mark.parametrize("return_response_method_used", [True, False]) -def test_get_response_values_outlier_detection( - response_method, return_response_method_used +def test_estimator_get_response_values( + estimator, response_method, return_response_method_used ): - """Check the behaviour of `_get_response_values` with outlier detector.""" - X, y = make_classification(n_samples=50, random_state=0) - outlier_detector = IsolationForest(random_state=0).fit(X, y) + """Check the behaviour of `_get_response_values`.""" + X, y = np.random.RandomState(0).randn(10, 2), np.array([0, 1] * 5) + estimator.fit(X, y) results = _get_response_values( - outlier_detector, + estimator, X, response_method=response_method, return_response_method_used=return_response_method_used, @@ -78,7 +77,7 @@ def test_get_response_values_outlier_detection( chosen_response_method = ( response_method[0] if isinstance(response_method, list) else response_method ) - prediction_method = getattr(outlier_detector, chosen_response_method) + prediction_method = getattr(estimator, chosen_response_method) assert_array_equal(results[0], prediction_method(X)) assert results[1] is None if return_response_method_used: @@ -417,6 +416,8 @@ def test_response_values_type_of_target_on_classes_no_warning(): (IsolationForest(), "predict", "multiclass", (10,)), (DecisionTreeRegressor(), "predict", "binary", (10,)), (DecisionTreeRegressor(), "predict", "multiclass", (10,)), + (KMeans(n_clusters=2, n_init=1), "predict", "binary", (10,)), + (KMeans(n_clusters=2, n_init=1), "predict", "multiclass", (10,)), ], ) def test_response_values_output_shape_( @@ -430,8 +431,8 @@ def test_response_values_output_shape_( - with response_method="predict", it is a 1d array of shape `(n_samples,)`; - otherwise, it is a 2d array of shape `(n_samples, n_classes)`; - for multilabel classification, it is a 2d array of shape `(n_samples, n_outputs)`; - - for outlier detection, it is a 1d array of shape `(n_samples,)`; - - for regression, it is a 1d array of shape `(n_samples,)`. + - for outlier detection, regression and clustering, + it is a 1d array of shape `(n_samples,)`. """ X = np.random.RandomState(0).randn(10, 2) if target_type == "binary": From 27a3b6d64a379ff8fe2164fde5ad8ef194b9e3c6 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Thu, 5 Feb 2026 16:28:06 +0100 Subject: [PATCH 185/462] MAINT use the rapidsai channel first in the CUDA CI config (#33212) --- ...a_forge_cuda_array-api_linux-64_conda.lock | 84 ++++++++++--------- ...ge_cuda_array-api_linux-64_environment.yml | 3 +- .../update_environments_and_lock_files.py | 4 +- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 7e18aeb5d3018..9703e88ca69ea 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 8bd38cbfb6761e42fe9b9ed474c118b28133f54feacf11682feab65d79c6c311 +# input_hash: fe79c472e9c028c3b054f565da29f7c4ae75aa209b99c5d4c71e227962497228 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/cuda-version-12.9-h4f385c5_3.conda#b6d5d7f1c171cbd228ea06b556cfa859 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 @@ -30,7 +30,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libnvptxcompiler-dev-12.9.86-ha770c72_2.conda#3fd926c321c6dbf386aa14bd8b125bfb https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 @@ -44,8 +44,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 @@ -53,7 +53,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb9d3cd8_0.conda#db63358239cbe1ff86242406d440e44a https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 @@ -93,12 +93,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libnvjitlink-12.9.86-hecca717_2.conda#3461b0f2d5cbb7973d361f9e85241d98 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -106,7 +106,7 @@ https://conda.anaconda.org/conda-forge/linux-64/nccl-2.29.2.1-h4d09622_1.conda#c https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 -https://conda.anaconda.org/rapidsai/linux-64/rapids-logger-0.1.1-h98325ef_0.conda#e22516a87ac1fb1ea6bf0aa6a18e9d30 +https://conda.anaconda.org/rapidsai/linux-64/rapids-logger-0.2.3-h98325ef_0.conda#81257f29bfcc1e58f0405d7bc9feb309 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.2-he8a4886_1.conda#bade189a194e66b93c03021bd36c337b https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb @@ -115,7 +115,7 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.con https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-hdaf4b65_5.conda#132e8f8f40f0ffc0bbde12bb4e8dd1a1 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 @@ -125,7 +125,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_ https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.conda#af0df9bc982b5ed2c67e8f5062d1f8c1 https://conda.anaconda.org/conda-forge/linux-64/libcurand-dev-10.3.10.19-h676940d_1.conda#fc716aaff5af15b80ccbd28b3e67672c @@ -136,7 +136,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.con https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-openmp_hd680484_4.conda#c0512e4f60d62ccccb4c3c8333b33608 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_4.conda#07479fc04ba3ddd5d9f760ef1635cfa7 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h7b12aa8_0.conda#a30848ebf39327ea078cf26d114cff53 -https://conda.anaconda.org/rapidsai/linux-64/librmm-25.08.00-cuda12_250806_63a4d366.conda#8825b9080d25244f21b7fe18ef25f78c +https://conda.anaconda.org/rapidsai/linux-64/librmm-26.02.00-cuda12_260204_498dafcf.conda#057e94dab29e9c69b4542eb0c61b161e https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-258.3-h6569c3e_0.conda#68294614784925a7c1427835dbe217d7 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef @@ -167,13 +167,13 @@ https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2 https://conda.anaconda.org/conda-forge/linux-64/libcusparse-dev-12.5.10.65-hecca717_2.conda#db94469fbd554c107acc3afd0af5d8ec https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-25.08.00-cuda12_250806_2fb92393.conda#ac979638ede39fa80829d6a346405ab2 +https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-26.02.00-cuda12_260204_c212ab9b.conda#702a98df50c3b8be134516647a217fde https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-openmp_hd77311e_4.conda#525e2455ed342f2aef93c59ac5db2e28 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-h19cb568_0.conda#a98b8d7cfdd20004f1bdd1a51cb22c58 -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_101_cp313.conda#aa23b675b860f2566af2dfb3ffdf3b8c +https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_0.conda#0227d04521bc3d28c7995c7e1f99a721 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 @@ -185,7 +185,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.3-hef928c7_0.cond https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-hc63082f_11.conda#6a653aefdc5d83a4f959869d1759e6e3 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda#1d4e0d37da5f3c22ecd44033f673feba https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_101.conda#c74a6b9e8694e5122949f611d1552df5 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.3.3-pyhcf101f3_0.conda#b08fa4a3478526e33a4c08224398d2e5 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a @@ -205,17 +205,18 @@ https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_open https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 +https://conda.anaconda.org/conda-forge/linux-64/llvmlite-0.44.0-py313hfdae721_2.conda#dd0d7947635c0c524608eab7db55dcc9 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-12.575.51-pyhd8ed1ab_0.conda#90600980e7240e1d6fdc97c1f32f57af +https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.590.48-pyhd8ed1ab_0.conda#fda409cefdbd417f9ca4e072c39add77 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py313h80991f8_0.conda#183fe6b9e99e5c2b464c1573ec78eac8 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda#f08a17c938eb6bc1b928bd8cdd37e20f +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 @@ -228,9 +229,9 @@ https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.4-py313hd02dea0_0.conda#442d7ac35e5d6bc89eba2998a9e1de06 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/linux-64/ucx-1.18.1-h990bcc0_2.conda#15e5ae8dc2c3a57a9cd77aa40dedfd40 +https://conda.anaconda.org/conda-forge/linux-64/ucx-1.20.0-hbe80e26_1.conda#ffdaec09a7c09710040eb9e613f8c531 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 @@ -239,7 +240,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.3-h06ab39a_1.conda#3689a4290319587e3b54a4f9e68f70c8 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda#4e921d9c85e6559c60215497978b3cdb https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-h3d7a050_0.conda#e6f12de3a9b016cea81a87db04d85ff3 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.2-py313h3dea7bd_0.conda#df05169cc886aaf53dc560db634519f8 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.3-py313h3dea7bd_0.conda#fa90494c873b21b3bdb21c3b588ff043 https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.5-py313h929d4db_0.conda#f2416964cdb2808dd2ed5be276a8fcdb https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee @@ -247,21 +248,20 @@ https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py313h3dea7bd_0 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_2.conda#3c71daed530c0c26671a1b1b7010e746 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_2.conda#0ad9019bb10eda915fb0ce5f78fef13b +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d -https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.45.01-cuda12_250806_c25d2cdb.conda#84eff90bd9369d4b654434b1ea354ec4 -https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py313hf6604e3_0.conda#a61bd1412975145dd688a71849b63d97 +https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 +https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff -https://conda.anaconda.org/conda-forge/noarch/pynvml-12.0.0-pyhd8ed1ab_0.conda#27a6f747d629815308c2d7e4f17aca4c https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.11-h4df99d1_101.conda#4af7a72062bddcb57dea6b236e1b245e +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.12-h4df99d1_100.conda#3d92938d5b83c49162ade038aab58a59 https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py313h246eb7c_0.conda#932203205c4cf6f661180b98a48f195a https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f @@ -272,44 +272,48 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0- https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 +https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.5.1-cuda12_py313hacc9b55_1.conda#808c80c320dfd77ba5da9f6a35b07503 https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.5-pyh698daf1_0.conda#a4fb0d4ffdac1cf2cda9318d2f789d20 -https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.4.1-py313h2626f57_0.conda#61b65ec6afaf6bf07e50bf32d4363461 +https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.6.0-py313h28b6081_2.conda#388fb72307f756f7f2c7f5928647bc6b https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_ha70ccd2_201.conda#8ecb348d9f4c748e79afa17308d23d49 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 +https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.conda#84cef0ce56c6db53edb3f8b83bdbb364 https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py313hbfd7664_0.conda#ab6d05e915ab2ae4c41d275b14592151 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py313h4b8bb8b_1.conda#2b18fe5b4b2d1611ddf8c2f080a46563 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10.conda#937d1d4c233adc6eeb2ac3d6e9a73e53 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-hd454692_0.conda#55986e49b7aafe9aa09d7f4c70a56a18 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 -https://conda.anaconda.org/conda-forge/linux-64/cupy-13.4.1-py313hdf5e20e_0.conda#b5bab25cd2f86d0425fbac36b75ea9bc +https://conda.anaconda.org/conda-forge/linux-64/cupy-13.6.0-py313h586c94b_2.conda#0685ae3980f823b2ca78552f7d8d4033 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.1-py310hffdcd12_0.conda#732a536c6ce768f096f5340121e10cc5 +https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.0-py310hffdcd12_0.conda#55bba24eb42fccab68125573fe3e702e https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_h673abb8_201.conda#f8dae51be1b9afdccd70b576b8f73b44 -https://conda.anaconda.org/rapidsai/linux-64/rmm-25.08.00-cuda12_py313_250806_63a4d366.conda#967087ac0c607d3118d4b162978a76f4 +https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h2c50142_1_cpu.conda#fba261a7ee565b711b45c5bea554e5a0 -https://conda.anaconda.org/conda-forge/noarch/polars-1.37.1-pyh6a1acc5_0.conda#1894d4373da653406c91e20ef89f05c8 +https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda#d9f44a3b02ff198d40562d05e758ad03 https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_201.conda#fb17e944f1ff5c1ab65822ba1f539b9d -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-hb82b983_4.conda#f4dfd61ec958d420bebdcefeb805d658 -https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.45.01-cuda12_py313_250806_c25d2cdb.conda#f9c5b31a6977929e9aa288feffd6fc7a +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 +https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h8c2c5c3_1_cpu.conda#102be5396c7899675268c17993e1a072 https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_1_cpu.conda#e7562d15926b3cea66a6e3546b133c5d -https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-25.08.00-cuda12_250806_2fb92393.conda#cbcb008978b2e7fd29995b8de4b4e7f2 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py313h85046ba_0.conda#2c5d21d466ef1ff0c0a98cfdbaf5c64b +https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313h85046ba_0.conda#f6161781ceb86e9f5da1b532e4c4453c https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_1_cpu.conda#8b1290b259b24a4b29b3a3d6dec0fe53 -https://conda.anaconda.org/rapidsai/linux-64/libcuvs-25.08.00-cuda12_250806_9ce11a0f.conda#864f524cef608705031c54db01fb31d9 -https://conda.anaconda.org/rapidsai/linux-64/libraft-25.08.00-cuda12_250806_2fb92393.conda#cf1d59daaaa86e2d5841f6ce9fc2a10d +https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be +https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py313he109ebe_0_cpu.conda#9120bf253ebbdb0015069b9a25cf4d36 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_1_cpu.conda#651c34402277a875986db6fa7930d42d -https://conda.anaconda.org/rapidsai/linux-64/pylibraft-25.08.00-cuda12_py313_250806_2fb92393.conda#a4e3e89406631b9c5fe94e1971bdc049 -https://conda.anaconda.org/rapidsai/linux-64/cuvs-25.08.00-cuda12_py313_250806_9ce11a0f.conda#beec28b5e042219ff268caecc852ec2f +https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.02.00-cuda12_260204_a2f5a8b7.conda#361cae27e77618c6ba9f943807471f9f +https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.02.00-cuda12_py313_260204_c212ab9b.conda#14933b753ec82f9d5a61d7cb4b5e2e71 +https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.02.00-cuda12_py313_260204_a2f5a8b7.conda#c46807878ad576379e7be3acc187d13a https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-h3f74fd7_1_cpu.conda#bcf3ca0f04ed703121db4012e8c8bf5a https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.0-py313h78bf25f_0.conda#a6e89cb214f318db9548b791ba27f862 diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml index d362ece646955..26e06923e0f90 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml @@ -2,6 +2,7 @@ # following script to centralize the configuration for CI builds: # build_tools/update_environments_and_lock_files.py channels: + - rapidsai - conda-forge dependencies: - python @@ -27,5 +28,5 @@ dependencies: - polars - pyarrow - cupy - - rapidsai::cuvs + - cuvs - array-api-strict diff --git a/build_tools/update_environments_and_lock_files.py b/build_tools/update_environments_and_lock_files.py index f9e439cdb2fe1..731b8bb91a08c 100644 --- a/build_tools/update_environments_and_lock_files.py +++ b/build_tools/update_environments_and_lock_files.py @@ -101,7 +101,7 @@ def remove_from(alist, to_remove): "tag": "cuda", "folder": "build_tools/github", "platform": "linux-64", - "channels": ["conda-forge"], + "channels": ["rapidsai", "conda-forge"], "conda_dependencies": common_dependencies + [ "ccache", @@ -110,7 +110,7 @@ def remove_from(alist, to_remove): "pyarrow", "cupy", # cuvs is needed for cupyx.scipy.spatial.distance.cdist and friends - "rapidsai::cuvs", + "cuvs", "array-api-strict", ], "virtual_package_spec": True, From 95f13b05c73466a322e3d2119f146f5e77a8ee3c Mon Sep 17 00:00:00 2001 From: Ram <144999593+atheendre130505@users.noreply.github.com> Date: Thu, 5 Feb 2026 21:50:09 +0530 Subject: [PATCH 186/462] FIX Remove redundant yield of check_class_weight_balanced_linear_classifier (#33197) --- sklearn/utils/estimator_checks.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index d0e2adb089d9d..689df6b616189 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -240,9 +240,6 @@ def _yield_classifier_checks(classifier): # test if predict_proba is a monotonic transformation of decision_function yield check_decision_proba_consistency - if isinstance(classifier, LinearClassifierMixin): - if "class_weight" in classifier.get_params().keys(): - yield check_class_weight_balanced_linear_classifier if ( isinstance(classifier, LinearClassifierMixin) and "class_weight" in classifier.get_params().keys() From 55974cb1b6144d7af1a04cf223afc8d954a21dc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Thu, 5 Feb 2026 19:10:48 +0100 Subject: [PATCH 187/462] CI Have the name of the failing build in the tracking issue (#33203) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- .github/workflows/unit-tests.yml | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 4f5b64f83b518..a6350b56f417d 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -227,12 +227,21 @@ jobs: - name: Checkout uses: actions/checkout@v6 + # This step is necessary to access the job name the same way in both matrix and + # non-matrix jobs (like free-threaded or scipy-dev builds). + - name: Set JOB_NAME variable + shell: bash + run: | + if [[ -z "$JOB_NAME" ]]; then + echo "JOB_NAME=${{ matrix.name }}" >> $GITHUB_ENV + fi + - name: Create cache for ccache uses: actions/cache@v5 with: path: ${{ env.CCACHE_DIR }} - key: ccache-v1-${{ matrix.name }}-${{ hashFiles('**/*.pyx*', '**/*.pxd*', '**/*.pxi*', '**/*.h', '**/*.c', '**/*.cpp', format('{0}', matrix.LOCK_FILE)) }} - restore-keys: ccache-${{ matrix.name }} + key: ccache-v1-${{ env.JOB_NAME }}-${{ hashFiles('**/*.pyx*', '**/*.pxd*', '**/*.pxi*', '**/*.h', '**/*.c', '**/*.cpp', format('{0}', env.LOCK_FILE)) }} + restore-keys: ccache-${{ env.JOB_NAME }} - name: Set up conda uses: conda-incubator/setup-miniconda@v3 @@ -286,15 +295,15 @@ jobs: pip install defusedxml PyGithub python maint_tools/update_tracking_issue.py \ ${{ secrets.BOT_GITHUB_TOKEN }} \ - "$GITHUB_WORKFLOW ${{ matrix.name }}" \ + "$GITHUB_WORKFLOW $JOB_NAME" \ "$GITHUB_REPOSITORY" \ https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID \ --junit-file $TEST_DIR/$JUNITXML \ --auto-close false \ - --job-name "${{ matrix.name }}" + --job-name "$JOB_NAME" free-threaded: - name: Linux x86-64 pylatest_free_threaded + name: &free-threaded-job-name Linux x86-64 pylatest_free_threaded runs-on: ubuntu-latest needs: [lint, retrieve-commit-message, retrieve-selected-tests] if: contains(needs.retrieve-commit-message.outputs.message, '[free-threaded]') || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' @@ -304,10 +313,12 @@ jobs: COVERAGE: false # Disable pytest-xdist to use multiple cores for stress-testing with pytest-run-parallel PYTEST_XDIST_VERSION: none + # To be able to access the job name in the steps, it must be set as an env variable. + JOB_NAME: *free-threaded-job-name steps: *unit-tests-steps scipy-dev: - name: Linux x86-64 pylatest_pip_scipy_dev + name: &scipy-dev-job-name Linux x86-64 pylatest_pip_scipy_dev runs-on: ubuntu-22.04 needs: [lint, retrieve-commit-message, retrieve-selected-tests] if: contains(needs.retrieve-commit-message.outputs.message, '[scipy-dev]') || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' @@ -316,4 +327,6 @@ jobs: LOCK_FILE: build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock SKLEARN_WARNINGS_AS_ERRORS: 1 CHECK_PYTEST_SOFT_DEPENDENCY: true + # To be able to access the job name in the steps, it must be set as an env variable. + JOB_NAME: *scipy-dev-job-name steps: *unit-tests-steps From 0932d7e2b34fa9d86561e03b1b3b0c1f91776628 Mon Sep 17 00:00:00 2001 From: Shruti Nath <51656807+snath-xoc@users.noreply.github.com> Date: Fri, 6 Feb 2026 12:08:45 +0300 Subject: [PATCH 188/462] Fix MinibatchKMeans minibatch_indices creation (#30751) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger Co-authored-by: Olivier Grisel --- .../sklearn.cluster/30751.fix.rst | 6 +++++ sklearn/cluster/_kmeans.py | 26 ++++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.cluster/30751.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.cluster/30751.fix.rst b/doc/whats_new/upcoming_changes/sklearn.cluster/30751.fix.rst new file mode 100644 index 0000000000000..f1ebdbd79d46f --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.cluster/30751.fix.rst @@ -0,0 +1,6 @@ +- :class:`cluster.MiniBatchKMeans` now correctly handles sample weights + during fitting. When sample weights are not None, mini-batch + indices are created by sub-sampling with replacement using the + normalized sample weights as probabilities. + By :user:`Shruti Nath `, :user:`Olivier Grisel `, + and :user:`Jeremie du Boisberranger `. diff --git a/sklearn/cluster/_kmeans.py b/sklearn/cluster/_kmeans.py index 002df2ca56414..aa7f86d3d3cb5 100644 --- a/sklearn/cluster/_kmeans.py +++ b/sklearn/cluster/_kmeans.py @@ -1876,8 +1876,8 @@ class MiniBatchKMeans(_BaseKMeans): ... max_iter=10, ... n_init="auto").fit(X) >>> kmeans.cluster_centers_ - array([[3.55102041, 2.48979592], - [1.06896552, 1. ]]) + array([[3.20967742, 3.56451613], + [1.32758621, 0.77586207]]) >>> kmeans.predict([[0, 0], [4, 4]]) array([1, 0], dtype=int32) @@ -2153,18 +2153,32 @@ def fit(self, X, y=None, sample_weight=None): # Initialize number of samples seen since last reassignment self._n_since_last_reassign = 0 + sum_of_weights = np.sum(sample_weight) + n_steps = (self.max_iter * n_samples) // self._batch_size + normalized_sample_weight = sample_weight / sum_of_weights + unit_sample_weight = np.ones_like(sample_weight, shape=(self._batch_size,)) with _get_threadpool_controller().limit(limits=1, user_api="blas"): # Perform the iterative optimization until convergence for i in range(n_steps): # Sample a minibatch from the full dataset - minibatch_indices = random_state.randint(0, n_samples, self._batch_size) - + minibatch_indices = random_state.choice( + n_samples, + self._batch_size, + p=normalized_sample_weight, + replace=True, + ) # Perform the actual update step on the minibatch data + # Note: since the sampling of the minibatch is sample_weight aware, + # we pass fixed unit weights to the `_mini_batch_step` call to avoid + # accounting for the weights twice. Also note that `_mini_batch_step` + # can be called with non-unit weights when the caller constructs + # the batches explicitly by calling the public `partial_fit` method + # instead. batch_inertia = _mini_batch_step( X=X[minibatch_indices], - sample_weight=sample_weight[minibatch_indices], + sample_weight=unit_sample_weight, centers=centers, centers_new=centers_new, weight_sums=self._counts, @@ -2202,7 +2216,7 @@ def fit(self, X, y=None, sample_weight=None): n_threads=self._n_threads, ) else: - self.inertia_ = self._ewa_inertia * n_samples + self.inertia_ = self._ewa_inertia * sum_of_weights return self From 2b2ac3abb59b3774bcb76c29675fb10343676011 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Fri, 6 Feb 2026 20:29:29 +1100 Subject: [PATCH 189/462] TST Add `CalibrationDisplay` to `test_common_curve_display.py` (#33217) --- .../_plot/tests/test_common_curve_display.py | 71 +++++++------------ 1 file changed, 24 insertions(+), 47 deletions(-) diff --git a/sklearn/metrics/_plot/tests/test_common_curve_display.py b/sklearn/metrics/_plot/tests/test_common_curve_display.py index 675cb26e17fba..f3499ba53cd0a 100644 --- a/sklearn/metrics/_plot/tests/test_common_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_common_curve_display.py @@ -34,9 +34,8 @@ def data_binary(data): "Display", [CalibrationDisplay, DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay], ) -def test_display_curve_error_classifier(pyplot, data, data_binary, Display): - """Check that a proper error is raised when only binary classification is - supported.""" +def test_display_curve_error_binary_classifier(pyplot, data, data_binary, Display): + """Check correct error raised when only binary classification supported.""" X, y = data X_binary, y_binary = data_binary clf = DecisionTreeClassifier().fit(X, y) @@ -110,15 +109,14 @@ def test_display_curve_error_regression(pyplot, data_binary, Display): @pytest.mark.parametrize( "Display", [DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay] ) -def test_display_curve_error_no_response( +def test_display_curve_error_no_response_method( pyplot, data_binary, response_method, msg, Display, ): - """Check that a proper error is raised when the response method requested - is not defined for the given trained classifier.""" + """Check error raised when `response_method` not defined for `estimator`.""" X, y = data_binary class MyClassifier(ClassifierMixin, BaseEstimator): @@ -133,17 +131,17 @@ def fit(self, X, y): @pytest.mark.parametrize( - "Display", [DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay] + "Display", + [CalibrationDisplay, DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay], ) @pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) -def test_display_curve_estimator_name_multiple_calls( +def test_display_curve_name_overwritten_by_plot_multiple_calls( pyplot, data_binary, Display, constructor_name, ): - """Check that passing `name` when calling `plot` will overwrite the original name - in the legend.""" + """Check passing `name` in `plot` overwrites name passed in `from_*` method.""" X, y = data_binary clf_name = "my hand-crafted name" clf = LogisticRegression().fit(X, y) @@ -181,11 +179,11 @@ def test_display_curve_estimator_name_multiple_calls( ], ) @pytest.mark.parametrize( - "Display", [DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay] + "Display", + [CalibrationDisplay, DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay], ) -def test_display_curve_not_fitted_errors_old_name(pyplot, data_binary, clf, Display): - """Check that a proper error is raised when the classifier is not - fitted.""" +def test_display_curve_not_fitted_errors(pyplot, data_binary, clf, Display): + """Check correct error raised when `estimator` is not fitted.""" X, y = data_binary # clone since we parametrize the test and the classifier will be fitted # when testing the second and subsequent plotting function @@ -203,36 +201,11 @@ def test_display_curve_not_fitted_errors_old_name(pyplot, data_binary, clf, Disp @pytest.mark.parametrize( - "clf", - [ - LogisticRegression(), - make_pipeline(StandardScaler(), LogisticRegression()), - make_pipeline( - make_column_transformer((StandardScaler(), [0, 1])), LogisticRegression() - ), - ], -) -@pytest.mark.parametrize("Display", [RocCurveDisplay]) -def test_display_curve_not_fitted_errors(pyplot, data_binary, clf, Display): - """Check that a proper error is raised when the classifier is not fitted.""" - X, y = data_binary - # clone since we parametrize the test and the classifier will be fitted - # when testing the second and subsequent plotting function - model = clone(clf) - with pytest.raises(NotFittedError): - Display.from_estimator(model, X, y) - model.fit(X, y) - disp = Display.from_estimator(model, X, y) - assert model.__class__.__name__ in disp.line_.get_label() - assert disp.name == model.__class__.__name__ - - -@pytest.mark.parametrize( - "Display", [DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay] + "Display", + [CalibrationDisplay, DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay], ) def test_display_curve_n_samples_consistency(pyplot, data_binary, Display): - """Check the error raised when `y_pred` or `sample_weight` have inconsistent - length.""" + """Check error raised when `y_pred` or `sample_weight` have inconsistent length.""" X, y = data_binary classifier = DecisionTreeClassifier().fit(X, y) @@ -241,15 +214,20 @@ def test_display_curve_n_samples_consistency(pyplot, data_binary, Display): Display.from_estimator(classifier, X[:-2], y) with pytest.raises(ValueError, match=msg): Display.from_estimator(classifier, X, y[:-2]) - with pytest.raises(ValueError, match=msg): - Display.from_estimator(classifier, X, y, sample_weight=np.ones(X.shape[0] - 2)) + # `CalibrationDisplay` does not support `sample_weight` + if Display != CalibrationDisplay: + with pytest.raises(ValueError, match=msg): + Display.from_estimator( + classifier, X, y, sample_weight=np.ones(X.shape[0] - 2) + ) @pytest.mark.parametrize( - "Display", [DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay] + "Display", + [CalibrationDisplay, DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay], ) def test_display_curve_error_pos_label(pyplot, data_binary, Display): - """Check consistence of error message when `pos_label` should be specified.""" + """Check consistency of error message when `pos_label` should be specified.""" X, y = data_binary y = y + 10 @@ -302,7 +280,6 @@ class SubclassOfDisplay(Display): assert isinstance(curve, SubclassOfDisplay) -# TODO(1.10): Remove once deprecated in all Displays @pytest.mark.parametrize( "Display, display_kwargs", [ From f22110eddb78896d968d503887834c0958926350 Mon Sep 17 00:00:00 2001 From: Auguste Baum <52001167+augustebaum@users.noreply.github.com> Date: Fri, 6 Feb 2026 10:49:50 +0100 Subject: [PATCH 190/462] CI Move debian-32 build from Azure to GHA (#33063) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- .github/workflows/unit-tests.yml | 116 ++++++++++++++++++++++++- azure-pipelines.yml | 65 -------------- build_tools/azure/posix-docker.yml | 134 ----------------------------- 3 files changed, 113 insertions(+), 202 deletions(-) delete mode 100644 azure-pipelines.yml delete mode 100644 build_tools/azure/posix-docker.yml diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index a6350b56f417d..741d346438af1 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -127,7 +127,7 @@ jobs: DISTRIB: conda LOCK_FILE: build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock - - name: Linuw x86-64 pylatest_conda_forge_mkl + - name: Linux x86-64 pylatest_conda_forge_mkl os: ubuntu-22.04 DISTRIB: conda LOCK_FILE: build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -303,7 +303,8 @@ jobs: --job-name "$JOB_NAME" free-threaded: - name: &free-threaded-job-name Linux x86-64 pylatest_free_threaded + name: &free-threaded-job-name + Linux x86-64 pylatest_free_threaded runs-on: ubuntu-latest needs: [lint, retrieve-commit-message, retrieve-selected-tests] if: contains(needs.retrieve-commit-message.outputs.message, '[free-threaded]') || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' @@ -318,7 +319,8 @@ jobs: steps: *unit-tests-steps scipy-dev: - name: &scipy-dev-job-name Linux x86-64 pylatest_pip_scipy_dev + name: &scipy-dev-job-name + Linux x86-64 pylatest_pip_scipy_dev runs-on: ubuntu-22.04 needs: [lint, retrieve-commit-message, retrieve-selected-tests] if: contains(needs.retrieve-commit-message.outputs.message, '[scipy-dev]') || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' @@ -330,3 +332,111 @@ jobs: # To be able to access the job name in the steps, it must be set as an env variable. JOB_NAME: *scipy-dev-job-name steps: *unit-tests-steps + + debian-32bit: + name: &debian-32bit-job-name + Linux i386 debian_32bit + runs-on: ubuntu-24.04 + needs: [lint, retrieve-commit-message, retrieve-selected-tests] + env: + DISTRIB: debian-32 + LOCK_FILE: build_tools/azure/debian_32bit_lock.txt + SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 4 # non-default seed + DOCKER_CONTAINER: i386/debian:trixie + # To be able to access the job name in the steps, it must be set as an env variable. + JOB_NAME: *debian-32bit-job-name + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Create cache for ccache + uses: actions/cache@v5 + with: + path: ${{ env.CCACHE_DIR }} + key: ccache-v1-${{ env.JOB_NAME }}-${{ hashFiles('**/*.pyx*', '**/*.pxd*', '**/*.pxi*', '**/*.h', '**/*.c', '**/*.cpp', format('{0}', env.LOCK_FILE)) }} + restore-keys: ccache-${{ env.JOB_NAME }} + + - name: Set up conda + uses: conda-incubator/setup-miniconda@v3 + if: ${{ startsWith(env.DISTRIB, 'conda') }} + with: + miniforge-version: latest + auto-activate-base: true + activate-environment: "" + + - name: Set random seed for nightly/manual runs + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + run: echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 100))" >> $GITHUB_ENV + + - name: Start container + # Environment variable are passed when starting the container rather + # than in "Run tests step" for more standard jobs + env: + COMMIT_MESSAGE: ${{ needs.retrieve-commit-message.outputs.message }} + SELECTED_TESTS: ${{ needs.retrieve-selected-tests.outputs.tests }} + COVERAGE: ${{ env.COVERAGE == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}} + run: > + docker container run --rm + --volume $TEST_DIR:/temp_dir + --volume $PWD:/scikit-learn + --volume $CCACHE_DIR:/ccache + -w /scikit-learn + --detach + --name skcontainer + -e TEST_DIR=/temp_dir + -e CCACHE_DIR=/ccache + -e COVERAGE + -e DISTRIB + -e LOCK_FILE + -e JUNITXML + -e VIRTUALENV + -e PYTEST_XDIST_VERSION + -e SKLEARN_SKIP_NETWORK_TESTS + -e SELECTED_TESTS + -e CCACHE_COMPRESS + -e COMMIT_MESSAGE + -e JOB_NAME + -e SKLEARN_TESTS_GLOBAL_RANDOM_SEED + $DOCKER_CONTAINER + sleep 1000000 + + - name: Build scikit-learn + run: docker exec skcontainer bash -l build_tools/azure/install.sh + + - name: Run tests + run: docker exec skcontainer bash -l build_tools/azure/test_script.sh + + - name: Run doctests in .py and .rst files + run: docker exec skcontainer bash -l build_tools/azure/test_docs.sh + if: ${{ needs.retrieve-selected-tests.outputs.tests == ''}} + + - name: Run pytest soft dependency test + run: docker exec skcontainer build_tools/azure/test_pytest_soft_dependency.sh + if: ${{ env.CHECK_PYTEST_SOFT_DEPENDENCY == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}} + + - name: Combine coverage reports from parallel test runners + run: docker exec skcontainer bash -l build_tools/azure/combine_coverage_reports.sh + if: ${{ env.COVERAGE == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}} + + - name: Upload coverage report to Codecov + uses: codecov/codecov-action@v5 + if: ${{ env.COVERAGE == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}} + with: + files: ./coverage.xml + token: ${{ secrets.CODECOV_TOKEN }} + disable_search: true + + - name: Update tracking issue + if: ${{ always() && (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')}} + run: | + set -ex + + pip install defusedxml PyGithub + python maint_tools/update_tracking_issue.py \ + ${{ secrets.BOT_GITHUB_TOKEN }} \ + "$GITHUB_WORKFLOW $JOB_NAME" \ + "$GITHUB_REPOSITORY" \ + https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID \ + --junit-file $TEST_DIR/$JUNITXML \ + --auto-close false \ + --job-name "$JOB_NAME" diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index 233fea5e3dcd6..0000000000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,65 +0,0 @@ -# Adapted from https://github.com/pandas-dev/pandas/blob/master/azure-pipelines.yml -schedules: -- cron: "30 2 * * *" - displayName: Run nightly build - branches: - include: - - main - always: true - -jobs: -- job: git_commit - displayName: Get Git Commit - pool: - vmImage: ubuntu-24.04 - steps: - - bash: python build_tools/azure/get_commit_message.py - name: commit - displayName: Get source version message - -- job: linting - dependsOn: [git_commit] - condition: | - and( - succeeded(), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[lint skip]')), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[ci skip]')) - ) - displayName: Linting - pool: - vmImage: ubuntu-24.04 - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.12' - - bash: | - source build_tools/shared.sh - # Include pytest compatibility with mypy - pip install pytest $(get_dep ruff min) $(get_dep mypy min) cython-lint - displayName: Install linters - - bash: | - ./build_tools/linting.sh - displayName: Run linters - - bash: | - pip install ninja meson scipy - python build_tools/check-meson-openmp-dependencies.py - displayName: Run Meson OpenMP checks - -- template: build_tools/azure/posix-docker.yml - parameters: - name: Linux_Docker - vmImage: ubuntu-24.04 - dependsOn: [linting, git_commit] - # Runs when dependencies succeeded or skipped - condition: | - and( - not(or(failed(), canceled())), - not(contains(dependencies['git_commit']['outputs']['commit.message'], '[ci skip]')) - ) - matrix: - debian_32bit: - DOCKER_CONTAINER: 'i386/debian:trixie' - DISTRIB: 'debian-32' - COVERAGE: "true" - LOCK_FILE: './build_tools/azure/debian_32bit_lock.txt' - SKLEARN_TESTS_GLOBAL_RANDOM_SEED: '4' # non-default seed diff --git a/build_tools/azure/posix-docker.yml b/build_tools/azure/posix-docker.yml deleted file mode 100644 index 8cf4fb75b8345..0000000000000 --- a/build_tools/azure/posix-docker.yml +++ /dev/null @@ -1,134 +0,0 @@ -parameters: - name: '' - vmImage: '' - matrix: [] - dependsOn: [] - condition: ne(variables['Build.Reason'], 'Schedule') - -jobs: -- job: ${{ parameters.name }} - dependsOn: ${{ parameters.dependsOn }} - condition: ${{ parameters.condition }} - timeoutInMinutes: 120 - pool: - vmImage: ${{ parameters.vmImage }} - variables: - VIRTUALENV: 'testvenv' - TEST_DIR: '$(Agent.WorkFolder)/tmp_folder' - JUNITXML: 'test-data.xml' - SKLEARN_SKIP_NETWORK_TESTS: '1' - PYTEST_XDIST_VERSION: 'latest' - COVERAGE: 'false' - # Set in azure-pipelines.yml - DISTRIB: '' - DOCKER_CONTAINER: '' - CREATE_ISSUE_ON_TRACKER: 'true' - CCACHE_DIR: $(Pipeline.Workspace)/ccache - CCACHE_COMPRESS: '1' - strategy: - matrix: - ${{ insert }}: ${{ parameters.matrix }} - - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.9' - addToPath: false - name: pyTools - displayName: Select python version to run CI python scripts - - bash: $(pyTools.pythonLocation)/bin/python build_tools/azure/get_selected_tests.py - displayName: Check selected tests for all random seeds - condition: eq(variables['Build.Reason'], 'PullRequest') - - task: Cache@2 - inputs: - key: '"ccache-v1" | "$(Agent.JobName)" | "$(Build.BuildNumber)"' - restoreKeys: | - "ccache-v1" | "$(Agent.JobName)" - path: $(CCACHE_DIR) - displayName: ccache - continueOnError: true - - script: > - mkdir -p $CCACHE_DIR - # Container is detached and sleeping, allowing steps to run commands - # in the container. The TEST_DIR is mapped allowing the host to access - # the JUNITXML file - - script: > - docker container run --rm - --volume $TEST_DIR:/temp_dir - --volume $BUILD_REPOSITORY_LOCALPATH:/repo_localpath - --volume $PWD:/scikit-learn - --volume $CCACHE_DIR:/ccache - -w /scikit-learn - --detach - --name skcontainer - -e BUILD_SOURCESDIRECTORY=/scikit-learn - -e TEST_DIR=/temp_dir - -e CCACHE_DIR=/ccache - -e BUILD_REPOSITORY_LOCALPATH=/repo_localpath - -e COVERAGE - -e DISTRIB - -e LOCK_FILE - -e JUNITXML - -e VIRTUALENV - -e PYTEST_XDIST_VERSION - -e SKLEARN_SKIP_NETWORK_TESTS - -e SELECTED_TESTS - -e CCACHE_COMPRESS - -e BUILD_SOURCEVERSIONMESSAGE - -e BUILD_REASON - $DOCKER_CONTAINER - sleep 1000000 - displayName: 'Start container' - - script: > - docker exec skcontainer ./build_tools/azure/install.sh - displayName: 'Install' - - script: > - docker exec skcontainer ./build_tools/azure/test_script.sh - displayName: 'Test Library' - - script: > - docker exec skcontainer ./build_tools/azure/combine_coverage_reports.sh - condition: and(succeeded(), eq(variables['COVERAGE'], 'true'), - eq(variables['SELECTED_TESTS'], '')) - displayName: 'Combine coverage' - - task: PublishTestResults@2 - inputs: - testResultsFiles: '$(TEST_DIR)/$(JUNITXML)' - testRunTitle: ${{ format('{0}-$(Agent.JobName)', parameters.name) }} - displayName: 'Publish Test Results' - condition: succeededOrFailed() - - script: > - docker container stop skcontainer - displayName: 'Stop container' - condition: always() - - bash: | - set -ex - if [[ $(BOT_GITHUB_TOKEN) == "" ]]; then - echo "GitHub Token is not set. Issue tracker will not be updated." - exit - fi - - LINK_TO_RUN="https://dev.azure.com/$BUILD_REPOSITORY_NAME/_build/results?buildId=$BUILD_BUILDID&view=logs&j=$SYSTEM_JOBID" - CI_NAME="$SYSTEM_JOBIDENTIFIER" - ISSUE_REPO="$BUILD_REPOSITORY_NAME" - - $(pyTools.pythonLocation)/bin/pip install defusedxml PyGithub - $(pyTools.pythonLocation)/bin/python maint_tools/update_tracking_issue.py \ - $(BOT_GITHUB_TOKEN) \ - $CI_NAME \ - $ISSUE_REPO \ - $LINK_TO_RUN \ - --junit-file $JUNIT_FILE \ - --auto-close false - displayName: 'Update issue tracker' - env: - JUNIT_FILE: $(TEST_DIR)/$(JUNITXML) - condition: and(succeededOrFailed(), eq(variables['CREATE_ISSUE_ON_TRACKER'], 'true'), - eq(variables['Build.Reason'], 'Schedule')) - - bash: bash build_tools/azure/upload_codecov.sh - condition: and(succeeded(), eq(variables['COVERAGE'], 'true'), - eq(variables['SELECTED_TESTS'], '')) - displayName: 'Upload To Codecov' - retryCountOnTaskFailure: 5 - env: - CODECOV_TOKEN: $(CODECOV_TOKEN) - JUNIT_FILE: $(TEST_DIR)/$(JUNITXML) From bf223d9c21d3f85de90592f69b9a8710fecbc939 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Fri, 6 Feb 2026 15:50:17 +0100 Subject: [PATCH 191/462] FIX add missing random states and cloning in `test_response.py` (#33221) --- sklearn/utils/tests/test_response.py | 35 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/sklearn/utils/tests/test_response.py b/sklearn/utils/tests/test_response.py index 59896a06ed2f2..869901e350227 100644 --- a/sklearn/utils/tests/test_response.py +++ b/sklearn/utils/tests/test_response.py @@ -16,7 +16,7 @@ from sklearn.preprocessing import scale from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor from sklearn.utils._response import _get_response_values, _get_response_values_binary -from sklearn.utils._testing import assert_allclose, assert_array_equal +from sklearn.utils._testing import assert_allclose X, y = load_iris(return_X_y=True) # scale the data to avoid ConvergenceWarning with LogisticRegression @@ -29,17 +29,17 @@ [ (DecisionTreeRegressor(), "predict_proba"), (DecisionTreeRegressor(), ["predict_proba", "decision_function"]), - (KMeans(n_clusters=2, n_init=1), "predict_proba"), - (KMeans(n_clusters=2, n_init=1), ["predict_proba", "decision_function"]), + (KMeans(n_clusters=2), "predict_proba"), + (KMeans(n_clusters=2), ["predict_proba", "decision_function"]), (DBSCAN(), "predict"), - (IsolationForest(random_state=0), "predict_proba"), - (IsolationForest(random_state=0), ["predict_proba", "score"]), + (IsolationForest(), "predict_proba"), + (IsolationForest(), ["predict_proba", "score"]), ], ) -def test_estimator_unsupported_response(pyplot, estimator, response_method): +def test_estimator_unsupported_response(estimator, response_method): """Check the error message with not supported response method.""" X, y = np.random.RandomState(0).randn(10, 2), np.array([0, 1] * 5) - estimator.fit(X, y) + estimator = clone(estimator).fit(X, y) # clone to make test execution thread-safe err_msg = "has none of the following attributes:" with pytest.raises(AttributeError, match=err_msg): _get_response_values( @@ -53,9 +53,9 @@ def test_estimator_unsupported_response(pyplot, estimator, response_method): "estimator, response_method", [ (LinearRegression(), "predict"), - (KMeans(n_clusters=2, n_init=1), "predict"), - (KMeans(n_clusters=2, n_init=1), "score"), - (KMeans(n_clusters=2, n_init=1), ["predict", "score"]), + (KMeans(n_clusters=2, random_state=0), "predict"), + (KMeans(n_clusters=2, random_state=0), "score"), + (KMeans(n_clusters=2, random_state=0), ["predict", "score"]), (IsolationForest(random_state=0), "predict"), (IsolationForest(random_state=0), "decision_function"), (IsolationForest(random_state=0), ["decision_function", "predict"]), @@ -67,7 +67,7 @@ def test_estimator_get_response_values( ): """Check the behaviour of `_get_response_values`.""" X, y = np.random.RandomState(0).randn(10, 2), np.array([0, 1] * 5) - estimator.fit(X, y) + estimator = clone(estimator).fit(X, y) # clone to make test execution thread-safe results = _get_response_values( estimator, X, @@ -78,7 +78,7 @@ def test_estimator_get_response_values( response_method[0] if isinstance(response_method, list) else response_method ) prediction_method = getattr(estimator, chosen_response_method) - assert_array_equal(results[0], prediction_method(X)) + assert_allclose(results[0], prediction_method(X)) assert results[1] is None if return_response_method_used: assert results[2] == chosen_response_method @@ -310,8 +310,7 @@ def test_get_response_values_multiclass(estimator, response_method): """Check that we can call `_get_response_values` with a multiclass estimator. It should return the predictions untouched. """ - estimator = clone(estimator) - estimator.fit(X, y) + estimator = clone(estimator).fit(X, y) # clone to make test execution thread-safe predictions, pos_label = _get_response_values( estimator, X, response_method=response_method ) @@ -416,8 +415,8 @@ def test_response_values_type_of_target_on_classes_no_warning(): (IsolationForest(), "predict", "multiclass", (10,)), (DecisionTreeRegressor(), "predict", "binary", (10,)), (DecisionTreeRegressor(), "predict", "multiclass", (10,)), - (KMeans(n_clusters=2, n_init=1), "predict", "binary", (10,)), - (KMeans(n_clusters=2, n_init=1), "predict", "multiclass", (10,)), + (KMeans(n_clusters=2), "predict", "binary", (10,)), + (KMeans(n_clusters=4), "predict", "multiclass", (10,)), ], ) def test_response_values_output_shape_( @@ -442,8 +441,8 @@ def test_response_values_output_shape_( else: # multilabel y = np.array([[0, 1], [1, 0]] * 5) - clf = clone(estimator).fit(X, y) + estimator = clone(estimator).fit(X, y) # clone to make test execution thread-safe - y_pred, _ = _get_response_values(clf, X, response_method=response_method) + y_pred, _ = _get_response_values(estimator, X, response_method=response_method) assert y_pred.shape == expected_shape From 06fafe37eeeb1cb3afc3fcb86e35d681bad10292 Mon Sep 17 00:00:00 2001 From: Seyi Kuforiji Date: Mon, 9 Feb 2026 02:23:36 +0100 Subject: [PATCH 192/462] DOC: Fix double space formatting in related_projects.rst (#33241) --- doc/related_projects.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/related_projects.rst b/doc/related_projects.rst index a7a10aef7929e..00c1572deb9ac 100644 --- a/doc/related_projects.rst +++ b/doc/related_projects.rst @@ -65,7 +65,7 @@ enhance the functionality of scikit-learn's estimators. organize, log and reproduce experiments - `Scikit-Learn Laboratory - `_ A command-line + `_ A command-line wrapper around scikit-learn that makes it easy to run machine learning experiments with multiple learners and large feature sets. From a9476907765503bee41f74d030ea090424c40352 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Mon, 9 Feb 2026 02:24:26 +0100 Subject: [PATCH 193/462] MNT remove leftover authors (#33240) --- benchmarks/bench_kernel_pca_solvers_time_vs_n_samples.py | 3 ++- benchmarks/bench_saga.py | 6 ++++-- doc/modules/density.rst | 1 - doc/modules/neighbors.rst | 4 ---- sklearn/svm/_liblinear.pyx | 5 +++-- sklearn/tests/test_init.py | 7 +++---- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/benchmarks/bench_kernel_pca_solvers_time_vs_n_samples.py b/benchmarks/bench_kernel_pca_solvers_time_vs_n_samples.py index cae74c6f442ff..2c59e795208bf 100644 --- a/benchmarks/bench_kernel_pca_solvers_time_vs_n_samples.py +++ b/benchmarks/bench_kernel_pca_solvers_time_vs_n_samples.py @@ -38,7 +38,8 @@ of examples is fixed, and the desired number of components varies. """ -# Author: Sylvain MARIE, Schneider Electric +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause import time diff --git a/benchmarks/bench_saga.py b/benchmarks/bench_saga.py index e376b481b5a94..b6e3d91885af4 100644 --- a/benchmarks/bench_saga.py +++ b/benchmarks/bench_saga.py @@ -1,9 +1,11 @@ -"""Author: Arthur Mensch, Nelle Varoquaux - +""" Benchmarks of sklearn SAGA vs lightning SAGA vs Liblinear. Shows the gain in using multinomial logistic regression in term of learning time. """ +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + import json import os import time diff --git a/doc/modules/density.rst b/doc/modules/density.rst index 53bd317003048..8c8c0b78c1990 100644 --- a/doc/modules/density.rst +++ b/doc/modules/density.rst @@ -3,7 +3,6 @@ ================== Density Estimation ================== -.. sectionauthor:: Jake Vanderplas Density estimation walks the line between unsupervised learning, feature engineering, and data modeling. Some of the most popular and useful diff --git a/doc/modules/neighbors.rst b/doc/modules/neighbors.rst index a9c0bb57d7dbc..1f095383499b2 100644 --- a/doc/modules/neighbors.rst +++ b/doc/modules/neighbors.rst @@ -4,8 +4,6 @@ Nearest Neighbors ================= -.. sectionauthor:: Jake Vanderplas - .. currentmodule:: sklearn.neighbors :mod:`sklearn.neighbors` provides functionality for unsupervised and @@ -638,8 +636,6 @@ implementation with special data types. The precomputed neighbors Neighborhood Components Analysis ================================ -.. sectionauthor:: William de Vazelhes - Neighborhood Components Analysis (NCA, :class:`NeighborhoodComponentsAnalysis`) is a distance metric learning algorithm which aims to improve the accuracy of nearest neighbors classification compared to the standard Euclidean distance. diff --git a/sklearn/svm/_liblinear.pyx b/sklearn/svm/_liblinear.pyx index 4ca05d4b5c9d3..137ec2d288179 100644 --- a/sklearn/svm/_liblinear.pyx +++ b/sklearn/svm/_liblinear.pyx @@ -1,9 +1,10 @@ """ Wrapper for liblinear - -Author: fabian.pedregosa@inria.fr """ +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + import numpy as np from sklearn.utils._cython_blas cimport _dot, _axpy, _scal, _nrm2 diff --git a/sklearn/tests/test_init.py b/sklearn/tests/test_init.py index 4df9c279030cb..6c80138b2b5ee 100644 --- a/sklearn/tests/test_init.py +++ b/sklearn/tests/test_init.py @@ -1,8 +1,7 @@ -# Basic unittests to test functioning of module's top-level - +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause -__author__ = "Yaroslav Halchenko" -__license__ = "BSD" +# Basic unittests to test functioning of module's top-level try: From c7c683354dfa07a483b81fdbc1ffd46fd1632277 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 9 Feb 2026 04:23:19 -0500 Subject: [PATCH 194/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33248) Co-authored-by: Lock file bot --- build_tools/azure/debian_32bit_lock.txt | 2 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 141 +++++++++--------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 30 ++-- .../pylatest_conda_forge_osx-arm64_conda.lock | 79 +++++----- ...st_pip_openblas_pandas_linux-64_conda.lock | 30 ++-- ...nblas_min_dependencies_linux-64_conda.lock | 46 +++--- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 34 ++--- ...min_conda_forge_openblas_win-64_conda.lock | 32 ++-- build_tools/circle/doc_linux-64_conda.lock | 112 +++++++------- .../doc_min_dependencies_linux-64_conda.lock | 90 +++++------ ...n_conda_forge_arm_linux-aarch64_conda.lock | 56 +++---- 11 files changed, 327 insertions(+), 325 deletions(-) diff --git a/build_tools/azure/debian_32bit_lock.txt b/build_tools/azure/debian_32bit_lock.txt index 616fd261661a2..2684298b8daea 100644 --- a/build_tools/azure/debian_32bit_lock.txt +++ b/build_tools/azure/debian_32bit_lock.txt @@ -4,7 +4,7 @@ # # pip-compile --output-file=build_tools/azure/debian_32bit_lock.txt build_tools/azure/debian_32bit_requirements.txt # -coverage[toml]==7.13.2 +coverage[toml]==7.13.3 # via pytest-cov cython==3.2.4 # via -r build_tools/azure/debian_32bit_requirements.txt diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index c3dff27c3c0cb..1bd0fc21ae06e 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -10,7 +10,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.2 https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_463.conda#291727757c8a8613312aaa4b52e82ad8 https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa -https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 +https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 @@ -20,7 +20,7 @@ https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.con https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc @@ -29,23 +29,23 @@ https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 -https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 +https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 @@ -68,11 +68,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -83,19 +83,19 @@ https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7 https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.2-he8a4886_1.conda#bade189a194e66b93c03021bd36c337b https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-hdaf4b65_5.conda#132e8f8f40f0ffc0bbde12bb4e8dd1a1 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee @@ -127,42 +127,42 @@ https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda# https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-h19cb568_0.conda#a98b8d7cfdd20004f1bdd1a51cb22c58 -https://conda.anaconda.org/conda-forge/linux-64/playwright-1.58.0-h0bd9c3d_0.conda#2ed0eabd4c852ea6538a2b9ce549b24c -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e +https://conda.anaconda.org/conda-forge/linux-64/playwright-1.58.2-h0bd9c3d_0.conda#9d161e4e16adbf1155a12470ced3c4cc +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_100_cp314.conda#b40594d5da041824087eebe12228af42 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_0.conda#0227d04521bc3d28c7995c7e1f99a721 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.3-hef928c7_0.conda#bdd464b33f6540ed70845b946c11a7b8 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-hc63082f_11.conda#6a653aefdc5d83a4f959869d1759e6e3 -https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda#1d4e0d37da5f3c22ecd44033f673feba -https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py313h18e8e13_0.conda#d9e90792551a527200637e23a915dd79 -https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py313hf159716_1.conda#6c4d3597cf43f3439a51b2b13e29a4ba +https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 +https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 +https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_100.conda#32a3e6470f571e373e3d723cccb0b521 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda#2cfaaccf085c133a477f0a7a8657afe9 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.1.0-pyhd8ed1ab_0.conda#1daaf94a304a27ba3446a306235a37ea -https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.1-py313h7033f15_0.conda#6eab2180bbbe36de88df9ed3fc579eb9 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 +https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.1-py314h42812f9_1.conda#cca70a5a85afb519e8c839ae80dc9334 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py314h97ea11e_2.conda#57f1ce4f7ba6bcd460be8f83c8f04c69 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda#ff63bb12ac31c176ff257e3289f20770 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee +https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda#fab1be106a50e20f10fe5228fd1d1651 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b @@ -170,103 +170,104 @@ https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#3 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py313h80991f8_0.conda#183fe6b9e99e5c2b464c1573ec78eac8 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py314h8ec4b1a_0.conda#f9b6a8fbb8dcb840a0c1c052dc5092e4 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda#23b4ba5619c4752976eb7ba1f5acb7e8 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py313h07c4f96_0.conda#82da2dcf1ea3e298f2557b50459809e0 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py314h5bd0f2a_0.conda#e35f08043f54d26a1be93fdbf90d30c3 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d +https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py314h5bd0f2a_1.conda#58e2ee530005067c5db23f33c6ab43d2 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.3-h06ab39a_1.conda#3689a4290319587e3b54a4f9e68f70c8 -https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda#4e921d9c85e6559c60215497978b3cdb -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-h3d7a050_0.conda#e6f12de3a9b016cea81a87db04d85ff3 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.2-py313h3dea7bd_0.conda#df05169cc886aaf53dc560db634519f8 +https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.3-py314h67df5f8_0.conda#705e973836337db525548d91d44ca3bc https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py313h3dea7bd_0.conda#c0f36dfbb130da4f6ce2df31f6b25ea8 -https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f +https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py314h28848ee_2.conda#6958d0a4028e0b3ffd80ce539482c605 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_2.conda#3c71daed530c0c26671a1b1b7010e746 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_2.conda#0ad9019bb10eda915fb0ce5f78fef13b +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d -https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 +https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.0-pyhd8ed1ab_0.conda#ec33a030c3bc90f0131305a8eba5f8a3 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.11-h4df99d1_100.conda#d1461b2e63b1909f4f5b41c823bd90ae +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_100.conda#90c63d1e08a8bce206e66e95ef249f48 https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda#a4059bc12930bddeb41aef71537ffaed https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.4-h8824e59_0.conda#113b9d9913280474c0868b0e290c0326 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-h75daedc_0.conda#e88f8e816ae46c12cbe912c8f4d9d3bc +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 -https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 -https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.57.0-pyhcf101f3_0.conda#a61bfabd06f24469454086deb7f8166e +https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py314h9891dd4_0.conda#6c7bdf1b5e901fd16789cdddce83956f +https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.58.0-pyhcf101f3_0.conda#3b886c49cf44aa133d0eb07e4d0cac89 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10.conda#937d1d4c233adc6eeb2ac3d6e9a73e53 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-hd454692_0.conda#55986e49b7aafe9aa09d7f4c70a56a18 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.0-h6083320_0.conda#1ea5ed29aea252072b975a232b195146 +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.37.1-py310hffdcd12_0.conda#732a536c6ce768f096f5340121e10cc5 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hffdcd12_0.conda#b659a59ec7b67623dcaec02388e06fb9 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h2c50142_0_cpu.conda#ef47efe8884347ab96f0d26399e83229 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h40b5c2d_2_cpu.conda#282f8460096fdc04d2c62ca2a30357a1 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 -https://conda.anaconda.org/conda-forge/noarch/polars-1.37.1-pyh6a1acc5_0.conda#1894d4373da653406c91e20ef89f05c8 +https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-hb82b983_4.conda#f4dfd61ec958d420bebdcefeb805d658 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h8c2c5c3_0_cpu.conda#fa2c484e95ba37950f926bd797c51dc4 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h8c2c5c3_2_cpu.conda#c9c3d7509b7faef60374fa290b4e5071 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_0_cpu.conda#be2161a27537cb288a5634daf768af00 -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_hfee2a32_100.conda#bc597665767a73ca870b4ad32e07f570 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py313hf6604e3_0.conda#7d51e3bef1a4b00bde1861d85ba2f874 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py313h85046ba_0.conda#2c5d21d466ef1ff0c0a98cfdbaf5c64b +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_2_cpu.conda#64c8c3132e92b2d02e6b0bcdf7125090 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h0bc6d91_101.conda#e9ec87a52136692bcf59f97063de3c78 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_1.conda#4ea6b620fdf24a1a0bc4f1c7134dfafb +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py314hf36963e_0.conda#46a2b79da4213038907306040c9c9fd8 https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_0_cpu.conda#0e1d44a4759116c17c77cdead68bb2d6 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py313hbfd7664_0.conda#ab6d05e915ab2ae4c41d275b14592151 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py313he109ebe_0_cpu.conda#9120bf253ebbdb0015069b9a25cf4d36 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py313_hf5c6997_100.conda#120b7f1d7c548044149e0ab80bbfcd69 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py313h4b8bb8b_1.conda#2b18fe5b4b2d1611ddf8c2f080a46563 -https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.0.1-pyhe01879c_0.conda#303ec962addf1b6016afd536e9db6bc6 +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_2_cpu.conda#f67acaf4653452503669ade10edec780 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py314hb4ffadd_0.conda#90e3461036907dcd77c950308c1033d2 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py314h52d6ec5_0_cpu.conda#267abc6a9fe2b609221a7b2a42b15e1c +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h3c9122e_101.conda#7168ab2f0a0bd4c64fb48c65b55523d9 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py314hf07bd8e_1.conda#c7df812186fb1290bc00d9b7b5a50b18 +https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.1.0-pyhcf101f3_0.conda#57d364589a8c710c5b34e8b4a5312ea6 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_0_cpu.conda#a373b33a7a1c9f57ef6273e886e91fe1 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 -https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed -https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_100.conda#3081ed71fc4fd81a6cc84938472798e5 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-h3f74fd7_0_cpu.conda#618c4d7d323f9b3ec4fdb0b3a5e5df1d -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.0-py313h78bf25f_0.conda#a6e89cb214f318db9548b791ba27f862 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_2_cpu.conda#d3633b19c4d7e26474733e18e602e8ce +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f +https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_101.conda#c533790737122f36f779ac3d66ce48f1 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-h3f74fd7_2_cpu.conda#8b003b0de3b7c7455400752d0df67d76 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.0-py314hdafbbf9_0.conda#f63f85bccdd104d2ffa341fd705f86d9 diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 37559ff83d529..f96701dbaf715 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -8,14 +8,14 @@ https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad65 https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda#97c4b3bd8a90722104798175a1bdddbf https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 -https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.8-h3d58e20_0.conda#9f8a60a77ecafb7966ca961c94f33bd1 +https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.8-h4fb565c_2.conda#1ac756454e65fb3fd7bc7de599526e43 https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda#222e0732a1d0780a622926265bee14ef -https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda#d214916b24c625bcc459b245d509f22e +https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda#66a0dc7464927d0853b590b6f53ba3ea https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda#210a85a1119f97ea7887188d176db135 https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.2-h8616949_0.conda#48dda187f169f5a8f1e5e07701d5cdd9 https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda#688a0c3d57fa118b9c97bf7e471ab46c -https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda#18b81186a6adb43f000ad19ed7b70381 +https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda#ec88ba8a245855935b871a7324373105 https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda#7bb6608cf1f83578587297a158a6630b https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda#003a54a4e32b02f7355b50a837e699da https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.8-h472b3d1_0.conda#e2d811e9f464dd67398b4ce1f9c7c872 @@ -34,19 +34,19 @@ https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda# https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-hd57b93d_1.conda#060f6892620dc862f3b54b9b2da8f177 https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda#afda563484aa0017278866707807a335 -https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda#3f50cdf9a97d0280655758b735781096 +https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda#30bb8d08b99b9a7600d39efb3559fff0 https://conda.anaconda.org/conda-forge/osx-64/qhull-2020.2-h3c5361c_5.conda#dd1ea9ff27c93db7c01a7b7656bd4ad4 https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda#eefd65452dfe7cce476a519bece46704 -https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda#bd9f1de651dbd80b51281c694827f78f -https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.2-h8bce59a_1.conda#cdd69480d52f2b871fad1a91324d9942 +https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda#6e6efb7463f8cef69dbcb4c2205bf60e +https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.3-h8bce59a_1.conda#b3ecb6480fd46194e3f7dd0ff4445dff https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf -https://conda.anaconda.org/conda-forge/osx-64/ccache-4.12.2-h23dfd00_0.conda#18be62e9b80f56a47b1ccd830e5e1941 +https://conda.anaconda.org/conda-forge/osx-64/ccache-4.12.3-h23dfd00_0.conda#9184b1fd28dd26fafba199afd2a2b713 https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.conda#dfbdc8fd781dc3111541e4234c19fdbd -https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_15.conda#c816665789d1e47cdfd6da8a81e1af64 +https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_17.conda#500bac4a846e5001cbf05572df6c3654 https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h745d5cb_1.conda#1fd2c75a8a9adc629983ed629dec42e1 -https://conda.anaconda.org/conda-forge/osx-64/python-3.14.2-hf88997e_100_cp314.conda#48921d5efb314c3e628089fc6e27e54a +https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_100_cp314.conda#b35e4ee0c1832ba9f8669f88983d44c5 https://conda.anaconda.org/conda-forge/osx-64/brotli-1.2.0-hf139dec_1.conda#149d8ee7d6541a02a6117d8814fd9413 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -56,17 +56,17 @@ https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.9-py314hf3ac25a_2.conda#28a77c52c425fa9c6d914c609c626b1a https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.18-h90db99b_0.conda#753acc10c7277f953f168890e5397c80 https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.1-h694c41f_0.conda#e0e2edaf5e0c71b843e25a7ecc451cc9 -https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_15.conda#c2a6149bf7f82774a0118b9efef966dd +https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_17.conda#bb0c5b043c41c27f4f73a103c6ad0c7f https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h87e8dc5_0.conda#a67d3517ebbf615b91ef9fdc99934e0c https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -74,12 +74,12 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.4-py314h3d180e3_0.conda#e9dfcd5b883e35aebe6dbe2c197dddbe https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.0-py314h6482030_1.conda#d69097de15cbad36f1eaafda0bad598a -https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.2-py314h10d0514_0.conda#8a0d5bba423473595e51a29b1336f636 +https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.3-py314h10d0514_0.conda#89676cb93389732dc8f71ec39798083d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.1-h694c41f_0.conda#ca641fdf8b7803f4b7212b6d66375930 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_15.conda#a089323fefeeaba2ae60e1ccebf86ddc +https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_17.conda#218faf079bac8521ccf3f8542feeb51d https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.0-py314hf9dbaa9_0.conda#ca55b2df1530e093f26d25ed503aafe8 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -94,7 +94,7 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.co https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-20_osx64_mkl.conda#51089a4865eb4aec2bc5c7468bd07f9f https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-20_osx64_mkl.conda#58f08e12ad487fac4a08f90ff0b87aec https://conda.anaconda.org/conda-forge/osx-64/liblapacke-3.9.0-20_osx64_mkl.conda#124ae8e384268a8da66f1d64114a1eda -https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.1-py314hfc4c462_0.conda#73bc04c55ef4911075790db9fcce921b +https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.2-py314hfc4c462_1.conda#891bda68803fbbcf08d37f94981b650a https://conda.anaconda.org/conda-forge/osx-64/blas-devel-3.9.0-20_osx64_mkl.conda#cc3260179093918b801e373c6e888e02 https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h22a2ed9_4.conda#511f02f632e1fb0555da3cb4261851d9 https://conda.anaconda.org/conda-forge/osx-64/pandas-3.0.0-py314h550b3c8_0.conda#6c2fa7e6dc0b23634f2f19d7054516b1 diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock index c6659312b0021..bf15224cd1f1f 100644 --- a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock @@ -5,22 +5,22 @@ https://conda.anaconda.org/conda-forge/noarch/libgfortran-devel_osx-arm64-14.3.0-hc965647_1.conda#c1b69e537b3031d0f5af780b432ce511 https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a66894dfd07c4510beb6b3f9672ccc0 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa -https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 +https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_6.conda#4cd4e8d9e11f08dfba7b48f6b3eae8cb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda#58fd217444c2a5701a44244faf518206 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-h38cb7af_0.conda#1e93aca311da0210e660d2247812fa02 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa -https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-hf598326_0.conda#780f0251b757564e062187044232c2b7 +https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda#4cb5878bdb9ebfa65b7cdff5445087c5 https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda#b79875dbb5b1db9a4a22a4520f918e1a -https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda#411ff7cd5d1472bba0f55c0faf04453b +https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda#43c04d9cb46ef176bb2a4c77e324d599 https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda#4d5a7445f0b25b6a3ddbb56e790f5251 https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda#f0695fbecf1006f27f4395d64bd0c4b8 https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda#009f0d956d7bfb00de86901d16e486c7 -https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda#85ccccb47823dd9f7a99d2c7f530342f +https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda#57c4be259f5e0b99a5983799a228ae55 https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda#c0d87c3c8e075daf1daf6c31b53e8083 https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda#e5e7d467f80da752be17796b87fe6385 https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda#369964e85dc26bfe78f41399b366c435 @@ -35,7 +35,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/fmt-12.1.0-h403dcb5_0.conda#ae2 https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-h7bae524_2.conda#eed7278dfbab727b56f2c0b64330814b https://conda.anaconda.org/conda-forge/osx-arm64/isl-0.26-imath32_h347afa1_101.conda#e80e44a3f4862b1da870dc0557f8cf3b https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda#a74332d9b60b62905e3d30709df08bf1 -https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20250512.1-cxx17_hd41c47c_0.conda#360dbb413ee2c170a0a684a33c4fc6b8 +https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.0-cxx17_h2062a1b_0.conda#160a2437f91ee5e1bc0178b2837a193c https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda#079e88933963f3f149054eec2c487bc2 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef @@ -45,40 +45,40 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.con https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h5ef1a60_1.conda#7eed1026708e26ee512f43a04d9d0027 https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda#175809cc57b2c67f27a0f238bd7f069d -https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda#b34dc4172653c13dcf453862f251af2b +https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda#f4f6ad63f98f64191c3e77c5f5f29d76 https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda#6483b1f59526e05d7d894e466b5b6924 https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda#f8381319127120ce51e081dce4865cf4 https://conda.anaconda.org/conda-forge/osx-arm64/sleef-3.9.0-hb028509_0.conda#68f833178f171cfffdd18854c0e9b7f9 https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_0.conda#347261d575a245cb6111fb2cb5a79fc7 -https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_3.conda#a73d54a5abba6543cb2f0af1bfbd6851 +https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda#a9d86bc62f39b94c4661716624eb21b0 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda#e3170d898ca6cb48f1bb567afb92f775 -https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.2-hed4e4f5_1.conda#75f39a44c08cb5dc4ea847698de34ba3 +https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.3-hed4e4f5_1.conda#d99c2a23a31b0172e90f456f580b695e https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c -https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.12.2-h414bf82_0.conda#5cacaa11f10beb9477976bc997305e27 +https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.12.3-h414bf82_0.conda#11dee8592fccf816ae8bd46f08c3ca31 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda#6d4ede03e2a8e20eb51f7f681d2a2550 -https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_16.conda#8b216bac0de7a9d60f3ddeba2515545c -https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.31.1-h98f38fd_4.conda#8a6b4281c176f1695ae0015f420e6aa9 +https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_17.conda#65c07cee234440ae4d5d340fc4b2e69a +https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.33.5-h4a5acfd_0.conda#b839e3295b66434f20969c8b940f056a https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda#c08557d00807785decafb932b5be7ef5 https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-h8d039ee_1.conda#fd804ee851e20faca4fecc7df0901d07 https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.1-hb693164_3.conda#4e4ea852d54cc2b869842de5044662fb -https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.11-hfc2f54d_100_cp313.conda#18a8c69608151098a8fb75eea64cc266 +https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_100_cp314.conda#97852749b58606ffe363c2cc491cfce1 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda#48ece20aa479be6ac9a284772827d00c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.11-py313hd8ed1ab_100.conda#5bf347916a543bcb290c780fa449bf73 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_100.conda#32a3e6470f571e373e3d723cccb0b521 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py313hf5aebd8_0.conda#6dc684ec14e88ff9485928f81286c7a5 +https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py314hc6117b3_0.conda#1289de88f884ac89144949cb97ccabe7 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda#2cfaaccf085c133a477f0a7a8657afe9 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.1.0-pyhd8ed1ab_0.conda#1daaf94a304a27ba3446a306235a37ea +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py313h7add70c_2.conda#9583687276aaa393e723f3b7970be69f +https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py314h42813c9_2.conda#9aa431bf603c231e8c77a1b0842a85ed https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.18-hdfa7624_0.conda#6631a7bd2335bb9699b1dbc234b19784 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda#f35fb38e89e2776994131fbf961fa44b -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_16.conda#265a9d03461da24884ecc8eb58396d57 +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_17.conda#c6329d871fb3207e9657c384128f5488 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 -https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py313h7d74516_0.conda#3df5979cc0b761dda0053ffdb0bca3ea +https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda#fab1be106a50e20f10fe5228fd1d1651 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.3.1-h8f1351a_1.conda#a5635df796b71f6ca400fc7026f50701 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b @@ -86,31 +86,32 @@ https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#3 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hbfb3c88_0.conda#6bf3d24692c157a41c01ce0bd17daeea https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda#ade77ad7513177297b1d75e351e136ce https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py313h6535dbc_0.conda#67a85c1b5c17124eaf9194206afd5159 +https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py314h0612a62_0.conda#83e1a2d7b0c1352870bbe9d9406135cf https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.2-py313h65a2061_0.conda#310642d43db19e0bf5e499f29c76a124 +https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.0-py314h0612a62_1.conda#c673decfe1f120b0717d0aa193b10060 +https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.3-py314h6e9b3f0_0.conda#e81fd2615bfa91c3e3c2966b4f8d6fa2 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.61.1-py313h7d74516_0.conda#894eb0c3e9a17643906a6da3209bf045 +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.1-hce30654_0.conda#1ec9a1ee7a2c9339774ad9bb6fe6caec -https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.2.1-py313hc1c22ca_2.conda#08bbc47d90ccee895465f61b8692e236 +https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.2.1-py314h07d5e28_2.conda#2e07295c0b3bcdae3551d525b70e396f https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_4.conda#eaf3d06e3a8a10dee7565e8d76ae618d https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_7.conda#5600ae1b88144099572939e773f4b20b -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_16.conda#11e09edf0dde4c288508501fe621bab4 +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_17.conda#45ba22eb5381fb602a45233d89ba27ae https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef -https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.1.0-py313h45e5a15_0.conda#78a39731fd50dbd511de305934fe7e62 +https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.1.0-py314hab283cf_0.conda#1f9dae6213643ac883e300c11df611eb https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -120,7 +121,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_4. https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h8d724d3_accelerate.conda#c32b3b0d73d5cb1ab2a095a69bf3a7bd https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.18.0-py313ha61f8ec_0.conda#08c825d0a6cde154eb8c4729563114e7 +https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.18.0-py314h784bc60_0.conda#4f367ea978ceb7f4c5e90ecc7b9f50fc https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_he8a363d_4.conda#76c651b923e048f3f3e0ecb22c966f70 @@ -131,30 +132,30 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.co https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_4.conda#caf7c8e48827c2ad0c402716159fe0a2 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_4.conda#df5cd5c925df1412426e3db71d31363f https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-5_hbdd07e9_accelerate.conda#29c7d09cbe6d342ced64b0447e1f3792 -https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.10.0-cpu_generic_h593a70c_0.conda#8100d227aad1ce35cb00f3a4f69cd5c3 -https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.1-py313h16eae64_0.conda#527abeb3c3f65345d9c337fb49e32d51 +https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.10.0-cpu_generic_hf7cc835_2.conda#3662b7ef51f97c1030b28bcd4bb0d8a0 +https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.2-py314hae46ccb_1.conda#0f0ddf0575b98d91cda9e3ca9eaeb9a2 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-5_h55bc449_accelerate.conda#6696b095e91860523bcc97303e11d30d -https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py313h2af2deb_4.conda#afd3e394d14e627be0de6e8ee3553dae -https://conda.anaconda.org/conda-forge/osx-arm64/pandas-3.0.0-py313h6974306_0.conda#ae2e72c47ce95ec8c489cffa0592f492 -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.10.0-cpu_generic_py313_hca44352_0.conda#4190280441d934739891072f82b02cc3 -https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.0-py313hc753a45_1.conda#5b73b1e6d191aac48960c50d65372f19 +https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py314hf8a3a22_4.conda#cddc851000ce131d757678c2f329eaad +https://conda.anaconda.org/conda-forge/osx-arm64/pandas-3.0.0-py314h5e21a50_0.conda#1594f26f007c3f2ef7ad789b4a651082 +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.10.0-cpu_generic_py314_he36690f_2.conda#58e87541ac9cbcbf6761d85a95b88578 +https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.0-py314hfc1f868_1.conda#09978c420b2e017134c825c06250bf23 https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.305-accelerate.conda#5f941c90faaca70599ef8302d0c2738f -https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py313h58042b9_0.conda#745c18472bc6d3dc9146c3dec18bb740 -https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py313h28ea3aa_1.conda#51a353d043e612a8f520627cf0e73653 -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.10.0-cpu_generic_hcc7c195_0.conda#031007adf47afe42e6ef38bcfc16f15d -https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py313h39782a4_0.conda#bae471007cbebf097a19e851c219d56a +https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py314hd63e3f0_0.conda#c84152e510d41378b8758826655b6ed7 +https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py314h95ce61a_1.conda#44282cc9330eb206f808c4f5be281fe2 +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.10.0-cpu_generic_hcc7c195_2.conda#9e989335f05b5d19538cf538805544da +https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py314he55896b_0.conda#ad9a3f773f13989b92b41c0eabed5a38 https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda#148516e0c9edf4e9331a4d53ae806a9b https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_7.conda#13150cdd8e6bc61aa68b55d1a2a69083 https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda#8d99c82e0f5fed6cc36fcf66a11e03f0 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_impl_osx-arm64-14.3.0-h6d03799_1.conda#1e9ec88ecc684d92644a45c6df2399d0 https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_7.conda#bde6fcb6b1fcefb687a7fb95675c6ec8 -https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_30.conda#c4084c97eb4a40f93efc3844c552d895 +https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_31.conda#6645630920c0980a33f055a49fbdb88e https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_7.conda#4fa4a9227c428372847c534a9bffd698 https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_hc995acf_7.conda#0c1f688616da9aac0ce556d74a24f740 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_osx-arm64-14.3.0-h3c33bd0_0.conda#8db8c0061c0f3701444b7b9cc9966511 -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_30.conda#ad0ecddf92544c4be2e431e1b720f9ed +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_31.conda#bd6926e81dc196064373b614af3bc9ff https://conda.anaconda.org/conda-forge/osx-arm64/gfortran-14.3.0-h3ef1dbf_0.conda#e148e0bc9bbc90b6325a479a5501786d https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda#043afed05ca5a0f2c18252ae4378bdee https://conda.anaconda.org/conda-forge/osx-arm64/fortran-compiler-1.11.0-h81a4f41_0.conda#d221c62af175b83186f96d8b0880bff6 diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index 70d8c5a93f3f5..f806978ace355 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -6,35 +6,35 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 -https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda#c7e925f37e3b40d893459e625f6a53f1 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.11-hc97d973_100_cp313.conda#0cbb0010f1d8ecb64a428a8d4214609e -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf47878473e5ab9fdb4115735230e191 +https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b -# pip babel @ https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl#sha256=4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2 +# pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c # pip charset-normalizer @ https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 -# pip coverage @ https://files.pythonhosted.org/packages/8e/78/befa6640f74092b86961f957f26504c8fba3d7da57cc2ab7407391870495/coverage-7.13.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=7be4d613638d678b2b3773b8f687537b284d7074695a43fe2fbbfc0e31ceaed1 +# pip coverage @ https://files.pythonhosted.org/packages/6f/99/97b600225fbf631e6f5bfd3ad5bcaf87fbb9e34ff87492e5a572ff01bbe2/coverage-7.13.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=16d23d6579cf80a474ad160ca14d8b319abaa6db62759d6eef53b2fc979b58c8 # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 # pip cython @ https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de @@ -48,7 +48,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 # pip meson @ https://files.pythonhosted.org/packages/9c/d5/582789135863eec7c8c1fa31fbde401b3d5d82dbbb4a0973351a1698f738/meson-1.10.1-py3-none-any.whl#sha256=fe43d1cc2e6de146fbea78f3a062194bcc0e779efc8a0f0d7c35544dfb86731f # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa -# pip numpy @ https://files.pythonhosted.org/packages/ba/87/d341e519956273b39d8d47969dd1eaa1af740615394fe67d06f1efa68773/numpy-2.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8 +# pip numpy @ https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499 # pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 # pip pillow @ https://files.pythonhosted.org/packages/01/9a/632e58ec89a32738cabfd9ec418f0e9898a2b4719afc581f07c04a05e3c9/pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 @@ -80,6 +80,6 @@ https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh145f28c_0.conda#bf4787 # pip pyamg @ https://files.pythonhosted.org/packages/63/f3/c13ae1422434baeefe4d4f306a1cc77f024fe96d2abab3c212cfa1bf3ff8/pyamg-5.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=5cc223c66a7aca06fba898eb5e8ede6bb7974a9ddf7b8a98f56143c829e63631 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 -# pip scipy-doctest @ https://files.pythonhosted.org/packages/f5/99/a17f725f45e57efcf5a84494687bba7176e0b5cba7ca0f69161a063fa86d/scipy_doctest-2.0.1-py3-none-any.whl#sha256=7725b1cb5f4722ab2a77b39f0aadd39726266e682b19e40f96663d7afb2d46b1 +# pip scipy-doctest @ https://files.pythonhosted.org/packages/92/4f/b10c11591ca2e98f5a51568e39ea625ac0686f651130f5ef18e38b5f4816/scipy_doctest-2.1.0-py3-none-any.whl#sha256=f3187913469a335f7e9546b5588160e1b25de58999c0a5d21615f281b794f66d # pip sphinx @ https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl#sha256=c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978 # pip numpydoc @ https://files.pythonhosted.org/packages/62/5e/3a6a3e90f35cea3853c45e5d5fb9b7192ce4384616f932cf7591298ab6e1/numpydoc-1.10.0-py3-none-any.whl#sha256=3149da9874af890bcc2a82ef7aae5484e5aa81cb2778f08e3c307ba6d963721b diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 802233c60d309..fe191b6a872cc 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -16,7 +16,7 @@ https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.con https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc @@ -24,9 +24,9 @@ https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 @@ -36,13 +36,13 @@ https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb9d3cd8_3.conda# https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 @@ -61,12 +61,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -77,26 +77,26 @@ https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/s2n-1.3.46-h06160fa_0.conda#413d96a0b655c8f8aacc36473a2dbb04 -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda#580a52a05f5be28ce00764149017c6d4 https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1.conda#f883d61afbc95c50f7b3f62546da4235 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda#d1db1b8be7c3a8983dcbbbfe4f0765de https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.conda#081aa22f4581c08e4372b0b6c2f8478e https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.conda#1f0a03af852a9659ed2bf08f2f1704fd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_17.conda#d7954bb54fc77e7952a78e5e0d134df5 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 @@ -129,11 +129,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-1.8.4-h2f23424_0.conda#4bb92585a250e67d49b46c073d29f9dd -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 https://conda.anaconda.org/conda-forge/linux-64/ucx-1.14.1-h64cca9d_5.conda#39aa3b356d10d7e5add0c540945a0944 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.3.1-h1e03375_0.conda#3082be841420d6288bc1268a9be45b75 @@ -170,7 +170,7 @@ https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda# https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda#978d03388b62173b8e6f79162cf52b86 https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -178,13 +178,13 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.0-h435f46f_0.conda#c7726f96aab024855ede05e0ca6e94a0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.8.13-hd4f18eb_5.conda#860fb8c0efec64a4a678eb2ea066ff65 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.2-py311h3778330_0.conda#b25c1e3463dde575d6701b8dee76d965 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.3-py311h3778330_0.conda#620e453607709b49ffdc834da5887217 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 @@ -203,12 +203,12 @@ https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bd https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_2.conda#3c71daed530c0c26671a1b1b7010e746 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_2.conda#0ad9019bb10eda915fb0ce5f78fef13b +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 @@ -227,7 +227,7 @@ https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728 https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h3c3fd16_6.conda#5aab84b9d164509b5bbe3af660518606 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c -https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_3.conda#d2bbbd293097e664ffb01fc4cdaf5729 +https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.0-py311h39c9aba_9_cpu.conda#c35fe329bcc51a1a3a254c990ba8f738 diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index b3e18db04fb6f..5b33a9992518d 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -6,42 +6,42 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 @@ -51,7 +51,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openbl https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 @@ -77,27 +77,27 @@ https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 +https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_0.conda#ea5be9abc2939c8431893b4e123a2065 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py311h2e04523_0.conda#716357afd11c16214cdac522da447704 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py311h2e04523_1.conda#a8105076864776eceae69d64d30e24d7 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py311h8032f78_0.conda#78d3e3073a999e662385c9a80d84ecec -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_1.conda#f4dda6316cc4718cbcab7009b5d60c41 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock index 0e7dbab15f0c8..8a304a1bfd9a9 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock @@ -14,7 +14,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda#8a86073cf3b343b87d03f41790d8b4e5 https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda#242d9f25d2ae60c76b38a5e42858e51d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_16.conda#ab8189163748f95d4cb18ea1952943c3 +https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_17.conda#18f0da832fb73029007218f0c56939f8 https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda#37eb311485d2d8b2c419449582046a42 https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda#37e16618af5c4851a3f3d66dd0e11141 https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda#1e610f2416b6acdd231c5f573d754a0f @@ -26,22 +26,22 @@ https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda#c1b81d https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda#444b0a45bbd1cb24f82eedb56721b9c4 https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda#8c9e4f1a0e688eef2e95711178061a0f -https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda#ba4ad812d2afc22b9a34ce8327a0930f -https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_16.conda#1edb8bd8e093ebd31558008e9cb23b47 +https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda#720b39f5ec0610457b725eb3f396219a +https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_17.conda#3b93f0d28aa246cb74ed9b65250cae70 https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#64571d1dd6cdcfa25d0664a5950fdaa2 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda#56a686f92ac0273c0f6af58858a3f013 https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda#ba0bfd4c3cf73f299ffe46ff0eaeb8e3 https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.30-pthreads_h877e47f_4.conda#f551f8ae0ae6535be1ffde181f9377f3 https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda#903979414b47d777d548e5f0165e6cd8 -https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.328.1-h477610d_0.conda#4403eae6c81f448d63a7f66c0b330536 +https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.341.0-h477610d_0.conda#804880b2674119b84277d6c16b01677d https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda#f9bbae5e2537e3b06e0f7310ba76c893 https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda#41fbfac52c601159df6c01f875de31b9 https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda#7ecb9f2f112c66f959d2bb7dbdb89b67 -https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda#84f8fb4afd1157f59098f618cd2437e4 +https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda#eb585509b815415bc964b2c7e11c7eb3 https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda#08c8fa3b419df480d985e304f7884d35 https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda#854fbdff64b572b5c0b470f334d34c11 -https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_3.conda#7cb36e506a7dba4817970f8adb6396f9 -https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.2-h0261ad2_1.conda#bc2fba648e1e784c549e20bbe1a8af40 +https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda#0481bfd9814bf525bd4b3ee4b51494c4 +https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.3-h0261ad2_1.conda#46a21c0a4e65f1a135251fc7c8663f83 https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda#31aec030344e962fbd7dbbbbd68e60a9 https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_h0adab6e_openblas.conda#bae34d8f039de36cc4384371aa12bd61 https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda#450e3ae947fc46b60f1d8f8f318b40d4 @@ -52,7 +52,7 @@ https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h3cfd58e_1.conda https://conda.anaconda.org/conda-forge/win-64/openblas-0.3.30-pthreads_h4a7f399_4.conda#482e61f83248a880d180629bf8ed36b2 https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda#77eaf2336f3ae749e712f63e36b0f0a1 https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda#3c8f2573569bb816483e5cf57efbbe29 -https://conda.anaconda.org/conda-forge/win-64/python-3.11.14-h0159041_2_cpython.conda#02a9ba5950d8b78e6c9862d6ba7a5045 +https://conda.anaconda.org/conda-forge/win-64/python-3.11.14-h0159041_3_cpython.conda#05ded1dca7befb66ec95a9ec6d34a71a https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda#8436cab9a76015dfe7208d3c9f97c156 https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda#a7c03e38aa9c0e84d41881b9236eacfb https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda#053b84beec00b71ea8ff7a4f84b55207 @@ -64,7 +64,7 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py311h275cad7_2.conda#e9eb24a8d111be48179bf82a9e0e13ca https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a8eebe_openblas.conda#1db756824d3aec6a25599c7821cb3e24 -https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_2.conda#511af9070467adf0e8af89ce18d516cf +https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_3.conda#06e385238457018ad1071179b67e39d1 https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda#6e7c5c5ab485057b5d07fd8188ba5c28 https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.3-h0c9aed9_0.conda#c2d5b6b790ef21abac0b5331094ccb56 https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hd232482_openblas.conda#78240c2b4322025a74e7e6edad247103 @@ -77,7 +77,7 @@ https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda# https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -86,14 +86,14 @@ https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py311h3485c13_0.cond https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.0-py311h3485c13_1.conda#a30a6a70ab7754dbf0b06fe1a96af9cb https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda#bc58fdbced45bb096364de0fba1637af -https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.2-py311h3f79411_0.conda#7483b07166c6fad6544dab8709988180 +https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.3-py311h3f79411_0.conda#76bfad83b8bfa9a043aacab46ad72f56 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/win-64/lcms2-2.18-hf2c6c5f_0.conda#b6c68d6b829b044cd17a41e0a8a23ca1 https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda#3235024fe48d4087721797ebd6c9d28c https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-5_hbb0e6ff_openblas.conda#b96fdd694dc8b7a5869613121c40d086 https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 -https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.1-py311h80b3fa1_0.conda#387094bb33448f55432ea38cf9b62f1f +https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.2-py311h80b3fa1_1.conda#a824c6667179120c458beb9e9394932f https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h24db6dd_0.conda#5af852046226bb3cb15c7f61c2ac020a https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -104,7 +104,7 @@ https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py311h3f79411_0.c https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda#d69c21967f35eb2ce7f1f85d6b6022d3 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.0-py311h17b8079_0.conda#da30e4de83b61f936f73660eb4fa3cd5 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.0-py311h9c22a71_1.conda#0d03c857517a5db3c1af5b553a528fac https://conda.anaconda.org/conda-forge/win-64/blas-2.305-openblas.conda#19bbf270f61bbef238e16a9509377a52 @@ -113,7 +113,7 @@ https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675f https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda#52ea1beba35b69852d210242dd20f97d -https://conda.anaconda.org/conda-forge/win-64/harfbuzz-12.3.0-h5a1b470_0.conda#0eb57e84ceeb62c0189827fe7966bdc5 -https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.10.1-h68b6638_4.conda#c4a3cf4e79a59cb46ad2d56b74c89e57 -https://conda.anaconda.org/conda-forge/win-64/pyside6-6.10.1-py311hf70c7b4_0.conda#fe94fb3de0c9ef09dfe49e4f4098299d +https://conda.anaconda.org/conda-forge/win-64/harfbuzz-12.3.2-h5a1b470_0.conda#fb5d7b9527b418f83e3316f3e6daa8a2 +https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.10.2-h68b6638_4.conda#f2dc18a6006aac4ac0050861c6df4120 +https://conda.anaconda.org/conda-forge/win-64/pyside6-6.10.2-py311hf70c7b4_0.conda#8512eff5fd02b371f36b0da26f5a78ee https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py311h1ea47a8_0.conda#64fe28aa2486e41918239d385336e88e diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 53cf905e4e458..eed35ba699936 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -12,37 +12,37 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_116.conda#0141e19cb0cd5602c49c84f920e81921 +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_117.conda#50d5470d29a25808d108d3917426d24b https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_116.conda#badba6a9f0e90fdaff87b06b54736ea6 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_117.conda#97f8b7e451f960200c057ca83d92f9be https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda#2c42649888aac645608191ffdc80d13a https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 @@ -61,12 +61,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_16.conda#0617b134e4dc4474c1038707499f7eed +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_17.conda#5edfb6baf1af52fa7c0a7072a42d1558 https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda#a587892d3c13b6621a6091be690dbca2 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -75,21 +75,21 @@ https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd -https://conda.anaconda.org/conda-forge/linux-64/svt-av1-3.1.2-hecca717_0.conda#9859766c658e78fec9afa4a54891d920 -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d +https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.0-hecca717_0.conda#9a6117aee038999ffefe6082ff1e9a81 +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_5.conda#6a0eb48e58684cca4d7acc8b7a0fd3c7 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.22.0-hc31b594_1.conda#52019609422a72ec80c32bbc16a889d8 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.0-hc31b594_0.conda#f3ac2d8b1b3ac0ba4e42050279ef6ce8 https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-ha09017c_8.conda#6e9bf4ce797d0216bd2a58298b6290b5 @@ -104,12 +104,12 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 -https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_105.conda#e410a8f80e22eb6d840e39ac6a34bd0e +https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_101.conda#83aa53cb3f5fc849851a84d777a60551 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h6395336_2.conda#c09c4ac973f7992ba0c6bb1aafd77bd4 +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda#22d5cc5fb45aab8ed3c00cde2938b825 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 @@ -118,18 +118,18 @@ https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda# https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.0-h8d634f6_0.conda#65900b71509b2fd6c0a34a5dc1bd893a -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda#8035e5b54c08429354d5d64027041cad https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda#537296d57ea995666c68c821b00e360b https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a -https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-default_h4852527_105.conda#1bc3e6c577a1a206c36456bdeae406de -https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-default_h4852527_105.conda#4b1e4ae87a52e9724a9ec0c7b822bc89 +https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_101.conda#9902aeb08445c03fb31e01beeb173988 +https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_101.conda#dec96579f9a7035a59492bf6ee613b53 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2#576d629e47797577ab0f1b351297ef4a https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b @@ -137,14 +137,14 @@ https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1a https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.2-pyhcf101f3_1.conda#61b8078a0905b12529abc622406cb62c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.14-py311hd8ed1ab_2.conda#43ed151bed1a0eb7181d305fed7cf051 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.14-py311hd8ed1ab_3.conda#85bce7761323f3b9b0854437afde219c https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2#961b3a227b437d82ad7054484cfa71b2 https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-he8b2097_16.conda#d274bf1343507683e6eb2954d1871569 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hb1e0a52_17.conda#f5c501fe2a016ed0103f7a89d2ac0412 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -164,7 +164,7 @@ https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0 https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.15.0-pyhcf101f3_0.conda#37926bb0db8b04b8b99945076e1442d0 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.16.0-pyhcf101f3_0.conda#648a62e4e4cf1605abf73e7f48b87d5e https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 @@ -174,7 +174,7 @@ https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.24.1-pyhd8ed1ab_0.conda#7526d20621b53440b0aae45d4797847e -https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.1-py311haee01d2_0.conda#8cc656ea4773e02929cc58745669b116 +https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda#7d9daffbb8d8e0af0f769dbbcd173a54 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 @@ -184,13 +184,13 @@ https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe0 https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda#a61bf9ec79426938ff785eb69dbb1960 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 -https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_0.conda#707c3d23f2476d3bfde8345b4e7d7853 +https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda#a24add9a3bababee946f3bc1c829acfe https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h2315fbb_0.conda#6c87a0f4566469af3585b11d89163fd7 https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda#3893f7b40738f9fe87510cb4468cdda5 https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_0.conda#645026465469ecd4989188e1c4e24953 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda#18de09b20462742fe093ba39185d9bac @@ -207,25 +207,25 @@ https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.con https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda#2841eb5bfc75ce15e9a0054b98dcd64d https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda#2f1ed718fcd829c184a6d4f0f2e07409 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.4-hb9d3cd8_0.conda#2de7f99d6581a4a7adbff607b5c278ca -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 -https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 +https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_0.conda#ea5be9abc2939c8431893b4e123a2065 https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_0.conda#b1a27250d70881943cca0dd6b4ba0956 https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_16.conda#77e54ea3bd0888e65ed821f19f5d23ad +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_17.conda#4e58f090f75b2941346da3685564e7a7 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_17.conda#50dc15ac993bb5859f923979c81fafc8 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_16.conda#3065346248242b288fd4f73fe34f833e -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_16.conda#8729b9d902631b9ee604346a90a50031 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_20.conda#6a7d74012f6ff0b58fb8fcb5286fa584 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_17.conda#ea4724804b89ddc81d16cabe3f4719b5 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_17.conda#8f02f68c780b0a6eeba034af3ed1c00a https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 @@ -233,20 +233,20 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_2.conda#3c71daed530c0c26671a1b1b7010e746 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_2.conda#0ad9019bb10eda915fb0ce5f78fef13b +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d -https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda#372a62464d47d9e966b630ffae3abe73 +https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b11e360fc4de2b0035fc8aaa74f17fd6 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py311h2e04523_0.conda#716357afd11c16214cdac522da447704 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py311h2e04523_1.conda#a8105076864776eceae69d64d30e24d7 https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.2-pyhd8ed1ab_0.conda#7702bcd70891dd0154d765a69e1afa94 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.14-hd8ed1ab_2.conda#a4effc7e6eb335d0e1080a5554590425 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.14-hd8ed1ab_3.conda#ba766ecdcff5b3f015498ad81f4d266e https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 @@ -266,10 +266,10 @@ https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311h724c32c_4.conda#d04e508f5a03162c8bab4586a65d00bf https://conda.anaconda.org/conda-forge/noarch/doit-0.36.0-pyhd8ed1ab_1.conda#18d4243b3d30352f9dea8e522f6ff4d1 https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_16.conda#dcaf539ffe75649239192101037f1406 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h9ce9316_17.conda#d5db7829d4b9b1676419fca2c63909b3 -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h310e576_17.conda#94474857477981fedf74cf7c47c88ba5 -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h273f733_0.conda#fc4da80856253cd3786551227c34bc7a +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_17.conda#dfcfcc0c20762eeb840771eda366940e +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h741da5e_20.conda#5f2bd1037991d4960438641a3ed3c5ae +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h3c3a7a4_20.conda#4b46597b58a2495ec48c215a40e42f0c +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h9837d23_1.conda#e30309a8776e0e969fa7092d7801641b https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a @@ -280,16 +280,16 @@ https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py311h8032f78_0.conda#78d3e3073a999e662385c9a80d84ecec https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_1.conda#f4dda6316cc4718cbcab7009b5d60c41 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_16.conda#f5b82e3d5f4d345e8e1a227636eeb64f -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_16.conda#a3aa64ee3486f51eb61018939c88ef12 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.0-h6083320_0.conda#1ea5ed29aea252072b975a232b195146 +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_17.conda#329ef645bc2f75b4025cba573810e178 +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_17.conda#eae8e3fb1f5eecb829dd7347d33ecacb +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.1-pyhcf101f3_0.conda#b8e1f542770b5f88b663012fc77f9628 @@ -299,7 +299,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.cond https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.1.14-pyhd8ed1ab_0.conda#3888b51c92979cdeef45120181dc8420 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.1.28-pyhd8ed1ab_0.conda#e8d6529858171ac4babb28c334306c0d https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f @@ -307,18 +307,18 @@ https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.0-pyhcf101f3_0.conda#97624651e6fc9ca05effe0b4a80766e3 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 -https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_3.conda#d2bbbd293097e664ffb01fc4cdaf5729 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.1-hb82b983_4.conda#f4dfd61ec958d420bebdcefeb805d658 +https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py311h2a99c40_0.conda#557f5d7ca735d89d706742bc19cd7e26 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda#f56000b36f09ab7533877e695e4e8cb0 -https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.0-pyh0398c0e_0.conda#1831f8fcb080707636343f5e1d8994f1 +https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.1-pyhbbac1ac_0.conda#d8f030e3730713c93a358fdb46f08281 https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.1-py311he4c1a5a_0.conda#6b0c36cdc506dc560538fba50e43dd03 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py311he4c1a5a_0.conda#7287f5cca6b7f82571c1911a43e924b0 https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 -https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.6-pyhcf101f3_1.conda#cfc86ccc3b1de35d36ccaae4c50391f5 +https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.0-pyhcf101f3_0.conda#b14079a39ae60ac7ad2ec3d9eab075ca https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda#d79a87dcfa726bcea8e61275feed6f83 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.0-pyhcf101f3_1.conda#e53b79419913df0b84f7c3af7727122b diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 4854bd27124b1..a3a7b99aca998 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -12,17 +12,17 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_116.conda#0141e19cb0cd5602c49c84f920e81921 +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_117.conda#50d5470d29a25808d108d3917426d24b https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_116.conda#badba6a9f0e90fdaff87b06b54736ea6 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_117.conda#97f8b7e451f960200c057ca83d92f9be https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc @@ -30,9 +30,9 @@ https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 -https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda#35f29eec58405aaf55e01cb470d8c26a -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_16.conda#5a68259fac2da8f2ee6f7bfe49c9eb8b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 +https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 @@ -41,12 +41,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda#9ee58d5c534af06558933af3c845a780 +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda#2c42649888aac645608191ffdc80d13a https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 @@ -67,12 +67,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_16.conda#0617b134e4dc4474c1038707499f7eed +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_17.conda#5edfb6baf1af52fa7c0a7072a42d1558 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_16.conda#1b3152694d236cf233b76b8c56bf0eae +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -84,23 +84,23 @@ https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd -https://conda.anaconda.org/conda-forge/linux-64/svt-av1-3.1.2-hecca717_0.conda#9859766c658e78fec9afa4a54891d920 -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda#86bc20552bf46075e3d92b67f089172d +https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.0-hecca717_0.conda#9a6117aee038999ffefe6082ff1e9a81 +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_5.conda#6a0eb48e58684cca4d7acc8b7a0fd3c7 -https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.2-hceb46e0_1.conda#40feea2979654ed579f1cda7c63ccb94 +https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.22.0-hc31b594_1.conda#52019609422a72ec80c32bbc16a889d8 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.0-hc31b594_0.conda#f3ac2d8b1b3ac0ba4e42050279ef6ce8 https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_16.conda#e5eb2ddedabd0063e442f230755d2062 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_17.conda#d7954bb54fc77e7952a78e5e0d134df5 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-ha09017c_8.conda#6e9bf4ce797d0216bd2a58298b6290b5 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 @@ -113,29 +113,29 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 -https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45-default_hfdba357_105.conda#e410a8f80e22eb6d840e39ac6a34bd0e +https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_101.conda#83aa53cb3f5fc849851a84d777a60551 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_0.conda#fd6acbf37b40cbe919450fa58309fbe1 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h6395336_2.conda#c09c4ac973f7992ba0c6bb1aafd77bd4 +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda#22d5cc5fb45aab8ed3c00cde2938b825 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.0-h8d634f6_0.conda#65900b71509b2fd6c0a34a5dc1bd893a -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_2_cpython.conda#c4202a55b4486314fbb8c11bc43a29a0 +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.6-hb9d3cd8_0.conda#febbab7d15033c913d53c7a2c102309d +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda#def531a3ac77b7fb8c21d17bb5d0badb https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a -https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45-default_h4852527_105.conda#1bc3e6c577a1a206c36456bdeae406de -https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45-default_h4852527_105.conda#4b1e4ae87a52e9724a9ec0c7b822bc89 +https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_101.conda#9902aeb08445c03fb31e01beeb173988 +https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_101.conda#dec96579f9a7035a59492bf6ee613b53 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a @@ -146,7 +146,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.con https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-he8b2097_16.conda#d274bf1343507683e6eb2954d1871569 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hb1e0a52_17.conda#f5c501fe2a016ed0103f7a89d2ac0412 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -165,39 +165,39 @@ https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.co https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e -https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.1-py311haee01d2_0.conda#8cc656ea4773e02929cc58745669b116 +https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda#3eeeeb9e4827ace8c0c1419c85d590ad -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda#18de09b20462742fe093ba39185d9bac https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb -https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.2-pyhd8ed1ab_0.conda#5d99943f2ae3cc69e1ada12ce9d4d701 +https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.4-pyhcf101f3_0.conda#043f0599dc8aa023369deacdb5ac24eb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.6-hb9d3cd8_2.conda#d3c295b50f092ab525ffe3c2aa4b7413 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.6-hb9d3cd8_0.conda#5efa5fa6243a622445fdfd72aee15efa +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 -https://conda.anaconda.org/conda-forge/noarch/babel-2.17.0-pyhd8ed1ab_0.conda#0a01c169f0ab0f91b26e77a3301fbfe4 -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_16.conda#77e54ea3bd0888e65ed821f19f5d23ad +https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_0.conda#ea5be9abc2939c8431893b4e123a2065 +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_17.conda#4e58f090f75b2941346da3685564e7a7 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_17.conda#50dc15ac993bb5859f923979c81fafc8 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_16.conda#3065346248242b288fd4f73fe34f833e +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_20.conda#6a7d74012f6ff0b58fb8fcb5286fa584 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_17.conda#ea4724804b89ddc81d16cabe3f4719b5 https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.3-h5192d8d_0.conda#48560c0be24568c3d53a944d2d496818 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_16.conda#8729b9d902631b9ee604346a90a50031 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_17.conda#8f02f68c780b0a6eeba034af3ed1c00a https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 @@ -216,24 +216,24 @@ https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_ https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_16.conda#dcaf539ffe75649239192101037f1406 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h9ce9316_17.conda#d5db7829d4b9b1676419fca2c63909b3 +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_17.conda#dfcfcc0c20762eeb840771eda366940e +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h741da5e_20.conda#5f2bd1037991d4960438641a3ed3c5ae https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h310e576_17.conda#94474857477981fedf74cf7c47c88ba5 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h3c3a7a4_20.conda#4b46597b58a2495ec48c215a40e42f0c https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_2.conda#3c71daed530c0c26671a1b1b7010e746 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_2.conda#0ad9019bb10eda915fb0ce5f78fef13b +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_16.conda#f5b82e3d5f4d345e8e1a227636eeb64f +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_17.conda#329ef645bc2f75b4025cba573810e178 https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.11-h651a532_0.conda#d8d8894f8ced2c9be76dc9ad1ae531ce -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_16.conda#a3aa64ee3486f51eb61018939c88ef12 +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_17.conda#eae8e3fb1f5eecb829dd7347d33ecacb https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.4-pyhd8ed1ab_2.conda#bb0230917e2473c77d615104dbe8a49d https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 @@ -254,7 +254,7 @@ https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h273f733_0.conda#fc4da80856253cd3786551227c34bc7a +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h9837d23_1.conda#e30309a8776e0e969fa7092d7801641b https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.conda#643f8cb35133eb1be4919fb953f0a25f https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 @@ -265,7 +265,7 @@ https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.1.14-pyhd8ed1ab_0.conda#3888b51c92979cdeef45120181dc8420 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.1.28-pyhd8ed1ab_0.conda#e8d6529858171ac4babb28c334306c0d https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.22.0-py311h320fe9a_2.conda#e94b7f09b52628b89e66cdbd8c3029dd https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.12.0-pyhd8ed1ab_0.tar.bz2#05ee2fb22c1eca4309c06d11aff049f3 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 4639087c4bf08..eb01745ae02d0 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.conda#9e115653741810778c9a915a2f8439e7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_16.conda#4d2f224e8186e7881d53e3aead912f6c +https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_17.conda#0ad9074c91b35dbf8b58bc68a9f9bda0 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-2_gnu.tar.bz2#6168d71addc746e8f2b8d57dfd2edcea @@ -16,27 +16,27 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda#cf105bce884e4ef8c8ccdca9fe6695e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_16.conda#cf9cd6739a3b694dcf551d898e112331 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_17.conda#0d842d2053b95a6dbb83554948e7cbfe https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.3-he30d5cf_0.conda#4a98cbc4ade694520227402ff8880630 https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_8.conda#2921ac0b541bf37c69e66bd6d9a43bca https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda#e7df0aab10b9cbb73ab2a467ebfaf8c7 https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d5cf_1.conda#8ec1d03f3000108899d1799d9964f281 https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda#a9138815598fe6b91a1d6782ca657b0c https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.3-hfae3067_0.conda#b414e36fbb7ca122030276c75fa9c34a -https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-hd65408f_0.conda#0c5ad486dcfb188885e3cf8ba209b97b -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_16.conda#3e54a6d0f2ff0172903c0acfda9efc0e -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_16.conda#87b4ffedaba8b4d675479313af74f612 +https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda#2f364feefb6a7c00423e80dcb12db62a +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_17.conda#bcd31f4a57798bd158dfc0647fa77ca3 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_17.conda#577bd91c44237433e010e9b96aea7ee0 https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda#5a86bf847b9b926f3a4f203339748d78 https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda#5109d7f837a3dfdf5c60f60e311b041f https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda#96944e3c92386a12755b94619bae0b35 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_16.conda#52d9df8055af3f1665ba471cce77da48 +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_17.conda#500d275cb616d81b5d9828aedffc4bc3 https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda#cf2861212053d05f27ec49c3784ff8bb https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda#08aad7cbe9f5a6b460d0976076b6ae64 https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda#182afabe009dc78d8b73100255ee6868 -https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.0-h8e36d6e_0.conda#7624c6e01aecba942e9115e0f5a2af9d +https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda#25f5885f11e8b1f075bccf4a2da91c60 https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda#bb5a90c93e3bac3d5690acf76b4a6386 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libice-1.1.2-h86ecc28_0.conda#c8d8ec3e00cd0fd8a231789b91a7c5b7 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda#1c246e1105000c3660558459e2fd6d43 @@ -50,26 +50,26 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda#6553a5d017fe14859ea8a4e6ea5def8f https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda#2079727b538f6dd16f3fa579d4c3c53f https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda#fb640d776fc92b682a14e001980825b1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_16.conda#776cca322459d09aad229a49761c0654 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_17.conda#7fa4f07979f7aff0938e5664f43f7053 https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.3.0-h5ad3122_1.conda#c11818b31f7c054ce220041b2459aacb https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.54-h1abf092_0.conda#45b47396febdf400c55fe129cfc398aa -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_16.conda#20b7f96f58ccbe8931c3a20778fb3b32 +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_17.conda#beb8c015b02b7a1c2eea6d7a9847f8f5 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda#b4df5d7d4b63579d081fd3a4cf99740e https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda#8b5222a41b5d51fb1a5a2c514e770218 https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.47-hf841c20_0.conda#1a30c42e32ca0ea216bd0bfe6f842f0b https://conda.anaconda.org/conda-forge/linux-aarch64/pixman-0.46.4-h7ac5ae9_1.conda#1587081d537bd4ae77d1c0635d465ba5 https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda#3d49cad61f829f4f0e0611547a9cda12 -https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h561c983_103.conda#631db4799bc2bfe4daccf80bb3cbc433 +https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda#7fc6affb9b01e567d2ef1d05b84aa6ed https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.24.0-h4f8a99f_1.conda#f6966cb1f000c230359ae98c29e37d87 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda#2d1409c50882819cb1af2de82e2b7208 -https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.2-ha7cb516_1.conda#055d3357e5d6f57291a687c6983e1884 +https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda#f731af71c723065d91b4c01bb822641b https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 -https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.12.2-h185addb_0.conda#bd265b4c7864af1bcc22822150cf74be +https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.12.3-h185addb_0.conda#3fc03e82e28b1a9b346f1395585f53ff https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.21.3-h50a48e9_0.conda#29c10432a2ca1472b53f299ffb2ffa37 -https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45-default_h1979696_105.conda#849c4cbbf8dd1d71e66c13afed1d2f12 +https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda#35b2ae7fadf364b8e5fb8185aaeb80e5 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.1-hdae7a39_0.conda#9c2f56b6e011c6d8010ff43b796aab2f https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.3-hf53f6bf_0.conda#f226b9798c6c176d2a94eea1350b3b6b https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e @@ -93,10 +93,10 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.con https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.1-h825857f_1.conda#eb4665cdf78fd02d4abc4edf8c15b7b9 https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.30-pthreads_h3a8cbd8_4.conda#e3f245ed352bd66d181b73a78d886038 https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c -https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.14-h91f4b29_2_cpython.conda#622ae39bb186be3eeeaa564a9c7e1eec +https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.14-h91f4b29_3_cpython.conda#b4b58af4399ab0fc63ec86181494832b https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-image-0.4.0-h5c728e9_2.conda#b82e5c78dbbfa931980e8bfe83bce913 https://conda.anaconda.org/conda-forge/linux-aarch64/xkeyboard-config-2.46-he30d5cf_0.conda#9524f30d9dea7dd5d6ead43a8823b6c2 -https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.6-h57736b2_0.conda#bd1e86dd8aa3afd78a4bfdb4ef918165 +https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.7-he30d5cf_0.conda#fb42b683034619915863d68dd9df03a3 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5cf_0.conda#e8b4056544341daf1d415eaeae7a040c https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda#ae2c2dd0e2d38d249887727db2af960e https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 @@ -120,7 +120,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.0-py311h8e17b9e https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.1-pyh332efcf_0.conda#cb72cedd94dd923c6a9405a3d3b1c018 +https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -129,23 +129,23 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.3-py311hb9158a3 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-aarch64/unicodedata2-17.0.0-py311h19352d5_1.conda#4a55814831e0ec9be84ccef6aed798c1 https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-cursor-0.1.6-he30d5cf_0.conda#8b70063c86f7f9a0b045e78d2d9971f7 -https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcomposite-0.4.6-h86ecc28_2.conda#86051eee0766c3542be24844a9c3cf36 +https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcomposite-0.4.7-he30d5cf_0.conda#9c639c1abdbfe6759c5beb2c1db4bc13 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcursor-1.2.3-h86ecc28_0.conda#f2054759c2203d12d0007005e1f1296d https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdamage-1.1.6-h86ecc28_0.conda#d5773c4e4d64428d7ddaa01f6f845dc7 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda#eeee3bdb31c6acde2b81ad1b8c287087 -https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.4-h86ecc28_0.conda#dd3e74283a082381aa3860312e3c721e -https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.6-h86ecc28_0.conda#d745faa2d7c15092652e40a22bb261ed -https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.2-py311h2dad8b0_0.conda#f5b980d16f2bdd10fd1a6b2d902391cb +https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda#1f64c613f0b8d67e9fb0e165d898fb6b +https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.7-he30d5cf_0.conda#b15ca02584678f38df6e114c32f93959 +https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.3-py311h2dad8b0_0.conda#752a19eb90f17bfd279ce86563579501 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.15.0-h8dda3cd_1.conda#112b71b6af28b47c624bcbeefeea685b https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.1-py311h164a683_0.conda#b59452fef1470e7e5c34a7c5deefe853 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_2.conda#533210c236818b9042aea471585e9ea1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.8-default_h94a09a5_2.conda#5d79d5dd604ceb8e98f007e6770c379c +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_3.conda#4ba7653ca09e74e8968120c6aea4bfb1 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.8-default_h94a09a5_3.conda#d294b96fc51b22e382e5220937c738f4 https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-5_hb558247_openblas.conda#8046d5ae90150f00c8b40455d9b2e180 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.1-hf8816c8_3.conda#e0d7a6cbc0b8a6d05002cb9bd061a4af -https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.328.1-h8b8848b_0.conda#e5a3ff3a266b68398bd28ed1d4363e65 -https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.1-py311h669026d_0.conda#e6f40fe186c60f1a6c54a8697213c5cd +https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.341.0-h8b8848b_0.conda#06bb91a87fb97ea09398d2e121e00c39 +https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.2-py311h669026d_1.conda#6b411688a868a37d95abfb99ebc8b88e https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f @@ -154,14 +154,14 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-5_h967826 https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311h04741b4_4.conda#1eeea54b0c520a475db39f8c711de661 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/noarch/pip-25.3-pyh8b19718_0.conda#c55515ca43c6444d2572e0f0d93cb6b9 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.0-py311h399493a_1.conda#ea481eda36e28a2487d0fe2891d168ff https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.305-openblas.conda#2efe635198609d0d2a122c6a0923b8f8 -https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-12.3.0-h1134a53_0.conda#60d635185d9c39e6c8dbd1771e6c7267 +https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-12.3.2-h1134a53_0.conda#f8ab08bc3716972b7bd47e48a6884260 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.10.1-h5343e53_4.conda#e14686527190e7b30fad9a49da71325b -https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.10.1-py311hf1caecd_0.conda#5877515b7a3ef76e2468c4f20d6d6997 +https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.10.2-h5343e53_4.conda#d21d5b2950f78f8f187aec04869bc9b3 +https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.10.2-py311hf1caecd_0.conda#a245e6ef62e8403f5c5e449e6227924d https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.8-py311hfecb2dc_0.conda#3920b856b59a909812f1913b96adaad8 From ed8fc93128145c60e06a412c7f83eacd5b6de39c Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 9 Feb 2026 04:24:29 -0500 Subject: [PATCH 195/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33247) Co-authored-by: Lock file bot --- ...a_forge_cuda_array-api_linux-64_conda.lock | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 9703e88ca69ea..a57cd5009e579 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -102,7 +102,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17. https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 -https://conda.anaconda.org/conda-forge/linux-64/nccl-2.29.2.1-h4d09622_1.conda#cda0cd556f99190e28f083c5125be060 +https://conda.anaconda.org/conda-forge/linux-64/nccl-2.29.2.1-h4d09622_2.conda#a8e54c58b3efc6fbbe8dfeb9f65c28d6 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 @@ -119,7 +119,7 @@ https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-hdaf4b65_5.conda#132e8f8f40f0ffc0bbde12bb4e8dd1a1 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_1.conda#55a83761db33f82d92d7d7a4a61662e5 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca @@ -183,7 +183,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0. https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.3-hef928c7_0.conda#bdd464b33f6540ed70845b946c11a7b8 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-hc63082f_11.conda#6a653aefdc5d83a4f959869d1759e6e3 -https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.1-h3a458e0_0.conda#1d4e0d37da5f3c22ecd44033f673feba +https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.3.3-pyhcf101f3_0.conda#b08fa4a3478526e33a4c08224398d2e5 @@ -193,7 +193,7 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda#9bcbd351966dc56a24fc0c368da5ad99 https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda#2cfaaccf085c133a477f0a7a8657afe9 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.1.0-pyhd8ed1ab_0.conda#1daaf94a304a27ba3446a306235a37ea +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 @@ -222,7 +222,7 @@ https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0. https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda#7b446fcbb6779ee479debb4fd7453e6c +https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -238,8 +238,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.cond https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.3-h06ab39a_1.conda#3689a4290319587e3b54a4f9e68f70c8 -https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.2-h3a5f585_1.conda#4e921d9c85e6559c60215497978b3cdb -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-h3d7a050_0.conda#e6f12de3a9b016cea81a87db04d85ff3 +https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.3-py313h3dea7bd_0.conda#fa90494c873b21b3bdb21c3b588ff043 https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.5-py313h929d4db_0.conda#f2416964cdb2808dd2ed5be276a8fcdb https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab @@ -268,7 +268,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.co https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.4-h8824e59_0.conda#113b9d9913280474c0868b0e290c0326 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-h75daedc_0.conda#e88f8e816ae46c12cbe912c8f4d9d3bc +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 @@ -285,35 +285,35 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10.conda#937d1d4c233adc6eeb2ac3d6e9a73e53 -https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-hd454692_0.conda#55986e49b7aafe9aa09d7f4c70a56a18 +https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/cupy-13.6.0-py313h586c94b_2.conda#0685ae3980f823b2ca78552f7d8d4033 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.0-py310hffdcd12_0.conda#55bba24eb42fccab68125573fe3e702e +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hffdcd12_0.conda#b659a59ec7b67623dcaec02388e06fb9 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_h673abb8_201.conda#f8dae51be1b9afdccd70b576b8f73b44 https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h2c50142_1_cpu.conda#fba261a7ee565b711b45c5bea554e5a0 -https://conda.anaconda.org/conda-forge/noarch/polars-1.38.0-pyh6a1acc5_0.conda#d9f44a3b02ff198d40562d05e758ad03 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h258748b_2_cuda.conda#c364f39d8a924797157da59d8cdd6b97 +https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_201.conda#fb17e944f1ff5c1ab65822ba1f539b9d https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h8c2c5c3_1_cpu.conda#102be5396c7899675268c17993e1a072 -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_1_cpu.conda#e7562d15926b3cea66a6e3546b133c5d +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h8c2c5c3_2_cuda.conda#7846ea1f43ef6beb04749b5dffd6e4da +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_2_cuda.conda#1e2a463be2b1248c214b246fa14b72f6 https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313h85046ba_0.conda#f6161781ceb86e9f5da1b532e4c4453c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_1_cpu.conda#8b1290b259b24a4b29b3a3d6dec0fe53 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_2_cuda.conda#b1f327dae633933118765c113fd3ecd0 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py313he109ebe_0_cpu.conda#9120bf253ebbdb0015069b9a25cf4d36 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_1_cpu.conda#651c34402277a875986db6fa7930d42d +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py313hc6b0d6e_0_cuda.conda#c0ee292386cfb7e143117c26d26698ea +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_2_cuda.conda#fa0aa202043167a22dd7638c08004cb2 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.02.00-cuda12_260204_a2f5a8b7.conda#361cae27e77618c6ba9f943807471f9f https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.02.00-cuda12_py313_260204_c212ab9b.conda#14933b753ec82f9d5a61d7cb4b5e2e71 https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.02.00-cuda12_py313_260204_a2f5a8b7.conda#c46807878ad576379e7be3acc187d13a -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-h3f74fd7_1_cpu.conda#bcf3ca0f04ed703121db4012e8c8bf5a +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-h3f74fd7_2_cuda.conda#cf0b0682dadc05c597b11ff24ae6c0b7 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.0-py313h78bf25f_0.conda#a6e89cb214f318db9548b791ba27f862 From f3bc33252152c283b1a3ae53840467436f8c0531 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 9 Feb 2026 04:24:55 -0500 Subject: [PATCH 196/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33246) Co-authored-by: Lock file bot --- .../pylatest_pip_scipy_dev_linux-64_conda.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 53bcc07b0de2a..871d065304336 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -6,15 +6,15 @@ https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.ta https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -25,16 +25,16 @@ https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.cond https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-h32b2ec7_101_cp314.conda#051f60a9d1e3aae7160d173aeb7029f8 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda#f08a17c938eb6bc1b928bd8cdd37e20f +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_100_cp314.conda#b40594d5da041824087eebe12228af42 +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c # pip charset-normalizer @ https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 -# pip coverage @ https://files.pythonhosted.org/packages/ba/49/f54ec02ed12be66c8d8897270505759e057b0c68564a65c429ccdd1f139e/coverage-7.13.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=a7fc042ba3c7ce25b8a9f097eb0f32a5ce1ccdb639d9eec114e26def98e1f8a4 +# pip coverage @ https://files.pythonhosted.org/packages/72/2d/b3f6913ee5a1d5cdd04106f257e5fac5d048992ffc2d9995d07b0f17739f/coverage-7.13.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=06e49c5897cb12e3f7ecdc111d44e97c4f6d0557b81a7a0204ed70a8b038f86f # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea From c9b33168ca6a58947c102216c6f097c7e484e75d Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Tue, 10 Feb 2026 21:09:01 +1100 Subject: [PATCH 197/462] TST Refactor out helper in `pos_label` display curve tests (#33223) --- .../_plot/tests/test_common_curve_display.py | 97 +++++++++++++- .../_plot/tests/test_roc_curve_display.py | 120 +++--------------- 2 files changed, 115 insertions(+), 102 deletions(-) diff --git a/sklearn/metrics/_plot/tests/test_common_curve_display.py b/sklearn/metrics/_plot/tests/test_common_curve_display.py index f3499ba53cd0a..e771b47f8ef6f 100644 --- a/sklearn/metrics/_plot/tests/test_common_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_common_curve_display.py @@ -4,7 +4,7 @@ from sklearn.base import BaseEstimator, ClassifierMixin, clone from sklearn.calibration import CalibrationDisplay from sklearn.compose import make_column_transformer -from sklearn.datasets import load_iris +from sklearn.datasets import load_breast_cancer, load_iris from sklearn.exceptions import NotFittedError from sklearn.linear_model import LogisticRegression from sklearn.metrics import ( @@ -14,9 +14,11 @@ PredictionErrorDisplay, RocCurveDisplay, ) +from sklearn.model_selection import cross_validate, train_test_split from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor +from sklearn.utils import shuffle @pytest.fixture(scope="module") @@ -30,6 +32,99 @@ def data_binary(data): return X[y < 2], y[y < 2] +def _check_pos_label_statistics( + display_class, response_method, constructor_name, check_metric +): + """Test switching `pos_label` gives correct statistics, using imbalanced data.""" + X, y = load_breast_cancer(return_X_y=True) + # create highly imbalanced classes + idx_positive = np.flatnonzero(y == 1) + idx_negative = np.flatnonzero(y == 0) + idx_selected = np.hstack([idx_negative, idx_positive[:25]]) + X, y = X[idx_selected], y[idx_selected] + X, y = shuffle(X, y, random_state=42) + # only use 2 features to make the problem even harder + X = X[:, :2] + y = np.array(["cancer" if c == 1 else "not cancer" for c in y], dtype=object) + X_train, X_test, y_train, y_test = train_test_split( + X, + y, + stratify=y, + random_state=0, + ) + + classifier = LogisticRegression() + classifier.fit(X_train, y_train) + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) + + # Sanity check to be sure the positive class is `classes_[0]`. + # Class imbalance ensures a large difference in prediction values between classes, + # allowing us to catch errors when we switch `pos_label`. + assert classifier.classes_.tolist() == ["cancer", "not cancer"] + + y_score = getattr(classifier, response_method)(X_test) + # we select the corresponding probability columns or reverse the decision + # function otherwise + y_score_cancer = -1 * y_score if y_score.ndim == 1 else y_score[:, 0] + y_score_not_cancer = y_score if y_score.ndim == 1 else y_score[:, 1] + + pos_label = "cancer" + y_score = y_score_cancer + if constructor_name == "from_estimator": + display = display_class.from_estimator( + classifier, + X_test, + y_test, + pos_label=pos_label, + response_method=response_method, + ) + elif constructor_name == "from_predictions": + display = display_class.from_predictions( + y_test, + y_score, + pos_label=pos_label, + ) + else: + display = display_class.from_cv_results( + cv_results, + X, + y, + response_method=response_method, + pos_label=pos_label, + ) + + check_metric(display, constructor_name, pos_label) + + pos_label = "not cancer" + y_score = y_score_not_cancer + if constructor_name == "from_estimator": + display = display_class.from_estimator( + classifier, + X_test, + y_test, + response_method=response_method, + pos_label=pos_label, + ) + elif constructor_name == "from_predictions": + display = display_class.from_predictions( + y_test, + y_score, + pos_label=pos_label, + ) + else: + display = display_class.from_cv_results( + cv_results, + X, + y, + response_method=response_method, + pos_label=pos_label, + ) + + check_metric(display, constructor_name, pos_label) + + @pytest.mark.parametrize( "Display", [CalibrationDisplay, DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay], diff --git a/sklearn/metrics/_plot/tests/test_roc_curve_display.py b/sklearn/metrics/_plot/tests/test_roc_curve_display.py index 72c636acd33cf..e426b7b99f67e 100644 --- a/sklearn/metrics/_plot/tests/test_roc_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_roc_curve_display.py @@ -7,14 +7,17 @@ from sklearn import clone from sklearn.compose import make_column_transformer -from sklearn.datasets import load_breast_cancer, make_classification +from sklearn.datasets import make_classification from sklearn.exceptions import NotFittedError, UndefinedMetricWarning from sklearn.linear_model import LogisticRegression from sklearn.metrics import RocCurveDisplay, auc, roc_curve -from sklearn.model_selection import cross_validate, train_test_split +from sklearn.metrics._plot.tests.test_common_curve_display import ( + _check_pos_label_statistics, +) +from sklearn.model_selection import cross_validate from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler -from sklearn.utils import _safe_indexing, shuffle +from sklearn.utils import _safe_indexing from sklearn.utils._response import _get_response_values_binary @@ -822,112 +825,27 @@ def test_roc_curve_display_default_labels( assert disp.line_[idx].get_label() == expected_label -def _check_auc(display, constructor_name): - roc_auc_limit = 0.95679 - roc_auc_limit_multi = [0.97007, 0.985915, 0.980952] - - if constructor_name == "from_cv_results": - for idx, roc_auc in enumerate(display.roc_auc): - assert roc_auc == pytest.approx(roc_auc_limit_multi[idx]) - else: - assert display.roc_auc == pytest.approx(roc_auc_limit) - assert trapezoid(display.tpr, display.fpr) == pytest.approx(roc_auc_limit) - - @pytest.mark.parametrize("response_method", ["predict_proba", "decision_function"]) @pytest.mark.parametrize( "constructor_name", ["from_estimator", "from_predictions", "from_cv_results"] ) def test_plot_roc_curve_pos_label(pyplot, response_method, constructor_name): - # check that we can provide the positive label and display the proper - # statistics - X, y = load_breast_cancer(return_X_y=True) - # create a highly imbalanced version of the breast cancer dataset - idx_positive = np.flatnonzero(y == 1) - idx_negative = np.flatnonzero(y == 0) - idx_selected = np.hstack([idx_negative, idx_positive[:25]]) - X, y = X[idx_selected], y[idx_selected] - X, y = shuffle(X, y, random_state=42) - # only use 2 features to make the problem even harder - X = X[:, :2] - y = np.array(["cancer" if c == 1 else "not cancer" for c in y], dtype=object) - X_train, X_test, y_train, y_test = train_test_split( - X, - y, - stratify=y, - random_state=0, - ) - - classifier = LogisticRegression() - classifier.fit(X_train, y_train) - cv_results = cross_validate( - LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True - ) - - # Sanity check to be sure the positive class is `classes_[0]` - # Class imbalance ensures a large difference in prediction values between classes, - # allowing us to catch errors when we switch `pos_label` - assert classifier.classes_.tolist() == ["cancer", "not cancer"] + """Test switching `pos_label` gives correct statistics, using imbalanced data.""" - y_score = getattr(classifier, response_method)(X_test) - # we select the corresponding probability columns or reverse the decision - # function otherwise - y_score_cancer = -1 * y_score if y_score.ndim == 1 else y_score[:, 0] - y_score_not_cancer = y_score if y_score.ndim == 1 else y_score[:, 1] + def _check_auc(display, constructor_name, pos_label): + roc_auc_limit = 0.95679 + roc_auc_limit_multi = [0.97007, 0.985915, 0.980952] - pos_label = "cancer" - y_score = y_score_cancer - if constructor_name == "from_estimator": - display = RocCurveDisplay.from_estimator( - classifier, - X_test, - y_test, - pos_label=pos_label, - response_method=response_method, - ) - elif constructor_name == "from_predictions": - display = RocCurveDisplay.from_predictions( - y_test, - y_score, - pos_label=pos_label, - ) - else: - display = RocCurveDisplay.from_cv_results( - cv_results, - X, - y, - response_method=response_method, - pos_label=pos_label, - ) - - _check_auc(display, constructor_name) - - pos_label = "not cancer" - y_score = y_score_not_cancer - if constructor_name == "from_estimator": - display = RocCurveDisplay.from_estimator( - classifier, - X_test, - y_test, - response_method=response_method, - pos_label=pos_label, - ) - elif constructor_name == "from_predictions": - display = RocCurveDisplay.from_predictions( - y_test, - y_score, - pos_label=pos_label, - ) - else: - display = RocCurveDisplay.from_cv_results( - cv_results, - X, - y, - response_method=response_method, - pos_label=pos_label, - ) + if constructor_name == "from_cv_results": + for idx, roc_auc in enumerate(display.roc_auc): + assert roc_auc == pytest.approx(roc_auc_limit_multi[idx]) + else: + assert display.roc_auc == pytest.approx(roc_auc_limit) + assert trapezoid(display.tpr, display.fpr) == pytest.approx(roc_auc_limit) - _check_auc(display, constructor_name) + _check_pos_label_statistics( + RocCurveDisplay, response_method, constructor_name, _check_auc + ) # TODO(1.9): remove From 9f07f64e7867788beff0d668576070ecaa953a5c Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Tue, 10 Feb 2026 13:12:17 +0100 Subject: [PATCH 198/462] DOC D2 Brier score aka scaled Brier score (#33253) --- doc/modules/model_evaluation.rst | 9 +++++---- sklearn/metrics/_classification.py | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index 823c41ac8f664..06a02b49731d5 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -2003,9 +2003,10 @@ the same does a lower Brier score loss always mean better calibration" .. rubric:: References -.. [Brier1950] G. Brier, `Verification of forecasts expressed in terms of probability - `_, - Monthly weather review 78.1 (1950) +.. [Brier1950] G. Brier (1950). + :doi:`"Verification of forecasts expressed in terms of probability" + <10.1175/1520-0493(1950)078%3C0001:VOFEIT%3E2.0.CO;2>`. + Monthly Weather Review 78(1), 1-3 .. [Bella2012] Bella, Ferri, Hernández-Orallo, and Ramírez-Quintana `"Calibration of Machine Learning Models" @@ -2219,7 +2220,7 @@ of 0.0. \text{dev}(y, \hat{y}) = \text{brier_score_loss}(y, \hat{y}). - This is also referred to as the Brier Skill Score (BSS). + This is also referred to as the Brier Skill Score (BSS) and scaled Brier score. Here are some usage examples of the :func:`d2_brier_score` function:: diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 77fc49bb63622..9c451f52b9dda 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -3956,6 +3956,8 @@ def d2_brier_score( ): """:math:`D^2` score function, fraction of Brier score explained. + This is also known as Brier Skill Score (BSS) and scaled Brier score. + Best possible score is 1.0 and it can be negative because the model can be arbitrarily worse than the null model. The null model, also known as the optimal intercept model, is a model that constantly predicts the per-class From 8b6df227b2b0643a62b156ea860b175ca594f72c Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Tue, 10 Feb 2026 15:32:59 +0100 Subject: [PATCH 199/462] TST remove redundant yield of `check_estimator_cloneable` (#33210) Co-authored-by: Adrin Jalali --- sklearn/utils/estimator_checks.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index 689df6b616189..6502de34bd345 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -130,7 +130,11 @@ def _yield_api_checks(estimator): ) tags = get_tags(estimator) - yield check_estimator_cloneable + # This is commented out since it's the first check both + # `parametrize_with_checks` and `check_esitmator` do + # anyway. But leaving it here as commented out to know + # it's a part of the basic API. + # yield check_estimator_cloneable yield check_estimator_tags_renamed yield check_valid_tag_types yield check_estimator_repr From d224a099ef535d74cc1d97d7795191448265d6ca Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Wed, 11 Feb 2026 02:16:28 +1100 Subject: [PATCH 200/462] TST Move common binary Display class tests to `test_common_curve_display.py` (#33218) --- .../_plot/tests/test_common_curve_display.py | 375 +++++++++++++++++- .../_plot/tests/test_roc_curve_display.py | 249 +----------- 2 files changed, 375 insertions(+), 249 deletions(-) diff --git a/sklearn/metrics/_plot/tests/test_common_curve_display.py b/sklearn/metrics/_plot/tests/test_common_curve_display.py index e771b47f8ef6f..a717494e0003f 100644 --- a/sklearn/metrics/_plot/tests/test_common_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_common_curve_display.py @@ -1,10 +1,13 @@ +from collections.abc import Mapping +from contextlib import suppress + import numpy as np import pytest from sklearn.base import BaseEstimator, ClassifierMixin, clone from sklearn.calibration import CalibrationDisplay from sklearn.compose import make_column_transformer -from sklearn.datasets import load_breast_cancer, load_iris +from sklearn.datasets import load_breast_cancer, load_iris, make_classification from sklearn.exceptions import NotFittedError from sklearn.linear_model import LogisticRegression from sklearn.metrics import ( @@ -375,6 +378,376 @@ class SubclassOfDisplay(Display): assert isinstance(curve, SubclassOfDisplay) +@pytest.mark.parametrize( + "Display, display_args", + [ + ( + RocCurveDisplay, + { + "fpr": np.array([0, 0.5, 1]), + "tpr": [np.array([0, 0.5, 1])], + "roc_auc": None, + "name": "test_curve", + }, + ), + ], +) +def test_display_validate_plot_params(pyplot, Display, display_args): + """Check `_validate_plot_params` returns the correct variables. + + `display_args` should be given in the same order as output by + `_validate_plot_params`. All `display_args` should be for a single curve. + """ + display = Display(**display_args) + results = display._validate_plot_params(ax=None, name=None) + + # Check if the number of parameters match + assert len(results) == len(display_args) + + for idx, (param, value) in enumerate(display_args.items()): + if param == "name": + assert results[idx] == [value] if isinstance(value, str) else value + elif value is None: + assert results[idx] is None + else: + assert isinstance(results[idx], list) + assert len(results[idx]) == 1 + + +auc_metrics = [[1.0, 1.0, 1.0], None] + + +@pytest.mark.parametrize( + "Display, auc_metric_name, auc_arg_name, display_args", + [ + pytest.param( + RocCurveDisplay, + "AUC", + "roc_auc", + { + "fpr": [np.array([0, 0.5, 1])] * 3, + "tpr": [np.array([0, 0.5, 1])] * 3, + "roc_auc": auc_metric, + }, + ) + for auc_metric in auc_metrics + ], +) +@pytest.mark.parametrize( + "curve_kwargs", + [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], +) +@pytest.mark.parametrize("name", [None, "single", ["one", "two", "three"]]) +def test_display_plot_legend_label( + pyplot, Display, auc_metric_name, auc_arg_name, display_args, curve_kwargs, name +): + """Check legend label correct with all `curve_kwargs`, `name` combinations. + + Checks `from_estimator` and `from_predictions` methods, when plotting multiple + curves. + """ + if not isinstance(curve_kwargs, list) and isinstance(name, list): + with pytest.raises(ValueError, match="To avoid labeling individual curves"): + Display(**display_args).plot(name=name, curve_kwargs=curve_kwargs) + return + + display = Display(**display_args).plot(name=name, curve_kwargs=curve_kwargs) + legend = display.ax_.get_legend() + auc_metric = display_args[auc_arg_name] + + if legend is None: + # No legend is created, exit test early + assert name is None + assert auc_metric is None + return + else: + legend_labels = [text.get_text() for text in legend.get_texts()] + + if isinstance(curve_kwargs, list): + # Multiple labels in legend + assert len(legend_labels) == 3 + for idx, label in enumerate(legend_labels): + if name is None: + expected_label = f"{auc_metric_name} = 1.00" if auc_metric else None + assert label == expected_label + elif isinstance(name, str): + expected_label = ( + f"single ({auc_metric_name} = 1.00)" if auc_metric else "single" + ) + assert label == expected_label + else: + # `name` is a list of different strings + expected_label = ( + f"{name[idx]} ({auc_metric_name} = 1.00)" + if auc_metric + else f"{name[idx]}" + ) + assert label == expected_label + else: + # Single label in legend + assert len(legend_labels) == 1 + if name is None: + expected_label = ( + f"{auc_metric_name} = 1.00 +/- 0.00" if auc_metric else None + ) + assert legend_labels[0] == expected_label + else: + # name is single string + expected_label = ( + f"single ({auc_metric_name} = 1.00 +/- 0.00)" + if auc_metric + else "single" + ) + assert legend_labels[0] == expected_label + # Close plots, prevents "more than 20 figures" opened warning + pyplot.close("all") + + +@pytest.mark.parametrize( + "Display, auc_metrics, auc_metric_name", + [ + (RocCurveDisplay, [0.96, 1.00, 1.00], "AUC"), + ], +) +@pytest.mark.parametrize( + "curve_kwargs", + [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], +) +@pytest.mark.parametrize("name", [None, "single", ["one", "two", "three"]]) +def test_display_from_cv_results_legend_label( + pyplot, Display, auc_metrics, auc_metric_name, curve_kwargs, name +): + """Check legend label correct with all `curve_kwargs`, `name` combinations. + + This function verifies that the legend labels in a Display object created from + cross-validation results are correctly formatted based on the provided parameters. + """ + X, y = X, y = make_classification(n_classes=2, n_samples=50, random_state=0) + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) + + if not isinstance(curve_kwargs, list) and isinstance(name, list): + with pytest.raises(ValueError, match="To avoid labeling individual curves"): + Display.from_cv_results( + cv_results, X, y, name=name, curve_kwargs=curve_kwargs + ) + else: + display = Display.from_cv_results( + cv_results, X, y, name=name, curve_kwargs=curve_kwargs + ) + + legend = display.ax_.get_legend() + legend_labels = [text.get_text() for text in legend.get_texts()] + if isinstance(curve_kwargs, list): + # Multiple labels in legend + assert len(legend_labels) == 3 + for idx, label in enumerate(legend_labels): + if name is None: + assert label == f"{auc_metric_name} = {auc_metrics[idx]:.2f}" + elif isinstance(name, str): + assert ( + label == f"single ({auc_metric_name} = {auc_metrics[idx]:.2f})" + ) + else: + # `name` is a list of different strings + assert ( + label + == f"{name[idx]} ({auc_metric_name} = {auc_metrics[idx]:.2f})" + ) + else: + # Single label in legend + assert len(legend_labels) == 1 + if name is None: + assert legend_labels[0] == ( + f"{auc_metric_name} = {np.mean(auc_metrics):.2f} +/- " + f"{np.std(auc_metrics):.2f}" + ) + else: + # name is single string + assert legend_labels[0] == ( + f"single ({auc_metric_name} = {np.mean(auc_metrics):.2f} +/- " + f"{np.std(auc_metrics):.2f})" + ) + # Close plots, prevents "more than 20 figures" opened warning + pyplot.close("all") + + +@pytest.mark.parametrize("Display", [RocCurveDisplay]) +def test_display_from_cv_results_param_validation(pyplot, data_binary, Display): + """Check parameter validation is correct.""" + X, y = data_binary + + # `cv_results` missing key + cv_results_no_est = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=False + ) + cv_results_no_indices = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=False + ) + for cv_results in (cv_results_no_est, cv_results_no_indices): + with pytest.raises( + ValueError, + match="`cv_results` does not contain one of the following required", + ): + Display.from_cv_results(cv_results, X, y) + + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) + + # `X` wrong length + with pytest.raises(ValueError, match="`X` does not contain the correct"): + Display.from_cv_results(cv_results, X[:10, :], y) + + # `y` not binary + y_multi = y.copy() + y_multi[0] = 2 + with pytest.raises(ValueError, match="The target `y` is not binary."): + Display.from_cv_results(cv_results, X, y_multi) + + # input inconsistent length + with pytest.raises(ValueError, match="Found input variables with inconsistent"): + Display.from_cv_results(cv_results, X, y[:10]) + with pytest.raises(ValueError, match="Found input variables with inconsistent"): + Display.from_cv_results(cv_results, X, y, sample_weight=[1, 2]) + + # `pos_label` inconsistency + y_multi[y_multi == 1] = 2 + with suppress(ValueError): # ignore any `pos_label` side errors + with pytest.warns( + # Also captures subclass warnings e.g., `UndefinedMetricWarning` + UserWarning, + match="No positive .* in y_true", + ): + Display.from_cv_results(cv_results, X, y_multi) + + # `name` is list while `curve_kwargs` is None or dict + for curve_kwargs in (None, {"alpha": 0.2}): + with pytest.raises(ValueError, match="To avoid labeling individual curves"): + Display.from_cv_results( + cv_results, + X, + y, + name=["one", "two", "three"], + curve_kwargs=curve_kwargs, + ) + + # `curve_kwargs` incorrect length + with pytest.raises(ValueError, match="`curve_kwargs` must be None, a dictionary"): + Display.from_cv_results(cv_results, X, y, curve_kwargs=[{"alpha": 1}]) + + # `curve_kwargs` both alias provided + with pytest.raises(TypeError, match="Got both c and"): + Display.from_cv_results( + cv_results, X, y, curve_kwargs={"c": "blue", "color": "red"} + ) + + +@pytest.mark.parametrize("Display", [RocCurveDisplay]) +def test_display_from_cv_results_pos_label_inferred(pyplot, data_binary, Display): + """Check `pos_label` inferred correctly by `from_cv_results(pos_label=None)`.""" + X, y = data_binary + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) + + disp = Display.from_cv_results(cv_results, X, y, pos_label=None) + # Should be `estimator.classes_[1]` + assert disp.pos_label == 1 + + +@pytest.mark.parametrize("Display", [RocCurveDisplay]) +@pytest.mark.parametrize( + "constructor_name, expected_clf_name", + [ + ("from_estimator", "LogisticRegression"), + ("from_predictions", "Classifier"), + ], +) +def test_display_default_name( + pyplot, + data_binary, + constructor_name, + expected_clf_name, + Display, +): + """Check the default name display in the figure when `name` is not provided.""" + X, y = data_binary + + lr = LogisticRegression().fit(X, y) + y_score = lr.predict_proba(X)[:, 1] + + if constructor_name == "from_estimator": + disp = Display.from_estimator(lr, X, y) + else: + disp = Display.from_predictions(y, y_score) + + assert expected_clf_name in disp.name + assert expected_clf_name in disp.line_.get_label() + + +@pytest.mark.parametrize("Display", [RocCurveDisplay]) +@pytest.mark.parametrize( + "curve_kwargs", + [None, {"alpha": 0.2}, [{"alpha": 0.2}, {"alpha": 0.3}, {"alpha": 0.4}]], +) +def test_display_from_cv_results_curve_kwargs( + pyplot, data_binary, curve_kwargs, Display +): + """Check `curve_kwargs` correctly passed.""" + X, y = data_binary + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) + display = Display.from_cv_results( + cv_results, + X, + y, + curve_kwargs=curve_kwargs, + ) + if curve_kwargs is None: + # Default `alpha` used + assert all(line.get_alpha() == 0.5 for line in display.line_) + elif isinstance(curve_kwargs, Mapping): + # `alpha` from dict used for all curves + assert all(line.get_alpha() == 0.2 for line in display.line_) + else: + # Different `alpha` used for each curve + assert all( + line.get_alpha() == curve_kwargs[i]["alpha"] + for i, line in enumerate(display.line_) + ) + + +@pytest.mark.parametrize("Display", [RocCurveDisplay]) +@pytest.mark.parametrize( + "curve_kwargs", + [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], +) +def test_display_from_cv_results_curve_kwargs_default_kwargs( + pyplot, data_binary, curve_kwargs, Display +): + """Check `curve_kwargs` and default color handled correctly in `from_cv_results`.""" + + X, y = data_binary + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) + display = Display.from_cv_results(cv_results, X, y, curve_kwargs=curve_kwargs) + + for idx, line in enumerate(display.line_): + color = line.get_color() + if curve_kwargs is None: + # Default color + assert color == "blue" + elif isinstance(curve_kwargs, Mapping): + # All curves "red" + assert color == "red" + else: + assert color == curve_kwargs[idx]["c"] + + @pytest.mark.parametrize( "Display, display_kwargs", [ diff --git a/sklearn/metrics/_plot/tests/test_roc_curve_display.py b/sklearn/metrics/_plot/tests/test_roc_curve_display.py index e426b7b99f67e..2049ff34e3546 100644 --- a/sklearn/metrics/_plot/tests/test_roc_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_roc_curve_display.py @@ -8,7 +8,7 @@ from sklearn import clone from sklearn.compose import make_column_transformer from sklearn.datasets import make_classification -from sklearn.exceptions import NotFittedError, UndefinedMetricWarning +from sklearn.exceptions import NotFittedError from sklearn.linear_model import LogisticRegression from sklearn.metrics import RocCurveDisplay, auc, roc_curve from sklearn.metrics._plot.tests.test_common_curve_display import ( @@ -200,135 +200,6 @@ def test_roc_curve_plot_parameter_length_validation(pyplot, params, err_msg): display.plot() -def test_validate_plot_params(pyplot): - """Check `_validate_plot_params` returns the correct variables.""" - fpr = np.array([0, 0.5, 1]) - tpr = [np.array([0, 0.5, 1])] - roc_auc = None - name = "test_curve" - - # Initialize display with test inputs - display = RocCurveDisplay( - fpr=fpr, - tpr=tpr, - roc_auc=roc_auc, - name=name, - pos_label=None, - ) - fpr_out, tpr_out, roc_auc_out, name_out = display._validate_plot_params( - ax=None, name=None - ) - - assert isinstance(fpr_out, list) - assert isinstance(tpr_out, list) - assert len(fpr_out) == 1 - assert len(tpr_out) == 1 - assert roc_auc_out is None - assert name_out == ["test_curve"] - - -def test_roc_curve_from_cv_results_param_validation(pyplot, data_binary): - """Check parameter validation is correct.""" - X, y = data_binary - - # `cv_results` missing key - cv_results_no_est = cross_validate( - LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=False - ) - cv_results_no_indices = cross_validate( - LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=False - ) - for cv_results in (cv_results_no_est, cv_results_no_indices): - with pytest.raises( - ValueError, - match="`cv_results` does not contain one of the following required", - ): - RocCurveDisplay.from_cv_results(cv_results, X, y) - - cv_results = cross_validate( - LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True - ) - - # `X` wrong length - with pytest.raises(ValueError, match="`X` does not contain the correct"): - RocCurveDisplay.from_cv_results(cv_results, X[:10, :], y) - - # `y` not binary - y_multi = y.copy() - y_multi[0] = 2 - with pytest.raises(ValueError, match="The target `y` is not binary."): - RocCurveDisplay.from_cv_results(cv_results, X, y_multi) - - # input inconsistent length - with pytest.raises(ValueError, match="Found input variables with inconsistent"): - RocCurveDisplay.from_cv_results(cv_results, X, y[:10]) - with pytest.raises(ValueError, match="Found input variables with inconsistent"): - RocCurveDisplay.from_cv_results(cv_results, X, y, sample_weight=[1, 2]) - - # `pos_label` inconsistency - y_multi[y_multi == 1] = 2 - with pytest.warns(UndefinedMetricWarning, match="No positive samples in y_true"): - RocCurveDisplay.from_cv_results(cv_results, X, y_multi) - - # `name` is list while `curve_kwargs` is None or dict - for curve_kwargs in (None, {"alpha": 0.2}): - with pytest.raises(ValueError, match="To avoid labeling individual curves"): - RocCurveDisplay.from_cv_results( - cv_results, - X, - y, - name=["one", "two", "three"], - curve_kwargs=curve_kwargs, - ) - - # `curve_kwargs` incorrect length - with pytest.raises(ValueError, match="`curve_kwargs` must be None, a dictionary"): - RocCurveDisplay.from_cv_results(cv_results, X, y, curve_kwargs=[{"alpha": 1}]) - - # `curve_kwargs` both alias provided - with pytest.raises(TypeError, match="Got both c and"): - RocCurveDisplay.from_cv_results( - cv_results, X, y, curve_kwargs={"c": "blue", "color": "red"} - ) - - -@pytest.mark.parametrize( - "curve_kwargs", - [None, {"alpha": 0.2}, [{"alpha": 0.2}, {"alpha": 0.3}, {"alpha": 0.4}]], -) -def test_roc_curve_display_from_cv_results_curve_kwargs( - pyplot, data_binary, curve_kwargs -): - """Check `curve_kwargs` correctly passed.""" - X, y = data_binary - n_cv = 3 - cv_results = cross_validate( - LogisticRegression(), X, y, cv=n_cv, return_estimator=True, return_indices=True - ) - display = RocCurveDisplay.from_cv_results( - cv_results, - X, - y, - curve_kwargs=curve_kwargs, - ) - if curve_kwargs is None: - # Default `alpha` used - assert all(line.get_alpha() == 0.5 for line in display.line_) - elif isinstance(curve_kwargs, Mapping): - # `alpha` from dict used for all curves - assert all(line.get_alpha() == 0.2 for line in display.line_) - else: - # Different `alpha` used for each curve - assert all( - line.get_alpha() == curve_kwargs[i]["alpha"] - for i, line in enumerate(display.line_) - ) - # Other default kwargs should be the same - for line in display.line_: - assert line.get_linestyle() == "--" - assert line.get_color() == "blue" - - # TODO(1.9): Remove in 1.9 @pytest.mark.parametrize( "constructor_name", ["from_estimator", "from_predictions", "plot"] @@ -462,112 +333,6 @@ def test_roc_curve_display_plotting_from_cv_results( assert line.get_label() == aggregate_expected_labels[idx] -@pytest.mark.parametrize("roc_auc", [[1.0, 1.0, 1.0], None]) -@pytest.mark.parametrize( - "curve_kwargs", - [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], -) -@pytest.mark.parametrize("name", [None, "single", ["one", "two", "three"]]) -def test_roc_curve_plot_legend_label(pyplot, data_binary, name, curve_kwargs, roc_auc): - """Check legend label correct with all `curve_kwargs`, `name` combinations.""" - fpr = [np.array([0, 0.5, 1]), np.array([0, 0.5, 1]), np.array([0, 0.5, 1])] - tpr = [np.array([0, 0.5, 1]), np.array([0, 0.5, 1]), np.array([0, 0.5, 1])] - if not isinstance(curve_kwargs, list) and isinstance(name, list): - with pytest.raises(ValueError, match="To avoid labeling individual curves"): - RocCurveDisplay(fpr=fpr, tpr=tpr, roc_auc=roc_auc).plot( - name=name, curve_kwargs=curve_kwargs - ) - - else: - display = RocCurveDisplay(fpr=fpr, tpr=tpr, roc_auc=roc_auc).plot( - name=name, curve_kwargs=curve_kwargs - ) - legend = display.ax_.get_legend() - if legend is None: - # No legend is created, exit test early - assert name is None - assert roc_auc is None - return - else: - legend_labels = [text.get_text() for text in legend.get_texts()] - - if isinstance(curve_kwargs, list): - # Multiple labels in legend - assert len(legend_labels) == 3 - for idx, label in enumerate(legend_labels): - if name is None: - expected_label = "AUC = 1.00" if roc_auc else None - assert label == expected_label - elif isinstance(name, str): - expected_label = "single (AUC = 1.00)" if roc_auc else "single" - assert label == expected_label - else: - # `name` is a list of different strings - expected_label = ( - f"{name[idx]} (AUC = 1.00)" if roc_auc else f"{name[idx]}" - ) - assert label == expected_label - else: - # Single label in legend - assert len(legend_labels) == 1 - if name is None: - expected_label = "AUC = 1.00 +/- 0.00" if roc_auc else None - assert legend_labels[0] == expected_label - else: - # name is single string - expected_label = "single (AUC = 1.00 +/- 0.00)" if roc_auc else "single" - assert legend_labels[0] == expected_label - - -@pytest.mark.parametrize( - "curve_kwargs", - [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], -) -@pytest.mark.parametrize("name", [None, "single", ["one", "two", "three"]]) -def test_roc_curve_from_cv_results_legend_label( - pyplot, data_binary, name, curve_kwargs -): - """Check legend label correct with all `curve_kwargs`, `name` combinations.""" - X, y = data_binary - n_cv = 3 - cv_results = cross_validate( - LogisticRegression(), X, y, cv=n_cv, return_estimator=True, return_indices=True - ) - - if not isinstance(curve_kwargs, list) and isinstance(name, list): - with pytest.raises(ValueError, match="To avoid labeling individual curves"): - RocCurveDisplay.from_cv_results( - cv_results, X, y, name=name, curve_kwargs=curve_kwargs - ) - else: - display = RocCurveDisplay.from_cv_results( - cv_results, X, y, name=name, curve_kwargs=curve_kwargs - ) - - legend = display.ax_.get_legend() - legend_labels = [text.get_text() for text in legend.get_texts()] - if isinstance(curve_kwargs, list): - # Multiple labels in legend - assert len(legend_labels) == 3 - auc = ["0.62", "0.66", "0.55"] - for idx, label in enumerate(legend_labels): - if name is None: - assert label == f"AUC = {auc[idx]}" - elif isinstance(name, str): - assert label == f"single (AUC = {auc[idx]})" - else: - # `name` is a list of different strings - assert label == f"{name[idx]} (AUC = {auc[idx]})" - else: - # Single label in legend - assert len(legend_labels) == 1 - if name is None: - assert legend_labels[0] == "AUC = 0.61 +/- 0.05" - else: - # name is single string - assert legend_labels[0] == "single (AUC = 0.61 +/- 0.05)" - - @pytest.mark.parametrize( "curve_kwargs", [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], @@ -595,18 +360,6 @@ def test_roc_curve_from_cv_results_curve_kwargs(pyplot, data_binary, curve_kwarg assert color == curve_kwargs[idx]["c"] -def test_roc_curve_from_cv_results_pos_label_inferred(pyplot, data_binary): - """Check `pos_label` inferred correctly by `from_cv_results(pos_label=None)`.""" - X, y = data_binary - cv_results = cross_validate( - LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True - ) - - disp = RocCurveDisplay.from_cv_results(cv_results, X, y, pos_label=None) - # Should be `estimator.classes_[1]` - assert disp.pos_label == 1 - - def _check_chance_level(plot_chance_level, chance_level_kw, display): """Check chance level line and line styles correct.""" import matplotlib as mpl From 33187195c2cc862ad775244af9cec28ccdf32bad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= Date: Wed, 11 Feb 2026 12:18:28 +0100 Subject: [PATCH 201/462] DOC Rephrase the param description of "name" in RocCurveDisplay (#33224) Co-authored-by: Olivier Grisel Co-authored-by: Lucy Liu --- sklearn/metrics/_plot/roc_curve.py | 61 ++++++++++++++++++------------ 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/sklearn/metrics/_plot/roc_curve.py b/sklearn/metrics/_plot/roc_curve.py index 0ea96733dcf4f..3582e61990f75 100644 --- a/sklearn/metrics/_plot/roc_curve.py +++ b/sklearn/metrics/_plot/roc_curve.py @@ -60,15 +60,20 @@ class RocCurveDisplay(_BinaryClassifierCurveDisplayMixin): name : str or list of str, default=None Name for labeling legend entries. The number of legend entries is determined by the `curve_kwargs` passed to `plot`, and is not affected by `name`. - To label each curve, provide a list of strings. To avoid labeling - individual curves that have the same appearance, a list cannot be used in - conjunction with `curve_kwargs` being a dictionary or None. If a - string is provided, it will be used to either label the single legend entry - or if there are multiple legend entries, label each individual curve with - the same name. If `None`, no name is shown in the legend. + + If a string is provided, it will be used to either label the single legend + entry or if there are multiple legend entries, label each individual curve + with the same name. + + If a list is provided, it will be used to label each curve individually. + Passing a list will raise an error if `curve_kwargs` is not a list to avoid + labeling individual curves that have the same appearance. + + If `None`, no name is shown in the legend. .. versionchanged:: 1.7 - `estimator_name` was deprecated in favor of `name`. + `estimator_name` was deprecated in favor of `name` and now accepts + a list for plotting multiple curves. pos_label : int, float, bool or str, default=None The class considered the positive class when ROC AUC metrics computed. @@ -184,15 +189,19 @@ def plot( created. name : str or list of str, default=None - Name for labeling legend entries. The number of legend entries - is determined by `curve_kwargs`, and is not affected by `name`. - To label each curve, provide a list of strings. To avoid labeling - individual curves that have the same appearance, a list cannot be used in - conjunction with `curve_kwargs` being a dictionary or None. If a - string is provided, it will be used to either label the single legend entry - or if there are multiple legend entries, label each individual curve with - the same name. If `None`, set to `name` provided at `RocCurveDisplay` - initialization. If still `None`, no name is shown in the legend. + Name for labeling legend entries. The number of legend entries is determined + by the `curve_kwargs` passed to `plot`, and is not affected by `name`. + + If a string is provided, it will be used to either label the single legend + entry or if there are multiple legend entries, label each individual curve + with the same name. + + If a list is provided, it will be used to label each curve individually. + Passing a list will raise an error if `curve_kwargs` is not a list to avoid + labeling individual curves that have the same appearance. + + If `None`, set to `name` provided at `RocCurveDisplay` initialization. If + still `None`, no name is shown in the legend. .. versionadded:: 1.7 @@ -678,14 +687,18 @@ def from_cv_results( created. name : str or list of str, default=None - Name for labeling legend entries. The number of legend entries - is determined by `curve_kwargs`, and is not affected by `name`. - To label each curve, provide a list of strings. To avoid labeling - individual curves that have the same appearance, a list cannot be used in - conjunction with `curve_kwargs` being a dictionary or None. If a - string is provided, it will be used to either label the single legend entry - or if there are multiple legend entries, label each individual curve with - the same name. If `None`, no name is shown in the legend. + Name for labeling legend entries. The number of legend entries is determined + by the `curve_kwargs` passed to `plot`, and is not affected by `name`. + + If a string is provided, it will be used to either label the single legend + entry or if there are multiple legend entries, label each individual curve + with the same name. + + If a list is provided, it will be used to label each curve individually. + Passing a list will raise an error if `curve_kwargs` is not a list to avoid + labeling individual curves that have the same appearance. + + If `None`, no name is shown in the legend. curve_kwargs : dict or list of dict, default=None Keywords arguments to be passed to matplotlib's `plot` function From a885b523630f0e2430c214ea30a1b3a74750dcaa Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Wed, 11 Feb 2026 17:35:03 +0100 Subject: [PATCH 202/462] DOC copy note on calibration to Brier score loss (#33254) --- doc/modules/calibration.rst | 6 +++--- doc/modules/model_evaluation.rst | 35 +++++++++++++------------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/doc/modules/calibration.rst b/doc/modules/calibration.rst index 0df94bb7b82e0..e920261d03d3f 100644 --- a/doc/modules/calibration.rst +++ b/doc/modules/calibration.rst @@ -36,8 +36,8 @@ good a classifier is calibrated. decomposition of Murphy [1]_. As it is not clear which term dominates, the score is of limited use for assessing calibration alone (unless one computes each term of the decomposition). A lower Brier loss, for instance, does not necessarily - mean a better calibrated model, it could also mean a worse calibrated model with much - more discriminatory power, e.g. using many more features. + mean a better calibrated model, it could also mean a worse calibrated model with + much more discriminatory power, e.g. using many more features. .. _calibration_curve: @@ -317,7 +317,7 @@ parameters for each single class. .. [1] Allan H. Murphy (1973). :doi:`"A New Vector Partition of the Probability Score" <10.1175/1520-0450(1973)012%3C0595:ANVPOT%3E2.0.CO;2>` - Journal of Applied Meteorology and Climatology + Journal of Applied Meteorology and Climatology, 12(4), 595-600 .. [2] `On the combination of forecast probabilities for consecutive precipitation periods. diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index 06a02b49731d5..bdcf3a85f48dd 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -1982,18 +1982,16 @@ two above definitions to follow. ... ) 0.146 -The Brier score can be used to assess how well a classifier is calibrated. -However, a lower Brier score loss does not always mean a better calibration. -This is because, by analogy with the bias-variance decomposition of the mean -squared error, the Brier score loss can be decomposed as the sum of calibration -loss and refinement loss [Bella2012]_. Calibration loss is defined as the mean -squared deviation from empirical probabilities derived from the slope of ROC -segments. Refinement loss can be defined as the expected optimal loss as -measured by the area under the optimal cost curve. Refinement loss can change -independently from calibration loss, thus a lower Brier score loss does not -necessarily mean a better calibrated model. "Only when refinement loss remains -the same does a lower Brier score loss always mean better calibration" -[Bella2012]_, [Flach2008]_. +.. note:: + As a strictly proper scoring rules for probabilistic predictions, + the Brier score assesses calibration (reliability) and + discriminative power (resolution) of a model, as well as the randomness of the data + (uncertainty) at the same time. This follows from the well-known Brier score + decomposition of Murphy [Murphy1973]_. As it is not clear which term dominates, + the score is of limited use for assessing calibration alone (unless one computes + each term of the decomposition). A lower Brier loss, for instance, does not + necessarily mean a better calibrated model, it could also mean a worse calibrated + model with much more discriminatory power, e.g. using many more features. .. rubric:: Examples @@ -2008,15 +2006,10 @@ the same does a lower Brier score loss always mean better calibration" <10.1175/1520-0493(1950)078%3C0001:VOFEIT%3E2.0.CO;2>`. Monthly Weather Review 78(1), 1-3 -.. [Bella2012] Bella, Ferri, Hernández-Orallo, and Ramírez-Quintana - `"Calibration of Machine Learning Models" - `_ - in Khosrow-Pour, M. "Machine learning: concepts, methodologies, tools - and applications." Hershey, PA: Information Science Reference (2012). - -.. [Flach2008] Flach, Peter, and Edson Matsubara. `"On classification, ranking, - and probability estimation." `_ - Dagstuhl Seminar Proceedings. Schloss Dagstuhl-Leibniz-Zentrum für Informatik (2008). +.. [Murphy1973] Allan H. Murphy (1973). + :doi:`"A New Vector Partition of the Probability Score" + <10.1175/1520-0450(1973)012%3C0595:ANVPOT%3E2.0.CO;2>` + Journal of Applied Meteorology and Climatology, 12(4), 595-600 .. _class_likelihood_ratios: From b6814a50009345addb0932a62b027af95867c826 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Thu, 12 Feb 2026 07:53:28 +0100 Subject: [PATCH 203/462] MNT remove unused function in PowerTransformer (#33264) --- sklearn/preprocessing/_data.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/sklearn/preprocessing/_data.py b/sklearn/preprocessing/_data.py index 15a8948412806..c904da57a5f0d 100644 --- a/sklearn/preprocessing/_data.py +++ b/sklearn/preprocessing/_data.py @@ -3572,25 +3572,6 @@ def _yeo_johnson_optimize(self, x): Like for Box-Cox, MLE is done via the brent optimizer. """ - x_tiny = np.finfo(np.float64).tiny - - def _neg_log_likelihood(lmbda): - """Return the negative log likelihood of the observed data x as a - function of lambda.""" - x_trans = self._yeo_johnson_transform(x, lmbda) - n_samples = x.shape[0] - x_trans_var = x_trans.var() - - # Reject transformed data that would raise a RuntimeWarning in np.log - if x_trans_var < x_tiny: - return np.inf - - log_var = np.log(x_trans_var) - loglike = -n_samples / 2 * log_var - loglike += (lmbda - 1) * (np.sign(x) * np.log1p(np.abs(x))).sum() - - return -loglike - # the computation of lambda is influenced by NaNs so we need to # get rid of them x = x[~np.isnan(x)] From 79932ba89321745252cbdfc490b46494c31c7eb6 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Thu, 12 Feb 2026 08:00:49 +0100 Subject: [PATCH 204/462] Add array API support for `FeatureUnion` (#33263) --- doc/modules/array_api.rst | 1 + .../array-api/33263.feature.rst | 2 + sklearn/pipeline.py | 16 +++- sklearn/tests/test_pipeline.py | 86 +++++++++++++++++++ 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/33263.feature.rst diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index 4e51fd51e1dc5..11fe3356a86aa 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -157,6 +157,7 @@ Meta-estimators that accept Array API inputs conditioned on the fact that the base estimator also does: - :class:`calibration.CalibratedClassifierCV` (with `method="temperature"`) +- :class:`pipeline.FeatureUnion` - :class:`model_selection.GridSearchCV` - :class:`model_selection.RandomizedSearchCV` - :class:`model_selection.HalvingGridSearchCV` diff --git a/doc/whats_new/upcoming_changes/array-api/33263.feature.rst b/doc/whats_new/upcoming_changes/array-api/33263.feature.rst new file mode 100644 index 0000000000000..fcded68c3762b --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/33263.feature.rst @@ -0,0 +1,2 @@ +- :class:`pipeline.FeatureUnion` now supports Array API compliant inputs when all + its transformers do. By :user:`Olivier Grisel `. diff --git a/sklearn/pipeline.py b/sklearn/pipeline.py index 3896beb6b70d8..f3f6bc7883c8e 100644 --- a/sklearn/pipeline.py +++ b/sklearn/pipeline.py @@ -14,6 +14,7 @@ from sklearn.exceptions import NotFittedError from sklearn.preprocessing import FunctionTransformer from sklearn.utils import Bunch +from sklearn.utils._array_api import get_namespace, get_namespace_and_device from sklearn.utils._metadata_requests import METHODS from sklearn.utils._param_validation import HasMethods, Hidden from sklearn.utils._repr_html.estimator import _VisualBlock @@ -1909,7 +1910,8 @@ def fit_transform(self, X, y=None, **params): results = self._parallel_func(X, y, _fit_transform_one, routed_params) if not results: # All transformers are None - return np.zeros((X.shape[0], 0)) + xp, _, device = get_namespace_and_device(X) + return xp.zeros((X.shape[0], 0), device=device) Xs, transformers = zip(*results) self._update_transformer_list(transformers) @@ -1979,11 +1981,13 @@ def transform(self, X, **params): ) if not Xs: # All transformers are None - return np.zeros((X.shape[0], 0)) + xp, _, device = get_namespace_and_device(X) + return xp.zeros((X.shape[0], 0), device=device) return self._hstack(Xs) def _hstack(self, Xs): + xp, _ = get_namespace(*Xs) # Check if Xs dimensions are valid for X, (name, _) in zip(Xs, self.transformer_list): if hasattr(X, "shape") and len(X.shape) != 2: @@ -2000,7 +2004,7 @@ def _hstack(self, Xs): if any(sparse.issparse(f) for f in Xs): return sparse.hstack(Xs).tocsr() - return np.hstack(Xs) + return xp.concat(Xs, axis=1) def _update_transformer_list(self, transformers): transformers = iter(transformers) @@ -2075,6 +2079,12 @@ def __sklearn_tags__(self): for name, trans in self.transformer_list if trans not in {"passthrough", "drop"} ) + tags.array_api_support = all( + True + if trans in {"passthrough", "drop"} + else get_tags(trans).array_api_support + for name, trans in self.transformer_list + ) except Exception: # If `transformer_list` does not comply with our API (list of tuples) # then it will fail. In this case, we assume that `sparse` is False diff --git a/sklearn/tests/test_pipeline.py b/sklearn/tests/test_pipeline.py index 6abc64b6658d5..26cb4a49f1c0b 100644 --- a/sklearn/tests/test_pipeline.py +++ b/sklearn/tests/test_pipeline.py @@ -34,6 +34,7 @@ from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_selection import SelectKBest, f_classif from sklearn.impute import SimpleImputer +from sklearn.kernel_approximation import Nystroem from sklearn.linear_model import Lasso, LinearRegression, LogisticRegression from sklearn.metrics import accuracy_score, r2_score from sklearn.model_selection import train_test_split @@ -48,11 +49,18 @@ check_recorded_metadata, ) from sklearn.utils import get_tags +from sklearn.utils._array_api import ( + _atol_for_type, + _convert_to_numpy, + get_namespace_and_device, + yield_namespace_device_dtype_combinations, +) from sklearn.utils._metadata_requests import COMPOSITE_METHODS, METHODS from sklearn.utils._testing import ( MinimalClassifier, MinimalRegressor, MinimalTransformer, + _array_api_for_tests, assert_allclose, assert_array_almost_equal, assert_array_equal, @@ -1945,6 +1953,84 @@ def test_feature_union_1d_output(): ).fit_transform(X) +@pytest.mark.parametrize( + "array_namespace, device, dtype_name", + yield_namespace_device_dtype_combinations(), +) +def test_feature_union_array_api_compliance(array_namespace, device, dtype_name): + """Test that FeatureUnion with Array API-compatible transformers works.""" + xp = _array_api_for_tests(array_namespace, device) + rnd = np.random.RandomState(0) + n_samples, n_features = 20, 10 + X_np = rnd.uniform(size=(n_samples, n_features)).astype(dtype_name) + X_xp = xp.asarray(X_np, device=device) + + n_components_1, n_components_2 = 5, 8 + union = FeatureUnion( + [ + ("nystroem1", Nystroem(n_components=n_components_1, random_state=0)), + ("nystroem2", Nystroem(n_components=n_components_2, random_state=1)), + ] + ) + + X_np_transformed = union.fit_transform(X_np) + + with config_context(array_api_dispatch=True): + X_xp_transformed = union.fit_transform(X_xp) + X_xp_transformed_np = _convert_to_numpy(X_xp_transformed, xp=xp) + + for name, trans in union.transformer_list: + for attr in ["components_", "normalization_"]: + if hasattr(trans, attr): + trans_xp, _, trans_device = get_namespace_and_device( + getattr(trans, attr) + ) + assert trans_xp is xp + assert trans_device == get_namespace_and_device(X_xp)[2] + + atol = _atol_for_type(dtype_name) + assert_allclose(X_np_transformed, X_xp_transformed_np, atol=atol) + assert X_xp_transformed_np.shape == ( + n_samples, + n_components_1 + n_components_2, + ) + + +def test_feature_union_array_api_support_tag(): + """Check that FeatureUnion.array_api_support tag reflects its transformers.""" + # All transformers support Array API -> union supports it + union = FeatureUnion( + [ + ("scaler", StandardScaler()), + ("nystroem", Nystroem(n_components=5, random_state=0)), + ] + ) + assert get_tags(union).array_api_support is True + + # One transformer does not support Array API -> union does not + union = FeatureUnion( + [ + ("scaler", StandardScaler()), + ("svd", TruncatedSVD(n_components=2)), + ] + ) + assert get_tags(union).array_api_support is False + + # passthrough/drop are treated as supporting Array API + union = FeatureUnion( + [ + ("scaler", StandardScaler()), + ("pass", "passthrough"), + ("dropped", "drop"), + ] + ) + assert get_tags(union).array_api_support is True + + # Only drop and passthrough -> True + union = make_union("drop", "passthrough") + assert get_tags(union).array_api_support is True + + # transform_input tests # ===================== From 9ca766bafa756ad714d14a98f270cd3723e6dc22 Mon Sep 17 00:00:00 2001 From: Omar Salman Date: Thu, 12 Feb 2026 14:41:58 +0500 Subject: [PATCH 205/462] FEA Add array API support for LogisticRegression with LBFGS (#32644) Co-authored-by: Olivier Grisel Co-authored-by: Christian Lorentzen --- doc/modules/array_api.rst | 1 + .../array-api/32644.feature.rst | 3 + .../sklearn.linear_model/32644.efficiency.rst | 7 + sklearn/_loss/__init__.py | 4 + sklearn/_loss/loss.py | 385 +++++++++++++++++- sklearn/_loss/tests/test_loss.py | 143 ++++++- sklearn/calibration.py | 25 +- sklearn/discriminant_analysis.py | 2 +- sklearn/linear_model/_base.py | 22 +- sklearn/linear_model/_glm/glm.py | 10 +- sklearn/linear_model/_linear_loss.py | 41 +- sklearn/linear_model/_logistic.py | 107 +++-- sklearn/linear_model/tests/test_logistic.py | 151 ++++++- .../_search_successive_halving.py | 7 + sklearn/utils/_array_api.py | 29 +- sklearn/utils/class_weight.py | 35 +- sklearn/utils/tests/test_array_api.py | 12 + 17 files changed, 893 insertions(+), 91 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/32644.feature.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/32644.efficiency.rst diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index 11fe3356a86aa..5f5ef5c73326e 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -132,6 +132,7 @@ Estimators - :class:`decomposition.PCA` (with `svd_solver="full"`, `svd_solver="covariance_eigh"`, or `svd_solver="randomized"` (`svd_solver="randomized"` only if `power_iteration_normalizer="QR"`)) - :class:`kernel_approximation.Nystroem` +- :class:`linear_model.LogisticRegression` (with `solver="lbfgs"`) - :class:`linear_model.Ridge` (with `solver="svd"`) - :class:`linear_model.RidgeCV` (with `solver="svd"`, see :ref:`device_support_for_float64`) - :class:`linear_model.RidgeClassifier` (with `solver="svd"`) diff --git a/doc/whats_new/upcoming_changes/array-api/32644.feature.rst b/doc/whats_new/upcoming_changes/array-api/32644.feature.rst new file mode 100644 index 0000000000000..1b125b81dbd29 --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/32644.feature.rst @@ -0,0 +1,3 @@ +- :class:`linear_model.LogisticRegression` now supports array API compatible inputs + with `solver="lbfgs"`. + By :user:`Omar Salman ` and :user:`Olivier Grisel `. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32644.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32644.efficiency.rst new file mode 100644 index 0000000000000..74220bbd7faa2 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/32644.efficiency.rst @@ -0,0 +1,7 @@ +- :class:`linear_model.LogisticRegression` with `solver="lbfgs"` now estimates + the gradient of the loss at `float32` precision when fitted with `float32` + data (`X`) to improve training speed and memory efficiency. Previously, the input + data would be implicitly cast to `float64`. If you relied on the previous + behavior for numerical reasons, you can explicitly cast your data to + `float64` before fitting to reproduce it. + By :user:`Omar Salman ` and :user:`Olivier Grisel `. diff --git a/sklearn/_loss/__init__.py b/sklearn/_loss/__init__.py index e0269a93a49ca..a55958a4d1ced 100644 --- a/sklearn/_loss/__init__.py +++ b/sklearn/_loss/__init__.py @@ -9,8 +9,10 @@ from sklearn._loss.loss import ( AbsoluteError, HalfBinomialLoss, + HalfBinomialLossArrayAPI, HalfGammaLoss, HalfMultinomialLoss, + HalfMultinomialLossArrayAPI, HalfPoissonLoss, HalfSquaredError, HalfTweedieLoss, @@ -22,8 +24,10 @@ __all__ = [ "AbsoluteError", "HalfBinomialLoss", + "HalfBinomialLossArrayAPI", "HalfGammaLoss", "HalfMultinomialLoss", + "HalfMultinomialLossArrayAPI", "HalfPoissonLoss", "HalfSquaredError", "HalfTweedieLoss", diff --git a/sklearn/_loss/loss.py b/sklearn/_loss/loss.py index 9cbaa5284d3a2..3e46fc7602de5 100644 --- a/sklearn/_loss/loss.py +++ b/sklearn/_loss/loss.py @@ -46,6 +46,14 @@ MultinomialLogit, ) from sklearn.utils import check_scalar +from sklearn.utils._array_api import ( + _average, + _logsumexp, + _ravel, + get_namespace, + get_namespace_and_device, +) +from sklearn.utils.extmath import softmax from sklearn.utils.stats import _weighted_percentile @@ -380,7 +388,9 @@ def gradient_hessian( ) return gradient_out, hessian_out - def __call__(self, y_true, raw_prediction, sample_weight=None, n_threads=1): + def __call__( + self, y_true, raw_prediction, sample_weight=None, n_threads=1, xp=None + ): """Compute the weighted average loss. Parameters @@ -394,6 +404,8 @@ def __call__(self, y_true, raw_prediction, sample_weight=None, n_threads=1): Sample weights. n_threads : int, default=1 Might use openmp thread parallelism. + xp : module, default=None + Array namespace module. Ignored by the Cython implementation. Returns ------- @@ -1022,6 +1034,12 @@ def __init__(self, sample_weight=None, n_classes=3): ) self.interval_y_true = Interval(0, np.inf, True, False) self.interval_y_pred = Interval(0, 1, False, False) + # These instance variables are specifically used for the array API + # methods to store certain intermediate values in order to avoid + # having to recompute them repeatedly. + self.class_indexing_offsets = None + self.y_true_int = None + self.y_true_one_hot = None def in_y_true_range(self, y): """Return True if y is in the valid range of y_true. @@ -1214,3 +1232,368 @@ def predict_proba(self, raw_prediction): "multinomial_loss": HalfMultinomialLoss, "exponential_loss": ExponentialLoss, } + + +class ArrayAPILossMixin: + """Mixin for loss classes that are compatible with the array API. + Currently this mixin only redefines the `__call__` method such that it + works according to the array API specification. + """ + + def __call__( + self, + y_true, + raw_prediction, + sample_weight=None, + n_threads=1, + xp=None, + ): + """Compute the weighted average loss for the array API losses. + + Parameters + ---------- + y_true : C-contiguous array of shape (n_samples,) + Observed, true target values. + raw_prediction : C-contiguous array of shape (n_samples,) or array of \ + shape (n_samples, n_classes) + Raw prediction values (in link space). + sample_weight : None or C-contiguous array of shape (n_samples,) + Sample weights. + n_threads : int, default=1 + Ignored by the array API implementation. + xp : module, default=None + Array namespace module. + + Returns + ------- + loss : float + Mean or averaged loss function. + """ + xp, _ = get_namespace(y_true, raw_prediction, sample_weight, xp=xp) + loss_xp = self.loss( + y_true=y_true, raw_prediction=raw_prediction, sample_weight=None + ) + return float(_average(loss_xp, weights=sample_weight, xp=xp)) + + +def _log1pexp(raw_prediction, raw_prediction_exp, xp): + """Numerically stable version of log(1 + exp(x)) that is compatible with + the array API. + + Parameters + ---------- + raw_prediction : C-contiguous array of shape (n_samples,) or array of \ + shape (n_samples, n_classes) + Raw prediction values (in link space). + raw_prediction_exp : C-contiguous array of shape (n_samples,) or array of \ + shape (n_samples, n_classes) + Exponential of the raw prediction values. + xp : module, default=None + Array namespace module. + + Returns + ------- + log1pexp : float + Numerically stable value for log(1 + exp(raw_prediction)). + """ + + # The "magic constants" used here are different for float64 and float32 + # dtypes. For float64, we simply use the values that are present in the + # Cython loss module and the details can be found there. For float32, + # we use the `scipy.optimize.brentq` with `xtol=1e-7`to deduce the valid + # cutoff for each of the different cases that are handled. The trick is + # to define for each special case a function that subtracts + # `np.log1p(np.exp(x, dtype=np.float32))` from the special case under + # consideration. Additionally the resulting values that are very close to + # zero are set to -1. + # Consider as an example the case `x + exp(-x)`: + # + # def x_plus_exp_negx(x): + # x = np.float32(x) + # val = ( + # x + np.exp(-x, dtype=np.float32)) + # - np.log1p(np.exp(x, dtype=np.float32) + # ) + # if np.isclose(val, 0, atol=1e-16): + # val = -1 + # return val + # + # + # x_cutoff = brentq(x_plus_exp_negx, 1, 20, xtol=1e-7) + # + # The bounds used in the `brentq` function for each case respectively are + # acquired through the referenced paper: + # https://cran.r-project.org/web/packages/Rmpfr/vignettes/log1mexp-note.pdf + # Compared to the reference, we have the additional case distinction x <= -2 + # in the float64 case. Since we don't have the reference bounds for this, + # we estimate the value as approximately x <= -1 for float32. + constants = ( + [-37, -2, 18, 33.3] + if raw_prediction.dtype == xp.float64 + else [-17, -1, 9, 14.6] + ) + return xp.where( + raw_prediction <= constants[0], + raw_prediction_exp, + xp.where( + raw_prediction <= constants[1], + xp.log1p(raw_prediction_exp), + xp.where( + raw_prediction <= constants[2], + xp.log(1.0 + raw_prediction_exp), + xp.where( + raw_prediction <= constants[3], + raw_prediction + 1 / raw_prediction_exp, + raw_prediction, + ), + ), + ), + ) + + +class HalfBinomialLossArrayAPI(ArrayAPILossMixin, HalfBinomialLoss): + """A version of the the HalfBinomialLoss that is compatible with + the array API. + """ + + def loss( + self, + y_true, + raw_prediction, + sample_weight=None, + loss_out=None, + n_threads=1, + ): + xp, _ = get_namespace(y_true, raw_prediction, sample_weight) + return self._compute_loss( + xp=xp, + y_true=y_true, + raw_prediction=raw_prediction, + raw_prediction_exp=xp.exp(raw_prediction), + sample_weight=sample_weight, + ) + + def gradient( + self, + y_true, + raw_prediction, + sample_weight=None, + gradient_out=None, + n_threads=1, + ): + xp, _ = get_namespace(y_true, raw_prediction, sample_weight) + return self._compute_gradient( + xp=xp, + y_true=y_true, + raw_prediction=raw_prediction, + raw_prediction_exp=xp.exp(raw_prediction), + sample_weight=sample_weight, + ) + + def loss_gradient( + self, + y_true, + raw_prediction, + sample_weight=None, + loss_out=None, + gradient_out=None, + n_threads=1, + ): + xp, _ = get_namespace(y_true, raw_prediction, sample_weight) + raw_prediction_exp = xp.exp(raw_prediction) + loss = self._compute_loss( + xp=xp, + y_true=y_true, + raw_prediction=raw_prediction, + raw_prediction_exp=raw_prediction_exp, + sample_weight=sample_weight, + ) + gradient = self._compute_gradient( + xp=xp, + y_true=y_true, + raw_prediction=raw_prediction, + raw_prediction_exp=raw_prediction_exp, + sample_weight=sample_weight, + ) + return loss, gradient + + def _compute_loss( + self, + xp, + y_true, + raw_prediction, + raw_prediction_exp, + sample_weight=None, + ): + log1pexp = _log1pexp( + raw_prediction=raw_prediction, + raw_prediction_exp=raw_prediction_exp, + xp=xp, + ) + loss = log1pexp - y_true * raw_prediction + if sample_weight is not None: + loss *= sample_weight + return loss + + def _compute_gradient( + self, + xp, + y_true, + raw_prediction, + raw_prediction_exp, + sample_weight=None, + ): + neg_raw_prediction_exp = 1 / raw_prediction_exp + grad = xp.where( + raw_prediction > (-37 if raw_prediction.dtype == xp.float64 else -17), + ((1 - y_true) - y_true * neg_raw_prediction_exp) + / (1 + neg_raw_prediction_exp), + raw_prediction_exp - y_true, + ) + if sample_weight is not None: + grad *= sample_weight + return grad + + +class HalfMultinomialLossArrayAPI(ArrayAPILossMixin, HalfMultinomialLoss): + """A version of the the HalfMultinomialLoss that is compatible with + the array API. + + Parameters + ---------- + sample_weight : {None, ndarray} + If sample_weight is None, the hessian might be constant. + + n_classes : {None, int} + The number of classes for classification, else None. + """ + + def __init__(self, sample_weight=None, n_classes=3): + super().__init__(n_classes=n_classes) + # These instance variables are specifically to store certain + # intermediate values in order to avoid having to recompute + # them repeatedly. + + # Used when computing the multinomial loss. + self.class_indexing_offsets = None + self.y_true_int = None + + # Used when computing the gradient. + self.y_true_one_hot = None + + def loss( + self, + y_true, + raw_prediction, + sample_weight=None, + loss_out=None, + n_threads=1, + ): + xp, _, device_ = get_namespace_and_device(y_true, raw_prediction, sample_weight) + return self._compute_loss( + xp=xp, + device_=device_, + y_true=y_true, + raw_prediction=raw_prediction, + sample_weight=sample_weight, + ) + + def gradient( + self, + y_true, + raw_prediction, + sample_weight=None, + gradient_out=None, + n_threads=1, + ): + xp, _, device_ = get_namespace_and_device(y_true, raw_prediction, sample_weight) + return self._compute_gradient( + xp=xp, + device_=device_, + y_true=y_true, + raw_prediction=raw_prediction, + sample_weight=sample_weight, + ) + + def loss_gradient( + self, + y_true, + raw_prediction, + sample_weight=None, + loss_out=None, + gradient_out=None, + n_threads=1, + ): + xp, _, device_ = get_namespace_and_device(y_true, raw_prediction, sample_weight) + loss = self._compute_loss( + xp=xp, + device_=device_, + y_true=y_true, + raw_prediction=raw_prediction, + sample_weight=sample_weight, + ) + gradient = self._compute_gradient( + xp=xp, + device_=device_, + y_true=y_true, + raw_prediction=raw_prediction, + sample_weight=sample_weight, + ) + return loss, gradient + + def _compute_loss( + self, + xp, + device_, + y_true, + raw_prediction, + sample_weight=None, + ): + log_sum_exp = _logsumexp(raw_prediction, axis=1, xp=xp) + if self.y_true_int is None: + self.y_true_int = xp.asarray(y_true, dtype=xp.int64, device=device_) + + if self.class_indexing_offsets is None: + self.class_indexing_offsets = ( + xp.arange(y_true.shape[0], device=device_) * self.n_classes + ) + true_label_probs = xp.take( + _ravel(raw_prediction), self.y_true_int + self.class_indexing_offsets + ) + loss = log_sum_exp - true_label_probs + if sample_weight is not None: + loss *= sample_weight + return loss + + def _compute_gradient( + self, + xp, + device_, + y_true, + raw_prediction, + sample_weight=None, + ): + if self.y_true_one_hot is None: + if self.y_true_int is None: + self.y_true_int = xp.asarray(y_true, dtype=xp.int64, device=device_) + + self.y_true_one_hot = self.y_true_int[:, None] == xp.arange( + self.n_classes, device=device_ + ) + self.y_true_one_hot = xp.astype( + self.y_true_one_hot, raw_prediction.dtype, copy=False + ) + grad = softmax(raw_prediction) + # TODO: once incremental assignment for multiple integer array + # indices is part of a released version of the array API + # spec and array-api-strict has been updated accordingly, + # we can further avoid allocating a big (n_samples, n_classes) + # array for the one-hot encoded y_true and instead use one of the + # following (the latter should allow for JAX support): + # grad[xp.arange(y_true.shape[0]), y_true_int] -= 1 + # xpx.at(grad)[xp.arange(y_true.shape[0]), y_true_int].add(-1) + # See: https://github.com/data-apis/array-api/issues/864 + grad -= self.y_true_one_hot + if sample_weight is not None: + grad *= sample_weight[:, None] + return grad diff --git a/sklearn/_loss/tests/test_loss.py b/sklearn/_loss/tests/test_loss.py index 4fea325729023..673b6b366074c 100644 --- a/sklearn/_loss/tests/test_loss.py +++ b/sklearn/_loss/tests/test_loss.py @@ -12,23 +12,38 @@ ) from scipy.special import logsumexp +from sklearn import config_context from sklearn._loss.link import IdentityLink, _inclusive_low_high from sklearn._loss.loss import ( _LOSSES, AbsoluteError, BaseLoss, HalfBinomialLoss, + HalfBinomialLossArrayAPI, HalfGammaLoss, HalfMultinomialLoss, + HalfMultinomialLossArrayAPI, HalfPoissonLoss, HalfSquaredError, HalfTweedieLoss, HalfTweedieLossIdentity, HuberLoss, PinballLoss, + _log1pexp, ) from sklearn.utils import assert_all_finite -from sklearn.utils._testing import create_memmap_backed_data, skip_if_32bit +from sklearn.utils._array_api import ( + _atol_for_type, + _convert_to_numpy, + _get_namespace_device_dtype_ids, + device, + yield_namespace_device_dtype_combinations, +) +from sklearn.utils._testing import ( + _array_api_for_tests, + create_memmap_backed_data, + skip_if_32bit, +) ALL_LOSSES = list(_LOSSES.values()) @@ -1356,3 +1371,129 @@ def test_tweedie_log_identity_consistency(p): assert_allclose( hessian_log, y_pred * gradient_identity + y_pred**2 * hessian_identity ) + + +@pytest.mark.parametrize( + "array_api_loss_class, loss_class", + [ + (HalfBinomialLossArrayAPI, HalfBinomialLoss), + (HalfMultinomialLossArrayAPI, HalfMultinomialLoss), + ], + ids=["HalfBinomialLoss", "HalfMultinomialLoss"], +) +@pytest.mark.parametrize( + "method_name", ["__call__", "gradient", "loss", "loss_gradient"] +) +@pytest.mark.parametrize("use_sample_weight", [False, True]) +@pytest.mark.parametrize( + "namespace, device_, dtype_name", + yield_namespace_device_dtype_combinations(), + ids=_get_namespace_device_dtype_ids, +) +def test_loss_array_api( + array_api_loss_class, + loss_class, + method_name, + use_sample_weight, + namespace, + device_, + dtype_name, +): + def _assert_array_api_result(result_xp, result_np, raw_prediction_xp, xp, atol): + assert_allclose(_convert_to_numpy(result_xp, xp=xp), result_np, atol=atol) + assert result_xp.dtype == raw_prediction_xp.dtype + assert device(result_xp) == device(raw_prediction_xp) + + xp = _array_api_for_tests(namespace, device_) + atol = _atol_for_type(dtype_name) + random_seed = 42 + n_samples = 100 + array_api_loss_instance = array_api_loss_class() + loss_instance = loss_class() + y_true, raw_prediction = random_y_true_raw_prediction( + loss=loss_instance, + n_samples=n_samples, + y_bound=(-100, 100), + raw_bound=(-50, 50), + seed=random_seed, + ) + y_true = y_true.astype(dtype_name) + raw_prediction = raw_prediction.astype(dtype_name) + y_true_xp = xp.asarray(y_true, device=device_) + raw_prediction_xp = xp.asarray(raw_prediction, device=device_) + if use_sample_weight: + rng = np.random.RandomState(random_seed) + sample_weight_np = ( + rng.uniform(-1, 5, size=n_samples).clip(0, None).astype(dtype_name) + ) + sample_weight_xp = xp.asarray(sample_weight_np, device=device_) + else: + sample_weight_np = None + sample_weight_xp = None + + method = getattr(loss_instance, method_name) + array_api_method = getattr(array_api_loss_instance, method_name) + result_np = method( + y_true=y_true, raw_prediction=raw_prediction, sample_weight=sample_weight_np + ) + with config_context(array_api_dispatch=True): + result_xp = array_api_method( + y_true=y_true_xp, + raw_prediction=raw_prediction_xp, + sample_weight=sample_weight_xp, + ) + if ( + method_name == "__call__" + ): # The `__call__` method just returns a float scalar + assert np.isclose(result_xp, result_np) + else: + if isinstance(result_xp, tuple): + for res_xp, res_np in zip(result_xp, result_np): + _assert_array_api_result( + result_xp=res_xp, + result_np=res_np, + raw_prediction_xp=raw_prediction_xp, + xp=xp, + atol=atol, + ) + else: + _assert_array_api_result( + result_xp=result_xp, + result_np=result_np, + raw_prediction_xp=raw_prediction_xp, + xp=xp, + atol=atol, + ) + + +@pytest.mark.parametrize( + "namespace, device_, dtype_name", + yield_namespace_device_dtype_combinations(), + ids=_get_namespace_device_dtype_ids, +) +def test_log1pexp(namespace, device_, dtype_name): + mpmath = pytest.importorskip("mpmath") + mpmath.mp.prec = 100 # Significantly more precise reference than float64. + values_to_test = np.linspace(-40, 40, 300) + xp = _array_api_for_tests(namespace, device_) + for value in values_to_test: + if dtype_name == "float32": + x = xp.asarray(value, dtype=xp.float32, device=device_) + else: + x = xp.asarray(value, dtype=xp.float64, device=device_) + + result_xp = float( + _log1pexp( + raw_prediction=x, + raw_prediction_exp=xp.exp(x), + xp=xp, + ) + ) + result_mpmath = float(mpmath.log(1 + mpmath.exp(value))) + assert result_mpmath > 0 + # Check that the relative error is within float32 or float64 precision. + assert result_xp == pytest.approx( + result_mpmath, + rel=1e-5 if dtype_name == "float32" else 1e-12, + abs=0, + ) diff --git a/sklearn/calibration.py b/sklearn/calibration.py index f0497bc221eae..7d3523bf15364 100644 --- a/sklearn/calibration.py +++ b/sklearn/calibration.py @@ -4,7 +4,6 @@ # SPDX-License-Identifier: BSD-3-Clause import warnings -from functools import partial from inspect import signature from math import log from numbers import Integral, Real @@ -13,7 +12,11 @@ from scipy.optimize import minimize, minimize_scalar from scipy.special import expit -from sklearn._loss import HalfBinomialLoss, HalfMultinomialLoss +from sklearn._loss import ( + HalfBinomialLoss, + HalfMultinomialLoss, + HalfMultinomialLossArrayAPI, +) from sklearn.base import ( BaseEstimator, ClassifierMixin, @@ -31,7 +34,6 @@ from sklearn.utils import Bunch, _safe_indexing, column_or_1d, get_tags, indexable from sklearn.utils._array_api import ( _convert_to_numpy, - _half_multinomial_loss, _is_numpy_namespace, get_namespace, get_namespace_and_device, @@ -1112,10 +1114,12 @@ def fit(self, X, y, sample_weight=None): if sample_weight is not None: sample_weight = _check_sample_weight(sample_weight, labels, dtype=dtype_) - if _is_numpy_namespace(xp): - multinomial_loss = HalfMultinomialLoss(n_classes=logits.shape[1]) - else: - multinomial_loss = partial(_half_multinomial_loss, xp=xp) + is_numpy_namespace = _is_numpy_namespace(xp) + multinomial_loss = ( + HalfMultinomialLoss(n_classes=logits.shape[1]) + if is_numpy_namespace + else HalfMultinomialLossArrayAPI(n_classes=logits.shape[1]) + ) def log_loss(log_beta=0.0): """Compute the log loss as a parameter of the inverse temperature @@ -1147,7 +1151,12 @@ def log_loss(log_beta=0.0): # This can cause dtype mismatch errors downstream (e.g., buffer dtype). log_beta = xp.asarray(log_beta, dtype=dtype_, device=xp_device) raw_prediction = xp.exp(log_beta) * logits - return multinomial_loss(labels, raw_prediction, sample_weight) + return multinomial_loss( + labels, + raw_prediction, + sample_weight, + xp=xp, + ) xatol = 64 * xp.finfo(dtype_).eps log_beta_minimizer = minimize_scalar( diff --git a/sklearn/discriminant_analysis.py b/sklearn/discriminant_analysis.py index e6396462cef5d..02e38d996efba 100644 --- a/sklearn/discriminant_analysis.py +++ b/sklearn/discriminant_analysis.py @@ -775,7 +775,7 @@ def predict_proba(self, X): xp, _ = get_namespace(X) decision = self.decision_function(X) if size(self.classes_) == 2: - proba = _expit(decision, xp) + proba = _expit(decision, xp=xp) return xp.stack([1 - proba, proba], axis=1) else: return softmax(decision) diff --git a/sklearn/linear_model/_base.py b/sklearn/linear_model/_base.py index 04704c713c99b..67e9e01b12db0 100644 --- a/sklearn/linear_model/_base.py +++ b/sklearn/linear_model/_base.py @@ -13,7 +13,6 @@ import scipy.sparse as sp from scipy import linalg, optimize, sparse from scipy.sparse.linalg import lsqr -from scipy.special import expit from sklearn.base import ( BaseEstimator, @@ -26,6 +25,9 @@ from sklearn.utils._array_api import ( _asarray_with_order, _average, + _convert_to_numpy, + _expit, + _is_numpy_namespace, get_namespace, get_namespace_and_device, indexing_dtype, @@ -390,7 +392,14 @@ def predict(self, X): else: indices = xp.argmax(scores, axis=1) - return xp.take(self.classes_, indices, axis=0) + # If `y` consists of strings during fitting then `self.classes_` will + # also contain strings and we handle such a scenario by returning the + # predictions according to the namespace of `self.classes_` i.e. numpy. + xp_classes, _ = get_namespace(self.classes_) + if _is_numpy_namespace(xp_classes): + indices = _convert_to_numpy(indices, xp=xp) + + return xp_classes.take(self.classes_, indices, axis=0) def _predict_proba_lr(self, X): """Probability estimation for OvR logistic regression. @@ -399,20 +408,21 @@ def _predict_proba_lr(self, X): 1. / (1. + np.exp(-self.decision_function(X))); multiclass is handled by normalizing that over all classes. """ + xp, _ = get_namespace(X) prob = self.decision_function(X) - expit(prob, out=prob) + prob = _expit(prob, out=prob, xp=xp) if prob.ndim == 1: - return np.vstack([1 - prob, prob]).T + return xp.stack([1 - prob, prob], axis=1) else: # OvR normalization, like LibLinear's predict_probability prob_sum = prob.sum(axis=1) all_zero = prob_sum == 0 - if np.any(all_zero): + if xp.any(all_zero): # The above might assign zero to all classes, which doesn't # normalize neatly; work around this to produce uniform probabilities. prob[all_zero, :] = 1 prob_sum[all_zero] = prob.shape[1] # n_classes - prob /= prob_sum.reshape((prob.shape[0], -1)) + prob /= xp.reshape(prob_sum, (prob.shape[0], -1)) return prob diff --git a/sklearn/linear_model/_glm/glm.py b/sklearn/linear_model/_glm/glm.py index 8bad8e8193385..c6225b4527620 100644 --- a/sklearn/linear_model/_glm/glm.py +++ b/sklearn/linear_model/_glm/glm.py @@ -201,15 +201,7 @@ def fit(self, X, y, sample_weight=None): y_numeric=True, multi_output=False, ) - - # required by losses - if self.solver == "lbfgs": - # lbfgs will force coef and therefore raw_prediction to be float64. The - # base_loss needs y, X @ coef and sample_weight all of same dtype - # (and contiguous). - loss_dtype = np.float64 - else: - loss_dtype = min(max(y.dtype, X.dtype), np.float64) + loss_dtype = X.dtype y = check_array(y, dtype=loss_dtype, order="C", ensure_2d=False) if sample_weight is not None: diff --git a/sklearn/linear_model/_linear_loss.py b/sklearn/linear_model/_linear_loss.py index 85ab639700549..6194245505d13 100644 --- a/sklearn/linear_model/_linear_loss.py +++ b/sklearn/linear_model/_linear_loss.py @@ -8,6 +8,11 @@ import numpy as np from scipy import sparse +from sklearn.utils._array_api import ( + _convert_to_numpy, + get_namespace, + get_namespace_and_device, +) from sklearn.utils.extmath import safe_sparse_dot, squared_norm @@ -198,12 +203,20 @@ def weight_intercept_raw(self, coef, X): (n_samples, n_classes) """ weights, intercept = self.weight_intercept(coef) - + xp, _, device_ = get_namespace_and_device(X) + + # The `weights` and `intercept` are only converted internally to the + # array API because the relevant `scipy.optimize` functions do not + # currently support the array API and we have to ensure that the final + # values returned to the respective `scipy.optimize` function are in + # the `numpy` namespace. + weights_xp = xp.asarray(weights, dtype=X.dtype, device=device_) + intercept_xp = xp.asarray(intercept, dtype=X.dtype, device=device_) if not self.base_loss.is_multiclass: - raw_prediction = X @ weights + intercept + raw_prediction = X @ weights_xp + intercept_xp else: # weights has shape (n_classes, n_dof) - raw_prediction = X @ weights.T + intercept # ndarray, likely C-contiguous + raw_prediction = X @ weights_xp.T + intercept_xp return weights, intercept, raw_prediction @@ -322,23 +335,33 @@ def loss_gradient( sample_weight=sample_weight, n_threads=n_threads, ) - sw_sum = n_samples if sample_weight is None else np.sum(sample_weight) - loss = loss.sum() / sw_sum + xp, _ = get_namespace(X, y, sample_weight) + sw_sum = n_samples if sample_weight is None else xp.sum(sample_weight) + loss = float(xp.sum(loss) / sw_sum) loss += self.l2_penalty(weights, l2_reg_strength) grad_pointwise /= sw_sum if not self.base_loss.is_multiclass: grad = np.empty_like(coef, dtype=weights.dtype) - grad[:n_features] = X.T @ grad_pointwise + l2_reg_strength * weights + X_grad = X.T @ grad_pointwise + grad[:n_features] = ( + _convert_to_numpy(X_grad, xp=xp) + l2_reg_strength * weights + ) if self.fit_intercept: - grad[-1] = grad_pointwise.sum() + grad[-1] = xp.sum(grad_pointwise) else: + # The final value of `grad` needs to be in the `numpy` namespace + # because the relevant `scipy.optimize` functions do not currently + # support the array API. grad = np.empty((n_classes, n_dof), dtype=weights.dtype, order="F") # grad_pointwise.shape = (n_samples, n_classes) - grad[:, :n_features] = grad_pointwise.T @ X + l2_reg_strength * weights + grad_X = grad_pointwise.T @ X + grad[:, :n_features] = ( + _convert_to_numpy(grad_X, xp) + l2_reg_strength * weights + ) if self.fit_intercept: - grad[:, -1] = grad_pointwise.sum(axis=0) + grad[:, -1] = _convert_to_numpy(xp.sum(grad_pointwise, axis=0), xp=xp) if coef.ndim == 1: grad = grad.ravel(order="F") diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index 0a566961dd497..90875a32dca27 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -12,7 +12,12 @@ import numpy as np from scipy import optimize -from sklearn._loss.loss import HalfBinomialLoss, HalfMultinomialLoss +from sklearn._loss.loss import ( + HalfBinomialLoss, + HalfBinomialLossArrayAPI, + HalfMultinomialLoss, + HalfMultinomialLossArrayAPI, +) from sklearn.base import _fit_context from sklearn.linear_model._base import ( BaseEstimator, @@ -33,6 +38,13 @@ check_random_state, compute_class_weight, ) +from sklearn.utils._array_api import ( + _is_numpy_namespace, + _matching_numpy_dtype, + get_namespace, + get_namespace_and_device, + size, +) from sklearn.utils._param_validation import Hidden, Interval, StrOptions from sklearn.utils.extmath import row_norms, softmax from sklearn.utils.fixes import _get_additional_lbfgs_options_dict @@ -250,23 +262,26 @@ def _logistic_regression_path( Cs = np.logspace(-4, 4, Cs) solver = _check_solver(solver, penalty, dual) + xp, _, device_ = get_namespace_and_device(X) # Preprocessing. if check_input: X = check_array( X, accept_sparse="csr", - dtype=np.float64, + dtype=[xp.float64, xp.float32], accept_large_sparse=solver not in ["liblinear", "sag", "saga"], ) y = check_array(y, ensure_2d=False, dtype=None) check_consistent_length(X, y) if sample_weight is not None or class_weight is not None: - sample_weight = _check_sample_weight(sample_weight, X, dtype=X.dtype, copy=True) + sample_weight = _check_sample_weight( + sample_weight, X, dtype=X.dtype, copy=True, ensure_same_device=True + ) n_samples, n_features = X.shape - n_classes = len(classes) + n_classes = classes.shape[0] if hasattr(classes, "shape") else len(classes) is_binary = n_classes == 2 if solver == "liblinear" and not is_binary: @@ -284,12 +299,17 @@ def _logistic_regression_path( class_weight_ = compute_class_weight( class_weight, classes=classes, y=y, sample_weight=sample_weight ) - sample_weight *= class_weight_[le.transform(y)] + class_weight_ = xp.asarray( + class_weight_[le.transform(y)], dtype=X.dtype, device=device_ + ) + sample_weight *= class_weight_ if is_binary: - w0 = np.zeros(n_features + int(fit_intercept), dtype=X.dtype) - mask = y == classes[1] - y_bin = np.ones(y.shape, dtype=X.dtype) + w0 = np.zeros( + n_features + int(fit_intercept), dtype=_matching_numpy_dtype(X, xp=xp) + ) + mask = xp.asarray(y == classes[1], device=device_) + y_bin = xp.ones(y.shape, dtype=X.dtype, device=device_) if solver == "liblinear": y_bin[~mask] = -1.0 else: @@ -300,10 +320,12 @@ def _logistic_regression_path( # All solvers capable of a multinomial need LabelEncoder, not LabelBinarizer, # i.e. y as a 1d-array of integers. LabelEncoder also saves memory # compared to LabelBinarizer, especially when n_classes is large. - Y_multi = le.transform(y).astype(X.dtype, copy=False) + Y_multi = xp.asarray(le.transform(y), dtype=X.dtype, device=device_) # It is important that w0 is F-contiguous. w0 = np.zeros( - (classes.size, n_features + int(fit_intercept)), order="F", dtype=X.dtype + (size(classes), n_features + int(fit_intercept)), + order="F", + dtype=_matching_numpy_dtype(X, xp=xp), ) # IMPORTANT NOTE: @@ -317,7 +339,7 @@ def _logistic_regression_path( # This needs to be calculated after sample_weight is multiplied by # class_weight. It is even tested that passing class_weight is equivalent to # passing sample_weights according to class_weight. - sw_sum = n_samples if sample_weight is None else np.sum(sample_weight) + sw_sum = n_samples if sample_weight is None else float(xp.sum(sample_weight)) if coef is not None: if is_binary: @@ -352,7 +374,12 @@ def _logistic_regression_path( if is_binary: target = y_bin loss = LinearModelLoss( - base_loss=HalfBinomialLoss(), fit_intercept=fit_intercept + base_loss=( + HalfBinomialLoss() + if _is_numpy_namespace(xp) + else HalfBinomialLossArrayAPI() + ), + fit_intercept=fit_intercept, ) if solver == "lbfgs": func = loss.loss_gradient @@ -363,7 +390,11 @@ def _logistic_regression_path( warm_start_sag = {"coef": np.expand_dims(w0, axis=1)} else: # multinomial loss = LinearModelLoss( - base_loss=HalfMultinomialLoss(n_classes=classes.size), + base_loss=( + HalfMultinomialLoss(n_classes=size(classes)) + if _is_numpy_namespace(xp) + else HalfMultinomialLossArrayAPI(n_classes=size(classes)) + ), fit_intercept=fit_intercept, ) target = Y_multi @@ -382,7 +413,8 @@ def _logistic_regression_path( warm_start_sag = {"coef": w0.T} coefs = list() - n_iter = np.zeros(len(Cs), dtype=np.int32) + n_iter = xp.zeros(len(Cs), dtype=xp.int32, device=device_) + coefs_order = "C" if not _is_numpy_namespace(xp) else "K" for i, C in enumerate(Cs): if solver == "lbfgs": l2_reg_strength = 1.0 / (C * sw_sum) @@ -503,17 +535,23 @@ def _logistic_regression_path( raise ValueError(msg) if is_binary: - coefs.append(w0.copy()) + coefs.append( + xp.asarray(w0.copy(order=coefs_order), dtype=X.dtype, device=device_) + ) else: if solver in ["lbfgs", "newton-cg", "newton-cholesky"]: multi_w0 = np.reshape(w0, (n_classes, -1), order="F") else: multi_w0 = w0 - coefs.append(multi_w0.copy()) + coefs.append( + xp.asarray( + multi_w0.copy(order=coefs_order), dtype=X.dtype, device=device_ + ) + ) n_iter[i] = n_iter_i - return np.array(coefs), np.array(Cs), n_iter + return xp.stack(coefs), xp.asarray(Cs, device=device_), n_iter # helper function for LogisticCV @@ -1165,13 +1203,16 @@ def fit(self, X, y, sample_weight=None): if penalty == "elasticnet" and self.l1_ratio is None: raise ValueError("l1_ratio must be specified when penalty is elasticnet.") + xp, _, device_ = get_namespace_and_device(X) + xp_y, _ = get_namespace(y) + if self.penalty is None: if self.C != 1.0: # default value warnings.warn( "Setting penalty=None will ignore the C and l1_ratio parameters" ) # Note that check for l1_ratio is done right above - C_ = np.inf + C_ = xp.inf penalty = "l2" else: C_ = self.C @@ -1183,24 +1224,19 @@ def fit(self, X, y, sample_weight=None): if self.n_jobs is not None: warnings.warn(msg, category=FutureWarning) - if solver == "lbfgs": - _dtype = np.float64 - else: - _dtype = [np.float64, np.float32] - X, y = validate_data( self, X, y, accept_sparse="csr", - dtype=_dtype, + dtype=[xp.float64, xp.float32], order="C", accept_large_sparse=solver not in ["liblinear", "sag", "saga"], ) n_features = X.shape[1] check_classification_targets(y) - self.classes_ = np.unique(y) - n_classes = len(self.classes_) + self.classes_ = xp_y.unique_values(y) + n_classes = size(self.classes_) is_binary = n_classes == 2 if solver == "liblinear": @@ -1251,8 +1287,8 @@ def fit(self, X, y, sample_weight=None): else: warm_start_coef = None if warm_start_coef is not None and self.fit_intercept: - warm_start_coef = np.append( - warm_start_coef, self.intercept_[:, np.newaxis], axis=1 + warm_start_coef = xp.concat( + [warm_start_coef, self.intercept_[:, None]], axis=1 ) # TODO: enable multi-threading if benchmarks show a positive effect, @@ -1280,9 +1316,9 @@ def fit(self, X, y, sample_weight=None): n_threads=n_threads, ) - self.n_iter_ = np.asarray(n_iter, dtype=np.int32) + self.n_iter_ = xp.asarray(n_iter, dtype=xp.int32) - self.coef_ = coefs[0] + self.coef_ = coefs[0, ...] if self.fit_intercept: if is_binary: self.intercept_ = self.coef_[-1:] @@ -1292,10 +1328,10 @@ def fit(self, X, y, sample_weight=None): self.coef_ = self.coef_[:, :-1] else: if is_binary: - self.intercept_ = np.zeros(1, dtype=X.dtype) + self.intercept_ = xp.zeros(1, dtype=X.dtype, device=device_) self.coef_ = self.coef_[None, :] else: - self.intercept_ = np.zeros(n_classes, dtype=X.dtype) + self.intercept_ = xp.zeros(n_classes, dtype=X.dtype, device=device_) return self @@ -1323,7 +1359,7 @@ def predict_proba(self, X): """ check_is_fitted(self) - is_binary = self.classes_.size <= 2 + is_binary = size(self.classes_) <= 2 if is_binary: return super()._predict_proba_lr(X) else: @@ -1349,11 +1385,13 @@ def predict_log_proba(self, X): Returns the log-probability of the sample for each class in the model, where classes are ordered as they are in ``self.classes_``. """ - return np.log(self.predict_proba(X)) + xp, _ = get_namespace(X) + return xp.log(self.predict_proba(X)) def __sklearn_tags__(self): tags = super().__sklearn_tags__() tags.input_tags.sparse = True + tags.array_api_support = self.solver == "lbfgs" if self.solver == "liblinear": tags.classifier_tags.multi_class = False @@ -2238,4 +2276,5 @@ def _get_scorer(self): def __sklearn_tags__(self): tags = super().__sklearn_tags__() tags.input_tags.sparse = True + tags.array_api_support = False return tags diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index 1d655599c55ce..496884962119c 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -36,7 +36,14 @@ from sklearn.preprocessing import LabelEncoder, StandardScaler, scale from sklearn.svm import l1_min_c from sklearn.utils import compute_class_weight, shuffle -from sklearn.utils._testing import ignore_warnings +from sklearn.utils._array_api import ( + _atol_for_type, + _convert_to_numpy, + _get_namespace_device_dtype_ids, + device, + yield_namespace_device_dtype_combinations, +) +from sklearn.utils._testing import _array_api_for_tests, ignore_warnings from sklearn.utils.fixes import _IS_32BIT, COO_CONTAINERS, CSR_CONTAINERS pytestmark = pytest.mark.filterwarnings( @@ -1527,9 +1534,7 @@ def test_saga_vs_liblinear(global_random_seed, csr_container, l1_ratio): assert_array_almost_equal(saga.coef_, liblinear.coef_, 3) -@pytest.mark.parametrize( - "solver", ["liblinear", "newton-cg", "newton-cholesky", "saga"] -) +@pytest.mark.parametrize("solver", SOLVERS) @pytest.mark.parametrize("fit_intercept", [False, True]) @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) def test_dtype_match(solver, fit_intercept, csr_container): @@ -1591,10 +1596,10 @@ def test_dtype_match(solver, fit_intercept, csr_container): # Check accuracy consistency assert_allclose(lr_32.coef_, lr_64.coef_.astype(np.float32), atol=atol) - if solver == "saga" and fit_intercept: + if solver in ("sag", "saga") and fit_intercept: # FIXME: SAGA on sparse data fits the intercept inaccurately with the # default tol and max_iter parameters. - atol = 1e-1 + atol = 2e-1 assert_allclose(lr_32.coef_, lr_32_sparse.coef_, atol=atol) assert_allclose(lr_64.coef_, lr_64_sparse.coef_, atol=atol) @@ -2576,6 +2581,140 @@ def test_logisticregression_warns_with_n_jobs(): lr.fit(X, y) +@pytest.mark.parametrize("binary", [False, True]) +@pytest.mark.parametrize("use_str_y", [False, True]) +@pytest.mark.parametrize("use_sample_weight", [False, True]) +@pytest.mark.parametrize("class_weight", [None, "balanced", "dict"]) +@pytest.mark.parametrize( + "array_namespace, device_, dtype_name", + yield_namespace_device_dtype_combinations(), + ids=_get_namespace_device_dtype_ids, +) +@pytest.mark.filterwarnings("error::sklearn.exceptions.ConvergenceWarning") +def test_logistic_regression_array_api_compliance( + binary, + use_str_y, + use_sample_weight, + class_weight, + array_namespace, + device_, + dtype_name, +): + xp = _array_api_for_tests(array_namespace, device_) + X_np = iris.data.astype(dtype_name, copy=True) + n_samples, _ = X_np.shape + X_xp = xp.asarray(X_np, device=device_) + if use_str_y: + if binary: + target = (iris.target > 0).astype(np.int64) + target = np.array(["setosa", "not-setosa"])[target] + if class_weight == "dict": + class_weight = {"setosa": 1.0, "not-setosa": 3.0} + else: + target = iris.target_names[iris.target] + if class_weight == "dict": + class_weight = {"virginica": 1.0, "setosa": 2.0, "versicolor": 3.0} + y_np = target.copy() + y_xp_or_np = np.asarray(y_np, copy=True) + else: + if binary: + target = (iris.target > 0).astype(np.int64) + if class_weight == "dict": + class_weight = {0: 1.0, 1: 3.0} + else: + target = iris.target + if class_weight == "dict": + class_weight = {0: 1.0, 1: 2.0, 2: 3.0} + y_np = target.astype(dtype_name) + y_xp_or_np = xp.asarray(y_np, device=device_) + + if use_sample_weight: + sample_weight = ( + np.random.default_rng(0) + .uniform(-1, 5, size=n_samples) + .clip(0, None) + .astype(dtype_name) + ) + else: + sample_weight = None + + # Use a strong regularization to ensure coef_ can be identified to a higher + # precision even when taking into account the iterated discrepancies when + # the gradient is computed in float32. This is only necessary because the + # iris dataset is perfectly separable. + # We selected a low value of C (high coef_ regularization) to be able + # to identify coef_ to some strict enough precision level. However we + # also want to make sure that this choice of regularization does not + # constrain the fitted models to a trivial baseline classifier where only + # the intercept would be non-zero. + lr_params = dict( + C=1e-2, solver="lbfgs", tol=1e-12, max_iter=500, class_weight=class_weight + ) + with warnings.catch_warnings(): + # Make sure that we converge in the reference fit. + lr_np = LogisticRegression(**lr_params).fit( + X_np, y_np, sample_weight=sample_weight + ) + assert lr_np.n_iter_ < lr_np.max_iter + + # Test that C was not too large for meaningful testing. + assert np.abs(lr_np.coef_).max() > 0.1 + + predict_proba_np = lr_np.predict_proba(X_np) + preditct_log_proba_np = lr_np.predict_log_proba(X_np) + prediction_np = lr_np.predict(X_np) + # TODO: those tolerance levels seem quite high. Investigate further if we + # can hunt down the numerical discrepancies more precisely. + atol = _atol_for_type(dtype_name) * 10 + rtol = 5e-3 if dtype_name == "float32" else 1e-5 + + with config_context(array_api_dispatch=True): + with warnings.catch_warnings(): + # Make sure that we converge when using the namespace/device + # specific fit. + warnings.simplefilter("error", ConvergenceWarning) + lr_xp = LogisticRegression(**lr_params).fit( + X_xp, y_xp_or_np, sample_weight=sample_weight + ) + + assert lr_xp.n_iter_.shape == lr_np.n_iter_.shape + assert int(lr_xp.n_iter_[0]) < lr_xp.max_iter + + for attr_name in ("coef_", "intercept_"): + attr_xp = getattr(lr_xp, attr_name) + attr_np = getattr(lr_np, attr_name) + assert_allclose( + _convert_to_numpy(attr_xp, xp=xp), attr_np, rtol=rtol, atol=atol + ) + assert attr_xp.dtype == X_xp.dtype + assert device(attr_xp) == device(X_xp) + + predict_proba_xp = lr_xp.predict_proba(X_xp) + assert_allclose( + _convert_to_numpy(predict_proba_xp, xp=xp), + predict_proba_np, + rtol=rtol, + atol=atol, + ) + assert predict_proba_xp.dtype == X_xp.dtype + assert device(predict_proba_xp) == device(X_xp) + + predict_log_proba_xp = lr_xp.predict_log_proba(X_xp) + assert_allclose( + _convert_to_numpy(predict_log_proba_xp, xp=xp), + preditct_log_proba_np, + rtol=rtol, + atol=atol, + ) + assert predict_log_proba_xp.dtype == X_xp.dtype + assert device(predict_log_proba_xp) == device(X_xp) + + prediction_xp = lr_xp.predict(X_xp) + if not use_str_y: + prediction_xp = _convert_to_numpy(prediction_xp, xp=xp) + assert_array_equal(prediction_xp, prediction_np) + + # TODO(1.10): remove when penalty is removed @pytest.mark.filterwarnings("ignore:'penalty' was deprecated") @pytest.mark.parametrize("penalty, l1_ratio", [("l1", 0.0), ("l2", 1.0)]) diff --git a/sklearn/model_selection/_search_successive_halving.py b/sklearn/model_selection/_search_successive_halving.py index 35d1fb0611e2c..bbe3a4f6e6a27 100644 --- a/sklearn/model_selection/_search_successive_halving.py +++ b/sklearn/model_selection/_search_successive_halving.py @@ -370,6 +370,13 @@ def _run_search(self, evaluate_candidates): def _generate_candidate_params(self): pass + def __sklearn_tags__(self): + # TODO: remove this when we add array API support to + # `BaseSuccessiveHalving` + tags = super().__sklearn_tags__() + tags.array_api_support = False + return tags + class HalvingGridSearchCV(BaseSuccessiveHalving): """Search over specified parameter values with successive halving. diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 23239ee062267..020a758589713 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -591,10 +591,16 @@ def move_to(*arrays, xp, device): ) -def _expit(X, xp=None): +def _expit(X, out=None, xp=None): + # The out argument for exp and hence expit is only supported for numpy, + # but not in the Array API specification. xp, _ = get_namespace(X, xp=xp) if _is_numpy_namespace(xp): - return xp.asarray(special.expit(numpy.asarray(X))) + if out is not None: + special.expit(X, out=out) + else: + out = special.expit(X) + return out return 1.0 / (1.0 + xp.exp(-X)) @@ -1120,7 +1126,7 @@ def _modify_in_place_if_numpy(xp, func, *args, out=None, **kwargs): return out -def _bincount(array, weights=None, minlength=None, xp=None): +def _bincount(array, weights=None, minlength=0, xp=None): # TODO: update if bincount is ever adopted in a future version of the standard: # https://github.com/data-apis/array-api/issues/812 xp, _ = get_namespace(array, xp=xp) @@ -1156,11 +1162,7 @@ def _logsumexp(array, axis=None, xp=None): i_max_dt = xp.astype(index_max, array.dtype) m = xp.sum(i_max_dt, axis=axis, keepdims=True, dtype=array.dtype) # Specifying device explicitly is the fix for https://github.com/scipy/scipy/issues/22680 - shift = xp.where( - xp.isfinite(array_max), - array_max, - xp.asarray(0, dtype=array_max.dtype, device=device), - ) + shift = xp.where(xp.isfinite(array_max), array_max, 0) exp = xp.exp(array - shift) s = xp.sum(exp, axis=axis, keepdims=True, dtype=exp.dtype) s = xp.where(s == 0, s, s / m) @@ -1195,3 +1197,14 @@ def _half_multinomial_loss(y, pred, sample_weight=None, xp=None): return float( _average(log_sum_exp - label_predictions, weights=sample_weight, xp=xp) ) + + +def _matching_numpy_dtype(X, xp=None): + xp, _ = get_namespace(X, xp=xp) + if _is_numpy_namespace(xp): + return X.dtype + + dtypes_dict = xp.__array_namespace_info__().dtypes() + reversed_dtypes_dict = {dtype: name for name, dtype in dtypes_dict.items()} + dtype_name = reversed_dtypes_dict[X.dtype] + return numpy.__array_namespace_info__().dtypes()[dtype_name] diff --git a/sklearn/utils/class_weight.py b/sklearn/utils/class_weight.py index 6f9c7f185043b..2c7a23cea23cc 100644 --- a/sklearn/utils/class_weight.py +++ b/sklearn/utils/class_weight.py @@ -6,6 +6,15 @@ import numpy as np from scipy import sparse +from sklearn.utils._array_api import ( + _bincount, + _convert_to_numpy, + _is_numpy_namespace, + _isin, + get_namespace, + get_namespace_and_device, + size, +) from sklearn.utils._param_validation import StrOptions, validate_params from sklearn.utils.validation import _check_sample_weight @@ -64,35 +73,45 @@ def compute_class_weight(class_weight, *, classes, y, sample_weight=None): # Import error caused by circular imports. from sklearn.preprocessing import LabelEncoder - if set(y) - set(classes): + xp, _, device_ = get_namespace_and_device(y, classes) + unique_y = xp.unique_values(y) + if set(_convert_to_numpy(unique_y, xp)) - set(_convert_to_numpy(classes, xp)): raise ValueError("classes should include all valid labels that can be in y") if class_weight is None or len(class_weight) == 0: # uniform class weights - weight = np.ones(classes.shape[0], dtype=np.float64, order="C") + weight = xp.ones(classes.shape[0], device=device_) elif class_weight == "balanced": # Find the weight of each class as present in y. le = LabelEncoder() y_ind = le.fit_transform(y) - if not all(np.isin(classes, le.classes_)): + if not all(_isin(classes, xp.astype(le.classes_, classes.dtype), xp=xp)): raise ValueError("classes should have valid labels that are in y") + if _is_numpy_namespace(xp) and sample_weight is not None: + xp_sw, _ = get_namespace(sample_weight) + sample_weight = _convert_to_numpy(sample_weight, xp_sw) + sample_weight = _check_sample_weight(sample_weight, y) - weighted_class_counts = np.bincount(y_ind, weights=sample_weight) - recip_freq = weighted_class_counts.sum() / ( - len(le.classes_) * weighted_class_counts + weighted_class_counts = _bincount(y_ind, weights=sample_weight, xp=xp) + recip_freq = xp.sum(weighted_class_counts) / ( + size(le.classes_) * weighted_class_counts ) weight = recip_freq[le.transform(classes)] else: # user-defined dictionary - weight = np.ones(classes.shape[0], dtype=np.float64, order="C") + weight = xp.ones(size(classes), device=device_) unweighted_classes = [] for i, c in enumerate(classes): + try: + c = int(c) + except ValueError: # `classes` contains strings + c = str(c) if c in class_weight: weight[i] = class_weight[c] else: unweighted_classes.append(c) - n_weighted_classes = len(classes) - len(unweighted_classes) + n_weighted_classes = size(classes) - len(unweighted_classes) if unweighted_classes and n_weighted_classes != len(class_weight): unweighted_classes_user_friendly_str = np.array(unweighted_classes).tolist() raise ValueError( diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index 785bb668e9878..b300bd5aeebc6 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -24,6 +24,7 @@ _is_numpy_namespace, _isin, _logsumexp, + _matching_numpy_dtype, _max_precision_float_dtype, _median, _nanmax, @@ -928,3 +929,14 @@ def test_half_multinomial_loss(use_sample_weight, namespace, device_, dtype_name ) assert numpy.isclose(np_loss, xp_loss) + + +@pytest.mark.parametrize( + "namespace, device_, dtype_name", yield_namespace_device_dtype_combinations() +) +def test_matching_numpy_dtype(namespace, device_, dtype_name): + xp = _array_api_for_tests(namespace, device_) + X_np = numpy.arange(1000).astype(dtype_name) + X_xp = xp.asarray(X_np, device=device_) + ret_dtype = _matching_numpy_dtype(X_xp, xp=xp) + assert ret_dtype == X_np.dtype From ce6a5738feaeefb70423e08a73b9c57e54ccb7f5 Mon Sep 17 00:00:00 2001 From: fabianhenning <35563234+fabianhenning@users.noreply.github.com> Date: Thu, 12 Feb 2026 11:12:04 +0100 Subject: [PATCH 206/462] DOC Fix wrong designation (#33267) --- sklearn/multioutput.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/multioutput.py b/sklearn/multioutput.py index d03cb4ac4e7f8..79f1231520b39 100644 --- a/sklearn/multioutput.py +++ b/sklearn/multioutput.py @@ -1234,7 +1234,7 @@ class RegressorChain(MetaEstimatorMixin, RegressorMixin, _BaseChain): A list of clones of base_estimator. order_ : list - The order of labels in the classifier chain. + The order of labels in the regressor chain. n_features_in_ : int Number of features seen during :term:`fit`. Only defined if the From e72a6847a26cfdf4dd4300fe469ce2e72a93abbd Mon Sep 17 00:00:00 2001 From: Taoufik KEHAL Date: Thu, 12 Feb 2026 14:01:49 +0100 Subject: [PATCH 207/462] Fix broken BNP Paribas logo link in documentation homepage (#33259) co-authored-by: shibadityadeb --- doc/_static/bnp-small.png | Bin 0 -> 12497 bytes doc/templates/index.html | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 doc/_static/bnp-small.png diff --git a/doc/_static/bnp-small.png b/doc/_static/bnp-small.png new file mode 100644 index 0000000000000000000000000000000000000000..3dda0ee559cc59045b34669df5445ea2d2781ae6 GIT binary patch literal 12497 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 br}F;*>3ZdX{yWho uses scikit-learn?

- + From 7802c0c793007bf5f8acef7cb7f16f3c8fcc1e14 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Fri, 13 Feb 2026 11:00:22 +0100 Subject: [PATCH 208/462] MNT remove a few global_random_seed in test_logistic.py (#33165) --- sklearn/linear_model/tests/test_logistic.py | 31 ++++++++------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index 496884962119c..928c11c61953c 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -523,18 +523,15 @@ def __call__(self, model, X, y, sample_weight=None): ("recall", ["_macro", "_weighted"]), ], ) -def test_logistic_cv_multinomial_score( - global_random_seed, scoring, multiclass_agg_list -): +def test_logistic_cv_multinomial_score(scoring, multiclass_agg_list): # test that LogisticRegressionCV uses the right score to compute its # cross-validation scores when using a multinomial scoring # see https://github.com/scikit-learn/scikit-learn/issues/8720 X, y = make_classification( - n_samples=100, random_state=global_random_seed, n_classes=3, n_informative=6 + n_samples=100, random_state=42, n_classes=3, n_informative=6 ) train, test = np.arange(80), np.arange(80, 100) - lr = LogisticRegression(C=1.0) - # we use lbfgs to support multinomial + lr = LogisticRegression(C=1.0, solver="lbfgs") params = lr.get_params() # Replace default penalty='deprecated' in 1.8 by the equivalent value that # can be used by _log_reg_scoring_path @@ -1457,7 +1454,7 @@ def test_warm_start(global_random_seed, solver, warm_start, fit_intercept): @pytest.mark.parametrize("solver", ["newton-cholesky", "newton-cg"]) @pytest.mark.parametrize("fit_intercept", (True, False)) @pytest.mark.parametrize("C", (1, np.inf)) -def test_warm_start_newton_solver(global_random_seed, solver, fit_intercept, C): +def test_warm_start_newton_solver(solver, fit_intercept, C): """Test that 2 steps at once are the same as 2 single steps with warm start.""" X, y = iris.data, iris.target @@ -1466,7 +1463,6 @@ def test_warm_start_newton_solver(global_random_seed, solver, fit_intercept, C): max_iter=2, fit_intercept=fit_intercept, C=C, - random_state=global_random_seed, ) with ignore_warnings(category=ConvergenceWarning): clf1.fit(X, y) @@ -1477,7 +1473,6 @@ def test_warm_start_newton_solver(global_random_seed, solver, fit_intercept, C): warm_start=True, fit_intercept=fit_intercept, C=C, - random_state=global_random_seed, ) with ignore_warnings(category=ConvergenceWarning): clf2.fit(X, y) @@ -2227,7 +2222,7 @@ def test_scores_attribute_layout_elasticnet(): @pytest.mark.parametrize("solver", ["lbfgs", "newton-cg", "newton-cholesky"]) @pytest.mark.parametrize("fit_intercept", [False, True]) -def test_multinomial_identifiability_on_iris(global_random_seed, solver, fit_intercept): +def test_multinomial_identifiability_on_iris(solver, fit_intercept): """Test that the multinomial classification is identifiable. A multinomial with c classes can be modeled with @@ -2256,7 +2251,6 @@ def test_multinomial_identifiability_on_iris(global_random_seed, solver, fit_int C=len(iris.data), solver=solver, fit_intercept=fit_intercept, - random_state=global_random_seed, ) # Scaling X to ease convergence. X_scaled = scale(iris.data) @@ -2269,7 +2263,7 @@ def test_multinomial_identifiability_on_iris(global_random_seed, solver, fit_int @pytest.mark.parametrize("class_weight", [{0: 1.0, 1: 10.0, 2: 1.0}, "balanced"]) -def test_sample_weight_not_modified(global_random_seed, class_weight): +def test_sample_weight_not_modified(class_weight): X, y = load_iris(return_X_y=True) n_features = len(X) W = np.ones(n_features) @@ -2278,7 +2272,6 @@ def test_sample_weight_not_modified(global_random_seed, class_weight): expected = W.copy() clf = LogisticRegression( - random_state=global_random_seed, class_weight=class_weight, max_iter=200, ) @@ -2288,15 +2281,15 @@ def test_sample_weight_not_modified(global_random_seed, class_weight): @pytest.mark.parametrize("solver", SOLVERS) @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) -def test_large_sparse_matrix(solver, global_random_seed, csr_container): +def test_large_sparse_matrix(solver, csr_container): # Solvers either accept large sparse matrices, or raise helpful error. # Non-regression test for pull-request #21093. # generate sparse matrix with int64 indices - X = csr_container(sparse.rand(20, 10, random_state=global_random_seed)) + X = csr_container(sparse.rand(20, 10, random_state=42)) for attr in ["indices", "indptr"]: setattr(X, attr, getattr(X, attr).astype("int64")) - rng = np.random.RandomState(global_random_seed) + rng = np.random.RandomState(42) y = rng.randint(2, size=X.shape[0]) if solver in ["liblinear", "sag", "saga"]: @@ -2476,13 +2469,11 @@ def test_passing_params_without_enabling_metadata_routing(): lr_cv.score(X, y, **params) -def test_newton_cholesky_fallback_to_lbfgs(global_random_seed): +def test_newton_cholesky_fallback_to_lbfgs(): # Wide data matrix should lead to a rank-deficient Hessian matrix # hence make the Newton-Cholesky solver raise a warning and fallback to # lbfgs. - X, y = make_classification( - n_samples=10, n_features=20, random_state=global_random_seed - ) + X, y = make_classification(n_samples=10, n_features=20, random_state=42) C = 1e30 # very high C to nearly disable regularization # Check that LBFGS can converge without any warning on this problem. From ae985be9dd397575cc4217167201f88984ad1b0a Mon Sep 17 00:00:00 2001 From: Tejas Date: Fri, 13 Feb 2026 17:26:55 +0530 Subject: [PATCH 209/462] DOC Fix grammar in clustering.rst: replace 'allows to' with 'allows verb-ing' (#33273) --- doc/modules/clustering.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/modules/clustering.rst b/doc/modules/clustering.rst index 45ea46155de74..4b2fa47c40ef3 100644 --- a/doc/modules/clustering.rst +++ b/doc/modules/clustering.rst @@ -237,7 +237,7 @@ clustering algorithms, see :func:`sklearn.cluster.kmeans_plusplus` for details and example usage. The algorithm supports sample weights, which can be given by a parameter -``sample_weight``. This allows to assign more weight to some samples when +``sample_weight``. This allows assigning more weight to some samples when computing cluster centers and values of inertia. For example, assigning a weight of 2 to a sample is equivalent to adding a duplicate of that sample to the dataset :math:`X`. @@ -2120,7 +2120,7 @@ of classes. .. topic:: Advantages: - - Allows to examine the spread of each true cluster across predicted clusters + - Allows examining the spread of each true cluster across predicted clusters and vice versa. - The contingency table calculated is typically utilized in the calculation of From c0ef1e6d4d4f9078a7637440cd7846143dfde058 Mon Sep 17 00:00:00 2001 From: Junteng Li Date: Fri, 13 Feb 2026 17:25:58 +0000 Subject: [PATCH 210/462] ENH save one copy in linear_model preprocessing with sample_weight (#33041) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger --- .../sklearn.linear_model/33041.efficiency.rst | 7 +++++ sklearn/linear_model/_base.py | 3 ++- sklearn/linear_model/tests/test_base.py | 26 ++++++++++++------- 3 files changed, 26 insertions(+), 10 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33041.efficiency.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33041.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33041.efficiency.rst new file mode 100644 index 0000000000000..332ebcf68417e --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33041.efficiency.rst @@ -0,0 +1,7 @@ +- The :class:`linear_model.LinearRegression`, :class:`linear_model.Ridge`, + :class:`linear_model.Lasso`, :class:`linear_model.LassoCV`, + :class:`linear_model.ElasticNet`, :class:`linear_model.ElasticNetCV` and + :class:`linear_model.BayesianRidge` classes now no longer make an unnecessary copy of + dense `X, y` input during preprocessing when `copy_X=False` and `sample_weight` + is provided. + By :user:`Junteng Li `. diff --git a/sklearn/linear_model/_base.py b/sklearn/linear_model/_base.py index 67e9e01b12db0..0c881a27427e1 100644 --- a/sklearn/linear_model/_base.py +++ b/sklearn/linear_model/_base.py @@ -212,7 +212,8 @@ def _preprocess_data( # For sparse X and y, it triggers copies anyway. # For dense X and y that already have been copied, we safely do inplace # rescaling. - X, y, sample_weight_sqrt = _rescale_data(X, y, sample_weight, inplace=copy) + # Hence, inplace=True here regardless of copy. + X, y, sample_weight_sqrt = _rescale_data(X, y, sample_weight, inplace=True) else: sample_weight_sqrt = None return X, y, X_offset, y_offset, X_scale, sample_weight_sqrt diff --git a/sklearn/linear_model/tests/test_base.py b/sklearn/linear_model/tests/test_base.py index 0839d98144b7c..8d02124975783 100644 --- a/sklearn/linear_model/tests/test_base.py +++ b/sklearn/linear_model/tests/test_base.py @@ -540,25 +540,33 @@ def test_csr_preprocess_data(csr_container): @pytest.mark.parametrize("sparse_container", [None] + CSR_CONTAINERS) @pytest.mark.parametrize("to_copy", (True, False)) -def test_preprocess_copy_data_no_checks(sparse_container, to_copy): +@pytest.mark.parametrize("use_sample_weight", (False, True)) +def test_preprocess_copy_data_no_checks(sparse_container, to_copy, use_sample_weight): X, y = make_regression() X[X < 2.5] = 0.0 + sample_weight = np.ones(len(y)) if use_sample_weight else None + if sparse_container is not None: X = sparse_container(X) X_, y_, _, _, _, _ = _preprocess_data( - X, y, fit_intercept=True, copy=to_copy, check_input=False + X, + y, + sample_weight=sample_weight, + fit_intercept=True, + copy=to_copy, + check_input=False, ) - if to_copy and sparse_container is not None: - assert not np.may_share_memory(X_.data, X.data) - elif to_copy: - assert not np.may_share_memory(X_, X) - elif sparse_container is not None: - assert np.may_share_memory(X_.data, X.data) + if sparse_container is not None: + if to_copy or use_sample_weight: + # sparse X, y always copied when use_sample_weight, regardless of to_copy + assert not np.may_share_memory(X_.data, X.data) + else: + assert np.may_share_memory(X_.data, X.data) else: - assert np.may_share_memory(X_, X) + assert np.may_share_memory(X_, X) == (not to_copy) @pytest.mark.parametrize("rescale_with_sw", [False, True]) From 2ff996e74ec4c4ab27208f9a67cba42a8c97833b Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Sat, 14 Feb 2026 18:48:31 +0100 Subject: [PATCH 211/462] MNT use scipy.stats.yeojohnson in PowerTransformer (#33272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger --- .../changed-models/33272.enhancement.rst | 5 ++++ sklearn/preprocessing/_data.py | 26 ++----------------- sklearn/preprocessing/tests/test_data.py | 2 +- 3 files changed, 8 insertions(+), 25 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/changed-models/33272.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/changed-models/33272.enhancement.rst b/doc/whats_new/upcoming_changes/changed-models/33272.enhancement.rst new file mode 100644 index 0000000000000..2d1b9a82e109a --- /dev/null +++ b/doc/whats_new/upcoming_changes/changed-models/33272.enhancement.rst @@ -0,0 +1,5 @@ +- The :meth:`transform` method of :class:`preprocessing.PowerTransformer` with + `method="yeo-johnson"` now uses the numerical more stable function + `scipy.stats.yeojohnson` instead of an own implementation. The results may deviate in + numerical edge cases or within the precision of floating-point arithmetic. + By :user:`Christian Lorentzen `. diff --git a/sklearn/preprocessing/_data.py b/sklearn/preprocessing/_data.py index c904da57a5f0d..991b0132e3945 100644 --- a/sklearn/preprocessing/_data.py +++ b/sklearn/preprocessing/_data.py @@ -3392,7 +3392,7 @@ def _fit(self, X, y=None, force_transform=False): transform_function = { "box-cox": boxcox, - "yeo-johnson": self._yeo_johnson_transform, + "yeo-johnson": stats.yeojohnson, }[self.method] with np.errstate(invalid="ignore"): # hide NaN warnings @@ -3437,7 +3437,7 @@ def transform(self, X): transform_function = { "box-cox": boxcox, - "yeo-johnson": self._yeo_johnson_transform, + "yeo-johnson": stats.yeojohnson, }[self.method] for i, lmbda in enumerate(self.lambdas_): with np.errstate(invalid="ignore"): # hide NaN warnings @@ -3528,28 +3528,6 @@ def _yeo_johnson_inverse_transform(self, x, lmbda): return x_inv - def _yeo_johnson_transform(self, x, lmbda): - """Return transformed input x following Yeo-Johnson transform with - parameter lambda. - """ - - out = np.zeros_like(x) - pos = x >= 0 # binary mask - - # when x >= 0 - if abs(lmbda) < np.spacing(1.0): - out[pos] = np.log1p(x[pos]) - else: # lmbda != 0 - out[pos] = (np.power(x[pos] + 1, lmbda) - 1) / lmbda - - # when x < 0 - if abs(lmbda - 2) > np.spacing(1.0): - out[~pos] = -(np.power(-x[~pos] + 1, 2 - lmbda) - 1) / (2 - lmbda) - else: # lmbda == 2 - out[~pos] = -np.log1p(-x[~pos]) - - return out - def _box_cox_optimize(self, x): """Find and return optimal lambda parameter of the Box-Cox transform by MLE, for observed data x. diff --git a/sklearn/preprocessing/tests/test_data.py b/sklearn/preprocessing/tests/test_data.py index 8d9c6a5f454ab..e82fd55a10148 100644 --- a/sklearn/preprocessing/tests/test_data.py +++ b/sklearn/preprocessing/tests/test_data.py @@ -2756,7 +2756,7 @@ def test_power_transformer_constant_feature(standardize): for Xt_ in [Xft, Xt]: if standardize: - assert_allclose(Xt_, np.zeros_like(X)) + assert_allclose(Xt_, np.zeros_like(X), atol=1e-14) else: assert_allclose(Xt_, X) From 898d9e3e7ad7007e4c8a479fde4df82976880b06 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 16 Feb 2026 04:14:54 -0500 Subject: [PATCH 212/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33289) Co-authored-by: Lock file bot --- .../azure/pylatest_pip_scipy_dev_linux-64_conda.lock | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 871d065304336..ec24f8f7cec3d 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -2,12 +2,11 @@ # platform: linux-64 # input_hash: 24ef416e2330a91ab0f9ebe316ec9431025e1b63eab146a1ce2e60f14fcf4caa @EXPLICIT -https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 @@ -28,13 +27,13 @@ https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_100_cp314.conda#b40594d5da041824087eebe12228af42 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c # pip charset-normalizer @ https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 -# pip coverage @ https://files.pythonhosted.org/packages/72/2d/b3f6913ee5a1d5cdd04106f257e5fac5d048992ffc2d9995d07b0f17739f/coverage-7.13.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=06e49c5897cb12e3f7ecdc111d44e97c4f6d0557b81a7a0204ed70a8b038f86f +# pip coverage @ https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea @@ -44,7 +43,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip meson @ https://files.pythonhosted.org/packages/9c/d5/582789135863eec7c8c1fa31fbde401b3d5d82dbbb4a0973351a1698f738/meson-1.10.1-py3-none-any.whl#sha256=fe43d1cc2e6de146fbea78f3a062194bcc0e779efc8a0f0d7c35544dfb86731f # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 -# pip platformdirs @ https://files.pythonhosted.org/packages/cb/28/3bfe2fa5a7b9c46fe7e13c97bda14c895fb10fa2ebf1d0abb90e0cea7ee1/platformdirs-4.5.1-py3-none-any.whl#sha256=d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31 +# pip platformdirs @ https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl#sha256=9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b # pip roman-numerals @ https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl#sha256=647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7 @@ -59,7 +58,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb # pip urllib3 @ https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl#sha256=bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 -# pip pyproject-metadata @ https://files.pythonhosted.org/packages/c0/57/e69a1de45ec7a99a707e9f1a5defa035a48de0cae2d8582451c72d2db456/pyproject_metadata-0.10.0-py3-none-any.whl#sha256=b1e439a9f7560f9792ee5975dcf5e89d2510b1fc84a922d7e5d665aa9102d966 +# pip pyproject-metadata @ https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl#sha256=85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 From 54481b2737b78a105b0cb05e9774986fffd39da7 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 16 Feb 2026 04:19:10 -0500 Subject: [PATCH 213/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33290) Co-authored-by: Lock file bot --- ...a_forge_cuda_array-api_linux-64_conda.lock | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index a57cd5009e579..17e257adec1f1 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_1.conda#9e298d76f543deb06eb0f3413675e13a +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_2.conda#253e70376a8ae74f9d99d44712b3e087 https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a66894dfd07c4510beb6b3f9672ccc0 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa @@ -83,7 +83,7 @@ https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libabseil-20250512.1-cxx17_hba17884_0.conda#83b160d4da3e1e847bf044997621ed63 +https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda#6f7b4302263347698fd24565fbf11310 https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e @@ -96,13 +96,13 @@ https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libnvjitlink-12.9.86-hecca717_2.conda#3461b0f2d5cbb7973d361f9e85241d98 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 -https://conda.anaconda.org/conda-forge/linux-64/nccl-2.29.2.1-h4d09622_2.conda#a8e54c58b3efc6fbbe8dfeb9f65c28d6 +https://conda.anaconda.org/conda-forge/linux-64/nccl-2.29.3.1-h4d09622_0.conda#71546ecb7c830d277af20cac43a5bdd0 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 @@ -131,24 +131,24 @@ https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.co https://conda.anaconda.org/conda-forge/linux-64/libcurand-dev-10.3.10.19-h676940d_1.conda#fc716aaff5af15b80ccbd28b3e67672c https://conda.anaconda.org/conda-forge/linux-64/libcusparse-12.5.10.65-hecca717_2.conda#890ebfaad48c887d3d82847ec9d6bc79 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_1.conda#5b5846bc2b23e07a1d61b89dcb67fcf0 https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-openmp_hd680484_4.conda#c0512e4f60d62ccccb4c3c8333b33608 -https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_4.conda#07479fc04ba3ddd5d9f760ef1635cfa7 -https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h7b12aa8_0.conda#a30848ebf39327ea078cf26d114cff53 +https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 +https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 https://conda.anaconda.org/rapidsai/linux-64/librmm-26.02.00-cuda12_260204_498dafcf.conda#057e94dab29e9c69b4542eb0c61b161e https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-258.3-h6569c3e_0.conda#68294614784925a7c1427835dbe217d7 +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-259.1-h6569c3e_0.conda#dbd34a7b836b479604b8b5f07c3a35ba https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libudev1-258.3-h6569c3e_0.conda#dc6d00d149316edb629059671dd8600e +https://conda.anaconda.org/conda-forge/linux-64/libudev1-259.1-h6569c3e_0.conda#8b11ee89763fc236d854c46cab7e762d https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.7-h28f887f_1.conda#7b8e3f846353b75db163ad93248e5f9d https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-ha8fc4e3_5.conda#3028f20dacafc00b22b88b324c8956cc https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 @@ -160,7 +160,7 @@ https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcublas-dev-12.9.1.4-h676940d_1.conda#f90f4ff087ac29005c6989ea0fb2735a https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.conda#a178a1f3642521f104ecceeefa138d01 -https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_0.conda#d71b1cf78714f31f1264591cdb7ce97d +https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_1.conda#c5b8ea827c65e5811d61aa49cd0bae9a https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2.conda#bb6e31a0daa64ede76fe8d3fff01c06f @@ -172,10 +172,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda# https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-openmp_hd77311e_4.conda#525e2455ed342f2aef93c59ac5db2e28 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-h19cb568_0.conda#a98b8d7cfdd20004f1bdd1a51cb22c58 +https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-hbb90d81_1.conda#9269175175f18091b8844c8e9f213205 https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 -https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_0.conda#0227d04521bc3d28c7995c7e1f99a721 +https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 @@ -186,12 +186,12 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-hc63082f_11.co https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.3.3-pyhcf101f3_0.conda#b08fa4a3478526e33a4c08224398d2e5 +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.3.4-pyhcf101f3_0.conda#5531bd855da47b70361e2e2207dd1864 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda#9bcbd351966dc56a24fc0c368da5ad99 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda#2cfaaccf085c133a477f0a7a8657afe9 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.0-pyhd8ed1ab_0.conda#69296c50b5876a09be85c512985b922a https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 @@ -200,7 +200,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openb https://conda.anaconda.org/conda-forge/linux-64/libcufile-1.14.1.1-hbc026e6_1.conda#cab1818eada3952ed09c8dcbb7c26af7 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-dev-11.7.5.82-h676940d_2.conda#0fe12e558abf507458bcec839e29778d https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda#ff63bb12ac31c176ff257e3289f20770 +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.0-h1d1128b_1.conda#66055700c90b50c0405a4e515bb4fe3c https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 @@ -215,14 +215,14 @@ https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda# https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.590.48-pyhd8ed1ab_0.conda#fda409cefdbd417f9ca4e072c39add77 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py313h80991f8_0.conda#183fe6b9e99e5c2b464c1573ec78eac8 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py313h80991f8_0.conda#2d5ee4938cdde91a8967f3eea686c546 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -240,7 +240,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.3-h06ab39a_1.conda#3689a4290319587e3b54a4f9e68f70c8 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.3-py313h3dea7bd_0.conda#fa90494c873b21b3bdb21c3b588ff043 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py313h3dea7bd_0.conda#77e1fc7133e03ccd62070f2405c82ea9 https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.5-py313h929d4db_0.conda#f2416964cdb2808dd2ed5be276a8fcdb https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee @@ -250,16 +250,16 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-h9d11ab5_1.conda#cd398eb8374fb626a710b7a35b7ffa98 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-h9692893_2.conda#c3de1cc30bc11edbc98aed352381449d +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.12-h4df99d1_100.conda#3d92938d5b83c49162ade038aab58a59 https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py313h246eb7c_0.conda#932203205c4cf6f661180b98a48f195a @@ -275,8 +275,8 @@ https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4. https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.5.1-cuda12_py313hacc9b55_1.conda#808c80c320dfd77ba5da9f6a35b07503 https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.5-pyh698daf1_0.conda#a4fb0d4ffdac1cf2cda9318d2f789d20 https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.6.0-py313h28b6081_2.conda#388fb72307f756f7f2c7f5928647bc6b -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_ha70ccd2_201.conda#8ecb348d9f4c748e79afa17308d23d49 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_1.conda#384a1730ea66a72692e377cb45996d61 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_hb019b6b_202.conda#20529bf89b9dad005a5ace8bc5408624 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.conda#84cef0ce56c6db53edb3f8b83bdbb364 https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 @@ -295,25 +295,25 @@ https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hf https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_h673abb8_201.conda#f8dae51be1b9afdccd70b576b8f73b44 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_hb8e8477_202.conda#d0429f5f90f804183a84c3f861a7eaa2 https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h258748b_2_cuda.conda#c364f39d8a924797157da59d8cdd6b97 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h2603568_3_cpu.conda#4952208743759431df21f01aba7466dd https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b -https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_201.conda#fb17e944f1ff5c1ab65822ba1f539b9d +https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_202.conda#1efceead0b494f34670136ce6de29e79 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h8c2c5c3_2_cuda.conda#7846ea1f43ef6beb04749b5dffd6e4da -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_2_cuda.conda#1e2a463be2b1248c214b246fa14b72f6 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h53684a4_3_cpu.conda#8ffa55113b6ade32fe4a51d480f0b806 +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_3_cpu.conda#e3eef5f398cccdd73d3ff2e3c8ec0793 https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313h85046ba_0.conda#f6161781ceb86e9f5da1b532e4c4453c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_2_cuda.conda#b1f327dae633933118765c113fd3ecd0 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_3_cpu.conda#c2415c2264b6b5e4ef45019ce6aa9579 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py313hc6b0d6e_0_cuda.conda#c0ee292386cfb7e143117c26d26698ea -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_2_cuda.conda#fa0aa202043167a22dd7638c08004cb2 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py313h98bfbea_0_cpu.conda#c8d1ba76789588fdf7fddc213a25137e +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_3_cpu.conda#22beeb3b36026e14f509a8b62ca58f1a https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.02.00-cuda12_260204_a2f5a8b7.conda#361cae27e77618c6ba9f943807471f9f https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.02.00-cuda12_py313_260204_c212ab9b.conda#14933b753ec82f9d5a61d7cb4b5e2e71 https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.02.00-cuda12_py313_260204_a2f5a8b7.conda#c46807878ad576379e7be3acc187d13a -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-h3f74fd7_2_cuda.conda#cf0b0682dadc05c597b11ff24ae6c0b7 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-hb4dd7c2_3_cpu.conda#c582146e900636a8db83955cc15eadd5 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.0-py313h78bf25f_0.conda#a6e89cb214f318db9548b791ba27f862 From db26c7f580ae49209ff5a6e3a43d2519a8f9c1cc Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 16 Feb 2026 04:20:27 -0500 Subject: [PATCH 214/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33291) Co-authored-by: Lock file bot --- build_tools/azure/debian_32bit_lock.txt | 4 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 68 ++++++++-------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 14 ++-- .../pylatest_conda_forge_osx-arm64_conda.lock | 20 ++--- ...st_pip_openblas_pandas_linux-64_conda.lock | 9 +-- ...nblas_min_dependencies_linux-64_conda.lock | 60 +++++++------- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 11 ++- ...min_conda_forge_openblas_win-64_conda.lock | 16 ++-- build_tools/azure/ubuntu_atlas_lock.txt | 2 +- build_tools/circle/doc_linux-64_conda.lock | 48 ++++++----- .../doc_min_dependencies_linux-64_conda.lock | 80 ++++++++++--------- ...n_conda_forge_arm_linux-aarch64_conda.lock | 20 ++--- 12 files changed, 176 insertions(+), 176 deletions(-) diff --git a/build_tools/azure/debian_32bit_lock.txt b/build_tools/azure/debian_32bit_lock.txt index 2684298b8daea..c369887a51a01 100644 --- a/build_tools/azure/debian_32bit_lock.txt +++ b/build_tools/azure/debian_32bit_lock.txt @@ -4,7 +4,7 @@ # # pip-compile --output-file=build_tools/azure/debian_32bit_lock.txt build_tools/azure/debian_32bit_requirements.txt # -coverage[toml]==7.13.3 +coverage[toml]==7.13.4 # via pytest-cov cython==3.2.4 # via -r build_tools/azure/debian_32bit_requirements.txt @@ -31,7 +31,7 @@ pluggy==1.6.0 # pytest-cov pygments==2.19.2 # via pytest -pyproject-metadata==0.10.0 +pyproject-metadata==0.11.0 # via meson-python pytest==9.0.2 # via diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index 1bd0fc21ae06e..e5dece942f515 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -6,7 +6,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_1.conda#9e298d76f543deb06eb0f3413675e13a +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_2.conda#253e70376a8ae74f9d99d44712b3e087 https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_463.conda#291727757c8a8613312aaa4b52e82ad8 https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa @@ -61,7 +61,7 @@ https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libabseil-20250512.1-cxx17_hba17884_0.conda#83b160d4da3e1e847bf044997621ed63 +https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda#6f7b4302263347698fd24565fbf11310 https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 @@ -70,7 +70,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -98,21 +98,21 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_1.conda#5b5846bc2b23e07a1d61b89dcb67fcf0 https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 -https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.31.1-h49aed37_4.conda#07479fc04ba3ddd5d9f760ef1635cfa7 -https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h7b12aa8_0.conda#a30848ebf39327ea078cf26d114cff53 +https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 +https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 -https://conda.anaconda.org/conda-forge/linux-64/nodejs-22.21.1-h273caaf_1.conda#2306549f0179b16be2e9e40e5396456e +https://conda.anaconda.org/conda-forge/linux-64/nodejs-22.21.1-h273caaf_2.conda#264e1ba248b109705429b4375888467a https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.7-h28f887f_1.conda#7b8e3f846353b75db163ad93248e5f9d https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-ha8fc4e3_5.conda#3028f20dacafc00b22b88b324c8956cc https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 @@ -126,10 +126,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-h19cb568_0.conda#a98b8d7cfdd20004f1bdd1a51cb22c58 +https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-hbb90d81_1.conda#9269175175f18091b8844c8e9f213205 https://conda.anaconda.org/conda-forge/linux-64/playwright-1.58.2-h0bd9c3d_0.conda#9d161e4e16adbf1155a12470ced3c4cc -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_100_cp314.conda#b40594d5da041824087eebe12228af42 -https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_0.conda#0227d04521bc3d28c7995c7e1f99a721 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 +https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 @@ -143,11 +143,11 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_100.conda#32a3e6470f571e373e3d723cccb0b521 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda#3bb89e4f795e5414addaa531d6b1500a https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda#2cfaaccf085c133a477f0a7a8657afe9 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.0-pyhd8ed1ab_0.conda#69296c50b5876a09be85c512985b922a https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.1-py314h42812f9_1.conda#cca70a5a85afb519e8c839ae80dc9334 @@ -157,7 +157,7 @@ https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py314h97ea11e_2.conda#57f1ce4f7ba6bcd460be8f83c8f04c69 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.73.1-h3288cfb_1.conda#ff63bb12ac31c176ff257e3289f20770 +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.0-h1d1128b_1.conda#66055700c90b50c0405a4e515bb4fe3c https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 @@ -170,7 +170,7 @@ https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#3 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py314h8ec4b1a_0.conda#f9b6a8fbb8dcb840a0c1c052dc5092e4 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py314h8ec4b1a_0.conda#79678378ae235e24b3aa83cee1b38207 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 @@ -178,7 +178,7 @@ https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda#23b4ba5619c4752976eb7ba1f5acb7e8 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f @@ -186,7 +186,7 @@ https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py314h5bd0f2a_0.conda#e35f08043f54d26a1be93fdbf90d30c3 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py314h5bd0f2a_1.conda#58e2ee530005067c5db23f33c6ab43d2 +https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py314h5bd0f2a_0.conda#494fdf358c152f9fdd0673c128c2f3dd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b @@ -197,7 +197,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.3-h06ab39a_1.conda#3689a4290319587e3b54a4f9e68f70c8 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.3-py314h67df5f8_0.conda#705e973836337db525548d91d44ca3bc +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py314h67df5f8_0.conda#6c7efc167cee337d9c41200506d022b8 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f @@ -207,15 +207,15 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-hdb79228_0.conda#a2e30ccd49f753fd30de0d30b1569789 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-hb9b0907_1.conda#1c0320794855f457dea27d35c4c71e23 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-h9d11ab5_1.conda#cd398eb8374fb626a710b7a35b7ffa98 +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-h9692893_2.conda#c3de1cc30bc11edbc98aed352381449d +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.0-pyhd8ed1ab_0.conda#ec33a030c3bc90f0131305a8eba5f8a3 -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_100.conda#90c63d1e08a8bce206e66e95ef249f48 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda#235765e4ea0d0301c75965985163b5a1 https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda#a4059bc12930bddeb41aef71537ffaed https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 @@ -224,7 +224,7 @@ https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_ https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.4-h8824e59_0.conda#113b9d9913280474c0868b0e290c0326 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_0.conda#bd21962ff8a9d1ce4720d42a35a4af40 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_1.conda#384a1730ea66a72692e377cb45996d61 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py314h9891dd4_0.conda#6c7bdf1b5e901fd16789cdddce83956f @@ -241,33 +241,33 @@ https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hf https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h40b5c2d_2_cpu.conda#282f8460096fdc04d2c62ca2a30357a1 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h2603568_3_cpu.conda#4952208743759431df21f01aba7466dd https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h8c2c5c3_2_cpu.conda#c9c3d7509b7faef60374fa290b4e5071 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h53684a4_3_cpu.conda#8ffa55113b6ade32fe4a51d480f0b806 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_2_cpu.conda#64c8c3132e92b2d02e6b0bcdf7125090 -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h0bc6d91_101.conda#e9ec87a52136692bcf59f97063de3c78 +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_3_cpu.conda#e3eef5f398cccdd73d3ff2e3c8ec0793 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h7058990_102.conda#478b66bfe4b3b33f92442eb2131cc42b https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_1.conda#4ea6b620fdf24a1a0bc4f1c7134dfafb https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py314hf36963e_0.conda#46a2b79da4213038907306040c9c9fd8 https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_2_cpu.conda#f67acaf4653452503669ade10edec780 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_3_cpu.conda#c2415c2264b6b5e4ef45019ce6aa9579 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py314hb4ffadd_0.conda#90e3461036907dcd77c950308c1033d2 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py314h52d6ec5_0_cpu.conda#267abc6a9fe2b609221a7b2a42b15e1c -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h3c9122e_101.conda#7168ab2f0a0bd4c64fb48c65b55523d9 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py314h969be7f_0_cpu.conda#66b6069247a271f2792ecb90e1087fde +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h6018c46_102.conda#1719e8fde93354419f0f6e1b46d67fcf https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py314hf07bd8e_1.conda#c7df812186fb1290bc00d9b7b5a50b18 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.1.0-pyhcf101f3_0.conda#57d364589a8c710c5b34e8b4a5312ea6 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_2_cpu.conda#d3633b19c4d7e26474733e18e602e8ce +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_3_cpu.conda#22beeb3b36026e14f509a8b62ca58f1a https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_101.conda#c533790737122f36f779ac3d66ce48f1 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-h3f74fd7_2_cpu.conda#8b003b0de3b7c7455400752d0df67d76 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_102.conda#9061f7a9fc6c51108ecfb97132161167 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-hb4dd7c2_3_cpu.conda#c582146e900636a8db83955cc15eadd5 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.0-py314hdafbbf9_0.conda#f63f85bccdd104d2ffa341fd705f86d9 diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index f96701dbaf715..5728134da66e5 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -29,7 +29,7 @@ https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda#21f765 https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda#63186ac7a8a24b3528b4b14f21c03f54 https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda#5a088b358e37ccb4f4e5c573ff37a9f9 -https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.54-h07817ec_0.conda#3d43dcdfcc3971939c80f855cf2df235 +https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.55-h07817ec_0.conda#4fc7ed44d55aaf1d72b8fbc18774b90c https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda#d910105ce2b14dfb2b32e92ec7653420 https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-hd57b93d_1.conda#060f6892620dc862f3b54b9b2da8f177 @@ -46,7 +46,7 @@ https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.con https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_17.conda#500bac4a846e5001cbf05572df6c3654 https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h745d5cb_1.conda#1fd2c75a8a9adc629983ed629dec42e1 -https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_100_cp314.conda#b35e4ee0c1832ba9f8669f88983d44c5 +https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda#030ec23658b941438ac42303aff0db2b https://conda.anaconda.org/conda-forge/osx-64/brotli-1.2.0-hf139dec_1.conda#149d8ee7d6541a02a6117d8814fd9413 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -66,22 +66,22 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.4-py314h3d180e3_0.conda#e9dfcd5b883e35aebe6dbe2c197dddbe https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.0-py314h6482030_1.conda#d69097de15cbad36f1eaafda0bad598a -https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.3-py314h10d0514_0.conda#89676cb93389732dc8f71ec39798083d +https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.1-py314h4f144dc_0.conda#773e3141f292d9698e706da094ada8c1 +https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.4-py314h10d0514_0.conda#f27072a17bcb5061cd46de7d01f69028 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.1-h694c41f_0.conda#ca641fdf8b7803f4b7212b6d66375930 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_17.conda#218faf079bac8521ccf3f8542feeb51d -https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.0-py314hf9dbaa9_0.conda#ca55b2df1530e093f26d25ed503aafe8 -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.1-py314hf9dbaa9_0.conda#9a35ec32776ac587bf178233fd2176e4 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.13.0-h06b67a2_5.conda#f3e5cd2b56a3c866214b1d2529a54730 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock index bf15224cd1f1f..7971a75fe0eae 100644 --- a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock @@ -35,12 +35,12 @@ https://conda.anaconda.org/conda-forge/osx-arm64/fmt-12.1.0-h403dcb5_0.conda#ae2 https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-h7bae524_2.conda#eed7278dfbab727b56f2c0b64330814b https://conda.anaconda.org/conda-forge/osx-arm64/isl-0.26-imath32_h347afa1_101.conda#e80e44a3f4862b1da870dc0557f8cf3b https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda#a74332d9b60b62905e3d30709df08bf1 -https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.0-cxx17_h2062a1b_0.conda#160a2437f91ee5e1bc0178b2837a193c +https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda#bb65152e0d7c7178c0f1ee25692c9fd1 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda#079e88933963f3f149054eec2c487bc2 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda#58b2c5aee0ad58549bf92baead9baead -https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.54-h132b30e_0.conda#1b80fd1eecb98f1cb7de4239f5d7dc15 +https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.55-h132b30e_0.conda#871dc88b0192ac49b6a5509932c31377 https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda#4b0bf313c53c3e89692f020fb55d5f2c https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h5ef1a60_1.conda#7eed1026708e26ee512f43a04d9d0027 @@ -63,14 +63,14 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.con https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-h8d039ee_1.conda#fd804ee851e20faca4fecc7df0901d07 https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.1-hb693164_3.conda#4e4ea852d54cc2b869842de5044662fb -https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_100_cp314.conda#97852749b58606ffe363c2cc491cfce1 +https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda#753c8d0447677acb7ddbcc6e03e82661 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda#48ece20aa479be6ac9a284772827d00c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_100.conda#32a3e6470f571e373e3d723cccb0b521 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda#3bb89e4f795e5414addaa531d6b1500a https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py314hc6117b3_0.conda#1289de88f884ac89144949cb97ccabe7 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.20.3-pyhd8ed1ab_0.conda#2cfaaccf085c133a477f0a7a8657afe9 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.0-pyhd8ed1ab_0.conda#69296c50b5876a09be85c512985b922a https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py314h42813c9_2.conda#9aa431bf603c231e8c77a1b0842a85ed @@ -91,7 +91,7 @@ https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda#ade77ad7513177297b1d75e351e136ce https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f @@ -99,8 +99,8 @@ https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py314h0612a62_0.conda#83e1a2d7b0c1352870bbe9d9406135cf https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.0-py314h0612a62_1.conda#c673decfe1f120b0717d0aa193b10060 -https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.3-py314h6e9b3f0_0.conda#e81fd2615bfa91c3e3c2966b4f8d6fa2 +https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py314h6c2aa35_0.conda#4fffb3ba871bb05f34ffb705534dfef5 +https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.4-py314h6e9b3f0_0.conda#96c7bf4f2b5010d29604a62e91e634bb https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.1-hce30654_0.conda#1ec9a1ee7a2c9339774ad9bb6fe6caec @@ -111,9 +111,9 @@ https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_h https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_7.conda#5600ae1b88144099572939e773f4b20b https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_17.conda#45ba22eb5381fb602a45233d89ba27ae https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef -https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.1.0-py314hab283cf_0.conda#1f9dae6213643ac883e300c11df611eb +https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.1.1-py314hab283cf_0.conda#bcb38a8005e93a3b240a0dbcf28df87a https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_7.conda#3b992d143f0008588ca26df8a324eee9 diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index f806978ace355..92b80f1ee85af 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -2,12 +2,11 @@ # platform: linux-64 # input_hash: 379fba3287458f6d9cd98c2c5855086a7e8b681b1116f1ab22e6e7ffc97a8c78 @EXPLICIT -https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 @@ -34,7 +33,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c # pip charset-normalizer @ https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 -# pip coverage @ https://files.pythonhosted.org/packages/6f/99/97b600225fbf631e6f5bfd3ad5bcaf87fbb9e34ff87492e5a572ff01bbe2/coverage-7.13.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=16d23d6579cf80a474ad160ca14d8b319abaa6db62759d6eef53b2fc979b58c8 +# pip coverage @ https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 # pip cython @ https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de @@ -50,7 +49,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip numpy @ https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499 # pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 -# pip pillow @ https://files.pythonhosted.org/packages/01/9a/632e58ec89a32738cabfd9ec418f0e9898a2b4719afc581f07c04a05e3c9/pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc +# pip pillow @ https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b # pip pyparsing @ https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl#sha256=850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d @@ -68,7 +67,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip array-api-strict @ https://files.pythonhosted.org/packages/e1/7b/81bef4348db9705d829c58b9e563c78eddca24438f1ce1108d709e6eed55/array_api_strict-2.4.1-py3-none-any.whl#sha256=22198ceb47cd3d9c0534c50650d265848d0da6ff71707171215e6678ce811ca5 # pip contourpy @ https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 -# pip pyproject-metadata @ https://files.pythonhosted.org/packages/c0/57/e69a1de45ec7a99a707e9f1a5defa035a48de0cae2d8582451c72d2db456/pyproject_metadata-0.10.0-py3-none-any.whl#sha256=b1e439a9f7560f9792ee5975dcf5e89d2510b1fc84a922d7e5d665aa9102d966 +# pip pyproject-metadata @ https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl#sha256=85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index fe191b6a872cc..d5267642ced6a 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -21,6 +21,7 @@ https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.con https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 +https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda#f9f81ea472684d75b9dd8d0b328cf655 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 @@ -52,6 +53,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#60 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.8.23-hd590300_0.conda#cc4f06f7eedb1523f3b83fd0fb3942ff https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d +https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.0.9-h166bdaf_9.conda#61641e239f96eae2b8492dc7e755828c @@ -63,8 +65,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c @@ -88,7 +89,6 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1 https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1.conda#f883d61afbc95c50f7b3f62546da4235 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 -https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda#d1db1b8be7c3a8983dcbbbfe4f0765de @@ -97,15 +97,16 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.co https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_17.conda#d7954bb54fc77e7952a78e5e0d134df5 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_1.conda#5b5846bc2b23e07a1d61b89dcb67fcf0 https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_3.conda#70d1de6301b58ed99fea01490a9802a3 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda#1d4c18d75c51ed9d00092a891a547a7d https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h8fd135c_2.conda#bbf65f7688512872f063810623b755dc https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318b08df404f9c9be5712aaa5a6f0bb0 -https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/rdma-core-28.9-h59595ed_1.conda#aeffb7c06b5f65e55e6c637408dc4100 https://conda.anaconda.org/conda-forge/linux-64/re2-2023.03.02-h8c504da_0.conda#206f8fa808748f6e90599c3368a1114e https://conda.anaconda.org/conda-forge/linux-64/snappy-1.1.10-hdb0a2a9_1.conda#78b8b85bdf1f42b8a2b3cb577d8742d1 @@ -113,12 +114,12 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda# https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.13.27-h3870b5a_0.conda#b868db6b48436bdbda71aa8576f4a44d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.conda#d47dee1856d9cb955b8076eeff304a5b https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_0.conda#fd6acbf37b40cbe919450fa58309fbe1 +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_1.conda#5ebd79c20c7ecf979f20e26fedc0a4fd https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 @@ -126,7 +127,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.co https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f +https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-1.8.4-h2f23424_0.conda#4bb92585a250e67d49b46c073d29f9dd https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 @@ -155,14 +157,15 @@ https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.1-pyhcf101f3_0.conda#9402ece5651f956de34cf0dc20dfc3a5 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 @@ -170,41 +173,39 @@ https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda# https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda#978d03388b62173b8e6f79162cf52b86 https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 +https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py311h49ec1c0_0.conda#2889f0c0b6a6d7a37bd64ec60f4cc210 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.0-h435f46f_0.conda#c7726f96aab024855ede05e0ca6e94a0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.8.13-hd4f18eb_5.conda#860fb8c0efec64a4a678eb2ea066ff65 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.3-py311h3778330_0.conda#620e453607709b49ffdc834da5887217 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py311h3778330_0.conda#6b1b19bdc407007d5e41079eab797ddc https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 -https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.3-h5192d8d_0.conda#48560c0be24568c3d53a944d2d496818 +https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.3-h5192d8d_1.conda#aefbd04e8e6cabe1d24eb8ffa6c48fd5 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 -https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 +https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 @@ -215,8 +216,7 @@ https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1 https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.20.2-h2a5cb19_18.conda#7313674073496cec938f73b71163bc31 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-20_linux64_openblas.conda#9932a1d4e9ecf2d35fb19475446e361e https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.11-h651a532_0.conda#d8d8894f8ced2c9be76dc9ad1ae531ce -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 @@ -224,14 +224,16 @@ https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#4 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h7b9373a_16.conda#54db1af780a69493a2e0675113a027f9 https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 -https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h3c3fd16_6.conda#5aab84b9d164509b5bbe3af660518606 +https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 +https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 -https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.0-py311h39c9aba_9_cpu.conda#c35fe329bcc51a1a3a254c990ba8f738 +https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-hc240232_7.conda#fa3bbe293d907990f3ca5b8b9d4b10f0 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b +https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af # pip pytz @ https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl#sha256=5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 # pip pandas @ https://files.pythonhosted.org/packages/fa/fe/c81ad3991f2c6aeacf01973f1d37b1dc76c0682f312f104741602a9557f1/pandas-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=e252a9e49b233ff96e2815c67c29702ac3a062098d80a170c506dff3470fd060 diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 5b33a9992518d..e9c19a640ce61 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -2,12 +2,11 @@ # platform: linux-64 # input_hash: 4a7e90be8a5287a384c3d5be14b2f52f18019e1dfa2c584c5325fc7d52f0a764 @EXPLICIT -https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 @@ -32,7 +31,7 @@ https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 @@ -71,13 +70,13 @@ https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_open https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 -https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb @@ -91,7 +90,7 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py311h2e04523_1.conda#a8105076864776eceae69d64d30e24d7 -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock index 8a304a1bfd9a9..0dd79cc08c351 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock @@ -16,7 +16,7 @@ https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.co https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_17.conda#18f0da832fb73029007218f0c56939f8 https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda#37eb311485d2d8b2c419449582046a42 -https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-2_gnu.conda#37e16618af5c4851a3f3d66dd0e11141 +https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda#1626967b574d1784b578b52eaeb071e7 https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda#1e610f2416b6acdd231c5f573d754a0f https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda#1077e9333c41ff0be8edd1a5ec0ddace https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_0.conda#3d3caf4ccc6415023640af4b1b33060a @@ -47,7 +47,7 @@ https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_h0adab6e_openblas https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda#450e3ae947fc46b60f1d8f8f318b40d4 https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda#ccd93cfa8e54fd9df4e83dbe55ff6e8c https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda#2cf0cf76cc15d360dfa2f17fd6cf9772 -https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.54-h7351971_0.conda#638ecb69e44b6a588afd5633e81f9e61 +https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.55-h7351971_0.conda#43f47a9151b9b8fc100aeefcf350d1a0 https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h3cfd58e_1.conda#07d73826fde28e7dbaec52a3297d7d26 https://conda.anaconda.org/conda-forge/win-64/openblas-0.3.30-pthreads_h4a7f399_4.conda#482e61f83248a880d180629bf8ed36b2 https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda#77eaf2336f3ae749e712f63e36b0f0a1 @@ -66,7 +66,7 @@ https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py311h275cad7_2.c https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a8eebe_openblas.conda#1db756824d3aec6a25599c7821cb3e24 https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_3.conda#06e385238457018ad1071179b67e39d1 https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda#6e7c5c5ab485057b5d07fd8188ba5c28 -https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.3-h0c9aed9_0.conda#c2d5b6b790ef21abac0b5331094ccb56 +https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.3-h0c9aed9_1.conda#72e868a2bc363563f7a4bda95113c717 https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hd232482_openblas.conda#78240c2b4322025a74e7e6edad247103 https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c @@ -77,16 +77,16 @@ https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda# https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py311h3485c13_0.conda#6e8d1faf5c0c08641c151e0fb79cb4db https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.0-py311h3485c13_1.conda#a30a6a70ab7754dbf0b06fe1a96af9cb +https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.1-py311h3485c13_0.conda#e6badeb53d9bc5cccebe46a62c5a7336 https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda#bc58fdbced45bb096364de0fba1637af -https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.3-py311h3f79411_0.conda#76bfad83b8bfa9a043aacab46ad72f56 +https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.4-py311h3f79411_0.conda#95b58888be94ced8132fce6dd0ff5d13 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/win-64/lcms2-2.18-hf2c6c5f_0.conda#b6c68d6b829b044cd17a41e0a8a23ca1 @@ -95,7 +95,7 @@ https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-5_hbb0e6ff_openb https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.2-py311h80b3fa1_1.conda#a824c6667179120c458beb9e9394932f https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h24db6dd_0.conda#5af852046226bb3cb15c7f61c2ac020a -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-5_ha590de0_openblas.conda#e19a49b16cf765708e6d8676a50f74e1 @@ -103,7 +103,7 @@ https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h275cad7_4.co https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py311h3f79411_0.conda#e5445b571c6e2919198c40c6db3d25c5 https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda#d69c21967f35eb2ce7f1f85d6b6022d3 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.0-py311h17b8079_0.conda#da30e4de83b61f936f73660eb4fa3cd5 +https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.1-py311h17b8079_0.conda#b17fe050184f2f7fd03e094a5fdc56ae https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.0-py311h9c22a71_1.conda#0d03c857517a5db3c1af5b553a528fac diff --git a/build_tools/azure/ubuntu_atlas_lock.txt b/build_tools/azure/ubuntu_atlas_lock.txt index b16443a77e699..cd7c3a7582e19 100644 --- a/build_tools/azure/ubuntu_atlas_lock.txt +++ b/build_tools/azure/ubuntu_atlas_lock.txt @@ -27,7 +27,7 @@ pluggy==1.6.0 # via pytest pygments==2.19.2 # via pytest -pyproject-metadata==0.10.0 +pyproject-metadata==0.11.0 # via meson-python pytest==9.0.2 # via diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index eed35ba699936..82bac4174f8c8 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -2,7 +2,6 @@ # platform: linux-64 # input_hash: 8ee751e2ee3835d0218c5e31f6b17221595b6def62eaad571cdb80dd568a67db @EXPLICIT -https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb @@ -17,7 +16,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda# https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_117.conda#97f8b7e451f960200c057ca83d92f9be https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 @@ -63,7 +62,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_17.conda#5edfb6baf1af52fa7c0a7072a42d1558 https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda#a587892d3c13b6621a6091be690dbca2 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 @@ -91,8 +90,8 @@ https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#43 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee -https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-ha09017c_8.conda#6e9bf4ce797d0216bd2a58298b6290b5 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_1.conda#5b5846bc2b23e07a1d61b89dcb67fcf0 +https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 @@ -103,7 +102,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda# https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_101.conda#83aa53cb3f5fc849851a84d777a60551 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 @@ -117,7 +116,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.0-h8d634f6_0.conda#65900b71509b2fd6c0a34a5dc1bd893a +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.1-h8d634f6_0.conda#cc109dc1a4bedbd4f66c15502cb5df5b https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 @@ -135,13 +134,13 @@ https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 -https://conda.anaconda.org/conda-forge/noarch/cloudpickle-3.1.2-pyhcf101f3_1.conda#61b8078a0905b12529abc622406cb62c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.14-py311hd8ed1ab_3.conda#85bce7761323f3b9b0854437afde219c https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2#961b3a227b437d82ad7054484cfa71b2 https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 +https://conda.anaconda.org/conda-forge/noarch/doit-0.37.0-pyhcf101f3_0.conda#37b3d4c558f2bb2b5378c43f4d6f1fb5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hb1e0a52_17.conda#f5c501fe2a016ed0103f7a89d2ac0412 @@ -169,9 +168,9 @@ https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda# https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.1-pyhcf101f3_0.conda#9402ece5651f956de34cf0dc20dfc3a5 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.24.1-pyhd8ed1ab_0.conda#7526d20621b53440b0aae45d4797847e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f @@ -189,8 +188,8 @@ https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h2315fbb_0.con https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda#3893f7b40738f9fe87510cb4468cdda5 -https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_0.conda#645026465469ecd4989188e1c4e24953 -https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 +https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda#28eb91468df04f655a57bcfbb35fc5c5 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda#18de09b20462742fe093ba39185d9bac @@ -201,7 +200,7 @@ https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.co https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda#019a7385be9af33791c989871317e1ed https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda#f6d7aa696c67756a650e91e15e88223c -https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 +https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py311h49ec1c0_0.conda#2889f0c0b6a6d7a37bd64ec60f4cc210 https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda#e7cb0f5745e4c5035a460248334af7eb https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda#6639b6b0d8b5a284f027a2003669aa65 https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda#2841eb5bfc75ce15e9a0054b98dcd64d @@ -216,14 +215,14 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0 https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_0.conda#ea5be9abc2939c8431893b4e123a2065 -https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_0.conda#b1a27250d70881943cca0dd6b4ba0956 +https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda#7c5ebdc286220e8021bf55e6384acd67 https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_17.conda#4e58f090f75b2941346da3685564e7a7 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_20.conda#6a7d74012f6ff0b58fb8fcb5286fa584 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_17.conda#ea4724804b89ddc81d16cabe3f4719b5 https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_17.conda#8f02f68c780b0a6eeba034af3ed1c00a https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 @@ -236,7 +235,7 @@ https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-hb80d175_3.conda#c39da2ad0e7dd600d1eb3146783b057d +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 @@ -244,14 +243,14 @@ https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py311h2e04523_1.conda#a8105076864776eceae69d64d30e24d7 https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.2-pyhd8ed1ab_0.conda#7702bcd70891dd0154d765a69e1afa94 -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.14-hd8ed1ab_3.conda#ba766ecdcff5b3f015498ad81f4d266e https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda#17b43cee5cc84969529d5d0b0309b2cb -https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.5.1-pyhcf101f3_0.conda#c0d0b883e97906f7524e2aac94be0e0d +https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda#f1acf5fdefa8300de697982bcb1761c9 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f @@ -261,20 +260,20 @@ https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py31 https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda#85c4f19f377424eafc4ed7911b291642 https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d -https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-h5f6438b_0.conda#08a03378bc5293c6f97637323802f480 +https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda#f11a319b9700b203aa14c295858782b6 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311h724c32c_4.conda#d04e508f5a03162c8bab4586a65d00bf -https://conda.anaconda.org/conda-forge/noarch/doit-0.36.0-pyhd8ed1ab_1.conda#18d4243b3d30352f9dea8e522f6ff4d1 https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_17.conda#dfcfcc0c20762eeb840771eda366940e -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h741da5e_20.conda#5f2bd1037991d4960438641a3ed3c5ae -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h3c3a7a4_20.conda#4b46597b58a2495ec48c215a40e42f0c +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h9837d23_1.conda#e30309a8776e0e969fa7092d7801641b https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda#7b8bace4943e0dc345fc45938826f2b8 +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.1-pyhcf101f3_0.conda#b8e1f542770b5f88b663012fc77f9628 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 @@ -292,7 +291,7 @@ https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_17.conda#eae https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.1-pyhcf101f3_0.conda#b8e1f542770b5f88b663012fc77f9628 +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.0-pyhcf101f3_0.conda#97624651e6fc9ca05effe0b4a80766e3 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 @@ -304,7 +303,6 @@ https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda#8368d58342d0825f0843dc6acdd0c483 -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.0-pyhcf101f3_0.conda#97624651e6fc9ca05effe0b4a80766e3 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 @@ -312,7 +310,7 @@ https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py311h2a99c40_0.conda#557f5d7ca735d89d706742bc19cd7e26 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e -https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyh29332c3_0.conda#f56000b36f09ab7533877e695e4e8cb0 +https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyhe01879c_0.conda#31e11c30bbee1682a55627f953c6725a https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.1-pyhbbac1ac_0.conda#d8f030e3730713c93a358fdb46f08281 https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py311he4c1a5a_0.conda#7287f5cca6b7f82571c1911a43e924b0 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index a3a7b99aca998..43dfd51122332 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -26,6 +26,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda# https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc +https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda#f9f81ea472684d75b9dd8d0b328cf655 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 @@ -56,6 +57,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8 https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d +https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 @@ -69,9 +71,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.54-h421ea60_0.conda#d361fa2a59e53b61c2675bfa073e5b7e +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_17.conda#5edfb6baf1af52fa7c0a7072a42d1558 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-h0c1763c_0.conda#f7d30045eccb83f2bb8053041f42db3c https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -96,36 +97,37 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.cond https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.0-hc31b594_0.conda#f3ac2d8b1b3ac0ba4e42050279ef6ce8 https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 -https://conda.anaconda.org/conda-forge/linux-64/icu-75.1-he02047a_0.conda#8b189310083baabfb622af68fd9d3ae3 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_17.conda#d7954bb54fc77e7952a78e5e0d134df5 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_0.conda#034bea55a4feef51c98e8449938e9cee -https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.1-ha09017c_8.conda#6e9bf4ce797d0216bd2a58298b6290b5 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_1.conda#5b5846bc2b23e07a1d61b89dcb67fcf0 +https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_3.conda#70d1de6301b58ed99fea01490a9802a3 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda#1d4c18d75c51ed9d00092a891a547a7d https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 -https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda#db038ce880f100acc74dba10302b5630 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_101.conda#83aa53cb3f5fc849851a84d777a60551 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_0.conda#fd6acbf37b40cbe919450fa58309fbe1 +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_1.conda#5ebd79c20c7ecf979f20e26fedc0a4fd https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda#22d5cc5fb45aab8ed3c00cde2938b825 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-ha9997c6_0.conda#e7733bc6785ec009e47a224a71917e84 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f +https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.0-h8d634f6_0.conda#65900b71509b2fd6c0a34a5dc1bd893a +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.1-h8d634f6_0.conda#cc109dc1a4bedbd4f66c15502cb5df5b https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 @@ -154,15 +156,17 @@ https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.b https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-h26afc86_0.conda#e512be7dc1f84966d50959e900ca121f +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.0-py311hf88fc01_0.conda#ce51a1258d127e1c72bad676235b9d6c -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.5.1-pyhcf101f3_0.conda#1bd2e65c8c7ef24f4639ae6e850dacc2 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.1-pyhcf101f3_0.conda#9402ece5651f956de34cf0dc20dfc3a5 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f @@ -172,7 +176,7 @@ https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda#3eeeeb9e4827ace8c0c1419c85d590ad -https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda#18de09b20462742fe093ba39185d9bac @@ -183,7 +187,7 @@ https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.0-py311h49ec1c0_1.conda#5e6d4026784e83c0a51c86ec428e8cc8 +https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py311h49ec1c0_0.conda#2889f0c0b6a6d7a37bd64ec60f4cc210 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 @@ -194,62 +198,58 @@ https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_20.conda#6a7d74012f6ff0b58fb8fcb5286fa584 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_17.conda#ea4724804b89ddc81d16cabe3f4719b5 -https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.3-h5192d8d_0.conda#48560c0be24568c3d53a944d2d496818 +https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.3-h5192d8d_1.conda#aefbd04e8e6cabe1d24eb8ffa6c48fd5 https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_17.conda#8f02f68c780b0a6eeba034af3ed1c00a https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.1-h5c52fec_2.conda#a8ac9a6342569d1714ae1b53ae2fcadb -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda#9f6a8664f1fe752f79473eeb9bf33a60 -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad +https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-h3394656_0.conda#09262e66b19567aff4f592fb53b28760 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_17.conda#dfcfcc0c20762eeb840771eda366940e -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h741da5e_20.conda#5f2bd1037991d4960438641a3ed3c5ae -https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.11-hc37bda9_0.conda#056d86cacf2b48c79c6a562a2486eb8c -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h3c3a7a4_20.conda#4b46597b58a2495ec48c215a40e42f0c +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 +https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_17.conda#329ef645bc2f75b4025cba573810e178 -https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.11-h651a532_0.conda#d8d8894f8ced2c9be76dc9ad1ae531ce https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_17.conda#eae8e3fb1f5eecb829dd7347d33ecacb -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.2.0-h15599e2_0.conda#b8690f53007e9b5ee2c2178dd4ac778c +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.4-pyhd8ed1ab_2.conda#bb0230917e2473c77d615104dbe8a49d -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad -https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed -https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h3c3fd16_6.conda#5aab84b9d164509b5bbe3af660518606 -https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 -https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 +https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 +https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed +https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e +https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba @@ -260,10 +260,12 @@ https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.con https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.8.0-py311h9f3472d_0.conda#17334e5c12abdf2db6b25bd4187cd3e4 +https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-hc240232_7.conda#fa3bbe293d907990f3ca5b8b9d4b10f0 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b +https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.1.28-pyhd8ed1ab_0.conda#e8d6529858171ac4babb28c334306c0d https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index eb01745ae02d0..355dd9fe7c0be 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -10,7 +10,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.c https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_17.conda#0ad9074c91b35dbf8b58bc68a9f9bda0 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-2_gnu.tar.bz2#6168d71addc746e8f2b8d57dfd2edcea +https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda#468fd3bb9e1f671d36c2cbc677e56f1d https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda#cf105bce884e4ef8c8ccdca9fe6695e7 @@ -53,7 +53,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321 https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_17.conda#7fa4f07979f7aff0938e5664f43f7053 https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.3.0-h5ad3122_1.conda#c11818b31f7c054ce220041b2459aacb https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.54-h1abf092_0.conda#45b47396febdf400c55fe129cfc398aa +https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda#be4088903b94ea297975689b3c3aeb27 https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_17.conda#beb8c015b02b7a1c2eea6d7a9847f8f5 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda#b4df5d7d4b63579d081fd3a4cf99740e @@ -71,7 +71,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.12.3-h185addb_0.co https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.21.3-h50a48e9_0.conda#29c10432a2ca1472b53f299ffb2ffa37 https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda#35b2ae7fadf364b8e5fb8185aaeb80e5 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.1-hdae7a39_0.conda#9c2f56b6e011c6d8010ff43b796aab2f -https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.3-hf53f6bf_0.conda#f226b9798c6c176d2a94eea1350b3b6b +https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.3-hf53f6bf_1.conda#9590055a5bc67692dbc2f6176df96a38 https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.2-h10b116e_0.conda#4e3ba0d5d192f99217b85f07a0761e64 https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d @@ -81,7 +81,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-0.4.1-hca56bd8_2.c https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-keysyms-0.4.1-h5c728e9_0.conda#57ca8564599ddf8b633c4ea6afee6f3a https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-renderutil-0.3.10-h5c728e9_0.conda#7beeda4223c5484ef72d89fb66b7e8c1 https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-wm-0.4.2-h5c728e9_0.conda#f14dcda6894722e421da2b7dcffb0b78 -https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.12-hca56bd8_0.conda#3df132f0048b9639bc091ef22937c111 +https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.13-h63a1b12_0.conda#22dd10425ef181e80e130db50675d615 https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-hd651790_1.conda#5c933384d588a06cd8dac78ca2864aab https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.28-h6c5dea3_0.conda#b6d06b46e791add99cc39fbbc34530d5 https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda#a4b6b82427d15f0489cef0df2d82f926 @@ -116,18 +116,18 @@ https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h30c48ee_0.conda#48f31a61be512ec1929f4b4a9cedf4bd https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.0-py311h8e17b9e_0.conda#c771bf4d9191e68f1a09c573a9de897f +https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.1-py311h8e17b9e_0.conda#2f611dceeef334e4d3448944bf714277 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-81.0.0-pyh332efcf_0.conda#d629a398d7bf872f9ed7b27ab959de15 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.3-py311hb9158a3_0.conda#e3afe76a49a1a9f85e0c5cd42a408e68 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/linux-aarch64/unicodedata2-17.0.0-py311h19352d5_1.conda#4a55814831e0ec9be84ccef6aed798c1 +https://conda.anaconda.org/conda-forge/linux-aarch64/unicodedata2-17.0.1-py311h19352d5_0.conda#22df73a2e312d88d56f6986e0a287edb https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-cursor-0.1.6-he30d5cf_0.conda#8b70063c86f7f9a0b045e78d2d9971f7 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcomposite-0.4.7-he30d5cf_0.conda#9c639c1abdbfe6759c5beb2c1db4bc13 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcursor-1.2.3-h86ecc28_0.conda#f2054759c2203d12d0007005e1f1296d @@ -135,7 +135,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdamage-1.1.6-h86ec https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda#eeee3bdb31c6acde2b81ad1b8c287087 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda#1f64c613f0b8d67e9fb0e165d898fb6b https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.7-he30d5cf_0.conda#b15ca02584678f38df6e114c32f93959 -https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.3-py311h2dad8b0_0.conda#752a19eb90f17bfd279ce86563579501 +https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.4-py311h2dad8b0_0.conda#6fcc144f2f5c3537297288e61d09e8f2 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.15.0-h8dda3cd_1.conda#112b71b6af28b47c624bcbeefeea685b https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.1-py311h164a683_0.conda#b59452fef1470e7e5c34a7c5deefe853 @@ -143,10 +143,10 @@ https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#61 https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_3.conda#4ba7653ca09e74e8968120c6aea4bfb1 https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.8-default_h94a09a5_3.conda#d294b96fc51b22e382e5220937c738f4 https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-5_hb558247_openblas.conda#8046d5ae90150f00c8b40455d9b2e180 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.1-hf8816c8_3.conda#e0d7a6cbc0b8a6d05002cb9bd061a4af +https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.2-hf8816c8_0.conda#c54b5b1eb1b2c0f41781293fd4b530b3 https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.341.0-h8b8848b_0.conda#06bb91a87fb97ea09398d2e121e00c39 https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.2-py311h669026d_1.conda#6b411688a868a37d95abfb99ebc8b88e -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 From 29cb1589e444a80b44fdd6911404a96a0e1e49ea Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 16 Feb 2026 05:47:46 -0500 Subject: [PATCH 215/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33245) Co-authored-by: Lock file bot --- ...pylatest_free_threaded_linux-64_conda.lock | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index c57a46ae4cc6a..cce577798d031 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -2,58 +2,57 @@ # platform: linux-64 # input_hash: 7f842ff628171ca53fc79777d1a71909440a7c3af69979c721418352753a843a @EXPLICIT -https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2#d7c89558ba9fa0495403155b64376d81 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#3251796e09870c978e0f69fa05e38fb6 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda#26c46f90d0e727e95c6c9498a33a09f3 -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2#73aaf86a425cc6e73fcf236a5a46396d -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda#6d0363467e6ed84f11435eb309f2ff06 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_16.conda#39183d4e0c05609fd65f130633194e37 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda#68f68355000ec3f1d6f26ea13e8f525f +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_16.conda#40d9b534410403c821ff64f00d0adc22 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.2-hedf47ba_0.conda#894811fefb5d282448a1685193feffaf -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda#3ec0aa5037d39b06554109a01e6fb0c6 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-he1279bd_1_cp314t.conda#9c01f87c0150322d53879878aa478c0c +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-he1279bd_1_cp314t.conda#19b5d632d02f56f9f95ce07dc1e086b5 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.2-py314hd8ed1ab_1.conda#437c7e7fabfe4274ae0e652298a013c6 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_1.conda#83eaa6b45bd9d99a26d673a4d50138b3 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.conda#cc2fcbfdf0628b5ad05b319866187bbc https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0-pyh145f28c_0.conda#f08a17c938eb6bc1b928bd8cdd37e20f +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/setuptools-80.10.2-pyh332efcf_0.conda#7b446fcbb6779ee479debb4fd7453e6c +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.1-py314hd4f4903_0.conda#66c5cfbc84524e3eb553503b80874087 -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.10.0-pyhd8ed1ab_0.conda#d9998bf52ced268eb83749ad65a2e061 -https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.2-h92d6c8b_1.conda#b1c229bbdd39ba06315b15c0ed7f3946 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314hd4f4903_1.conda#f626ab4f8adec5ea04a13558822e92f9 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 +https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.3-h92d6c8b_1.conda#817a41a5e7c547bda68fd981fb72b1ec https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py314h529d2a9_1.conda#2548681b651d007d01368d98b3f8536e From 1725ec01d1bdca988ade34a6cd52ac53ff4195fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Mon, 16 Feb 2026 16:43:33 +0100 Subject: [PATCH 216/462] TST Work around free-threaded warnings race condition (#33293) Co-authored-by: Olivier Grisel --- sklearn/preprocessing/tests/test_encoders.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sklearn/preprocessing/tests/test_encoders.py b/sklearn/preprocessing/tests/test_encoders.py index d7632ab2f09d1..636055c599a4e 100644 --- a/sklearn/preprocessing/tests/test_encoders.py +++ b/sklearn/preprocessing/tests/test_encoders.py @@ -2411,10 +2411,13 @@ def test_onehotencoder_handle_unknown_warn_maps_to_infrequent(): min_frequency=2, drop="first", ) + encoder_infreq.fit(train_data) - result_infreq = encoder_infreq.transform(test_data) warning_match = "unknown categories will be encoded as the infrequent category" + # The warning is raised because `drop is not None`. + with pytest.warns(UserWarning, match=warning_match): + result_infreq = encoder_infreq.transform(test_data) with pytest.warns(UserWarning, match=warning_match): result_warn = encoder_warn.transform(test_data) From a462c92910cb0b594d5ad3a8df801b2fae859cf9 Mon Sep 17 00:00:00 2001 From: Shruti Nath <51656807+snath-xoc@users.noreply.github.com> Date: Mon, 16 Feb 2026 19:38:05 +0200 Subject: [PATCH 217/462] Deprecate use of `probability=True` in SVC and NuSVC (#32050) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivier Grisel Co-authored-by: Loïc Estève Co-authored-by: Jérémie du Boisberranger --- .../sklearn.svm/32050.api.rst | 5 ++ sklearn/ensemble/tests/test_bagging.py | 17 ++++-- .../ensemble/tests/test_weight_boosting.py | 10 ++-- sklearn/metrics/tests/test_classification.py | 5 +- sklearn/model_selection/tests/test_search.py | 2 +- sklearn/semi_supervised/_self_training.py | 6 +- .../tests/test_self_training.py | 26 +++++---- sklearn/svm/_base.py | 34 ++++++++--- sklearn/svm/_classes.py | 14 ++++- sklearn/svm/tests/test_sparse.py | 23 ++++---- sklearn/svm/tests/test_svm.py | 58 +++++++------------ sklearn/tests/test_base.py | 1 + sklearn/tests/test_multiclass.py | 16 ++--- sklearn/tests/test_pipeline.py | 12 ++-- 14 files changed, 128 insertions(+), 101 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.svm/32050.api.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.svm/32050.api.rst b/doc/whats_new/upcoming_changes/sklearn.svm/32050.api.rst new file mode 100644 index 0000000000000..d00a2e603f1ae --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.svm/32050.api.rst @@ -0,0 +1,5 @@ +- The `probability` parameter of :class:`sklearn.svm.SVC` and :class:`sklearn.svm.NuSVC` + is deprecated due to not being thread-safe and will be removed in 1.11. Use + :class:`sklearn.calibration.CalibratedClassifierCV` with the respective estimator and + `ensemble=False` instead. + By :user:`Shruti Nath `. diff --git a/sklearn/ensemble/tests/test_bagging.py b/sklearn/ensemble/tests/test_bagging.py index b57b294ee0366..69656d2ee3f01 100644 --- a/sklearn/ensemble/tests/test_bagging.py +++ b/sklearn/ensemble/tests/test_bagging.py @@ -14,6 +14,7 @@ from sklearn import config_context from sklearn.base import BaseEstimator +from sklearn.calibration import CalibratedClassifierCV from sklearn.datasets import load_diabetes, load_iris, make_hastie_10_2 from sklearn.dummy import DummyClassifier, DummyRegressor from sklearn.ensemble import ( @@ -125,9 +126,8 @@ def test_classification(): ) def test_sparse_classification(sparse_container, params, method): # Check classification for various parameter settings on sparse input. - - class CustomSVC(SVC): - """SVC variant that records the nature of the training set""" + class CustomClassifier(LogisticRegression): + """LogisticRegression variant that records the nature of the training set""" def fit(self, X, y): super().fit(X, y) @@ -141,17 +141,19 @@ def fit(self, X, y): X_train_sparse = sparse_container(X_train) X_test_sparse = sparse_container(X_test) + # Trained on sparse format sparse_classifier = BaggingClassifier( - estimator=CustomSVC(kernel="linear", decision_function_shape="ovr"), + estimator=CustomClassifier(), random_state=1, **params, ).fit(X_train_sparse, y_train) + print(sparse_classifier, method) sparse_results = getattr(sparse_classifier, method)(X_test_sparse) # Trained on dense format dense_classifier = BaggingClassifier( - estimator=CustomSVC(kernel="linear", decision_function_shape="ovr"), + estimator=CustomClassifier(), random_state=1, **params, ).fit(X_train, y_train) @@ -371,7 +373,10 @@ def test_oob_score_classification(): iris.data, iris.target, random_state=rng ) - for estimator in [DecisionTreeClassifier(), SVC()]: + for estimator in [ + DecisionTreeClassifier(), + CalibratedClassifierCV(SVC(), ensemble=False), + ]: clf = BaggingClassifier( estimator=estimator, n_estimators=100, diff --git a/sklearn/ensemble/tests/test_weight_boosting.py b/sklearn/ensemble/tests/test_weight_boosting.py index 2a430cbf9aec9..618560f0971c0 100644 --- a/sklearn/ensemble/tests/test_weight_boosting.py +++ b/sklearn/ensemble/tests/test_weight_boosting.py @@ -9,7 +9,7 @@ from sklearn.base import BaseEstimator, clone from sklearn.dummy import DummyClassifier, DummyRegressor from sklearn.ensemble import AdaBoostClassifier, AdaBoostRegressor -from sklearn.linear_model import LinearRegression +from sklearn.linear_model import LinearRegression, LogisticRegression from sklearn.model_selection import GridSearchCV, train_test_split from sklearn.svm import SVC, SVR from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor @@ -283,8 +283,8 @@ def test_sample_weights_infinite(): def test_sparse_classification(sparse_container, expected_internal_type): # Check classification with sparse input. - class CustomSVC(SVC): - """SVC variant that records the nature of the training set.""" + class CustomProbabilisticClassifier(LogisticRegression): + """LogisticRegression variant that records the nature of the training set.""" def fit(self, X, y, sample_weight=None): """Modification on fit caries data type for later verification.""" @@ -305,13 +305,13 @@ def fit(self, X, y, sample_weight=None): # Trained on sparse format sparse_classifier = AdaBoostClassifier( - estimator=CustomSVC(probability=True), + estimator=CustomProbabilisticClassifier(), random_state=1, ).fit(X_train_sparse, y_train) # Trained on dense format dense_classifier = AdaBoostClassifier( - estimator=CustomSVC(probability=True), + estimator=CustomProbabilisticClassifier(), random_state=1, ).fit(X_train, y_train) diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index 9a42b8a5acaf4..2b039a2d391dc 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -11,6 +11,7 @@ from sklearn import datasets, svm from sklearn.base import config_context +from sklearn.calibration import CalibratedClassifierCV from sklearn.datasets import make_multilabel_classification from sklearn.exceptions import UndefinedMetricWarning from sklearn.metrics import ( @@ -100,7 +101,9 @@ def make_prediction(dataset=None, binary=False): X = np.c_[X, rng.randn(n_samples, 200 * n_features)] # run classifier, get class probabilities and label predictions - clf = svm.SVC(kernel="linear", probability=True, random_state=0) + clf = CalibratedClassifierCV( + svm.SVC(kernel="linear", random_state=0), ensemble=False, cv=3 + ) y_pred_proba = clf.fit(X[:half], y[:half]).predict_proba(X[half:]) if binary: diff --git a/sklearn/model_selection/tests/test_search.py b/sklearn/model_selection/tests/test_search.py index 2678e1aa68d75..d652a7fdce1f3 100644 --- a/sklearn/model_selection/tests/test_search.py +++ b/sklearn/model_selection/tests/test_search.py @@ -1671,7 +1671,7 @@ def test_predict_proba_disabled(): # Test predict_proba when disabled on estimator. X = np.arange(20).reshape(5, -1) y = [0, 0, 1, 1, 1] - clf = SVC(probability=False) + clf = SVC() gs = GridSearchCV(clf, {}, cv=2).fit(X, y) assert not hasattr(gs, "predict_proba") diff --git a/sklearn/semi_supervised/_self_training.py b/sklearn/semi_supervised/_self_training.py index 4b69e3defd405..4bdfc9a181dc5 100644 --- a/sklearn/semi_supervised/_self_training.py +++ b/sklearn/semi_supervised/_self_training.py @@ -137,13 +137,13 @@ class SelfTrainingClassifier(ClassifierMixin, MetaEstimatorMixin, BaseEstimator) >>> import numpy as np >>> from sklearn import datasets >>> from sklearn.semi_supervised import SelfTrainingClassifier - >>> from sklearn.svm import SVC + >>> from sklearn.linear_model import LogisticRegression >>> rng = np.random.RandomState(42) >>> iris = datasets.load_iris() >>> random_unlabeled_points = rng.rand(iris.target.shape[0]) < 0.3 >>> iris.target[random_unlabeled_points] = -1 - >>> svc = SVC(probability=True, gamma="auto") - >>> self_training_model = SelfTrainingClassifier(svc) + >>> clf = LogisticRegression() + >>> self_training_model = SelfTrainingClassifier(clf) >>> self_training_model.fit(iris.data, iris.target) SelfTrainingClassifier(...) """ diff --git a/sklearn/semi_supervised/tests/test_self_training.py b/sklearn/semi_supervised/tests/test_self_training.py index 26b6feff6ab2a..3004f49bda48d 100644 --- a/sklearn/semi_supervised/tests/test_self_training.py +++ b/sklearn/semi_supervised/tests/test_self_training.py @@ -5,6 +5,7 @@ from numpy.testing import assert_array_equal from sklearn.base import clone +from sklearn.calibration import CalibratedClassifierCV from sklearn.datasets import load_iris, make_blobs from sklearn.ensemble import StackingClassifier from sklearn.exceptions import NotFittedError @@ -116,7 +117,7 @@ def test_k_best(): def test_sanity_classification(): - estimator = SVC(gamma="scale", probability=True) + estimator = CalibratedClassifierCV(SVC(gamma="scale"), ensemble=False) estimator.fit(X_train[n_labeled_samples:], y_train[n_labeled_samples:]) st = SelfTrainingClassifier(estimator) @@ -142,7 +143,10 @@ def test_none_iter(): @pytest.mark.parametrize( "estimator", - [KNeighborsClassifier(), SVC(gamma="scale", probability=True, random_state=0)], + [ + KNeighborsClassifier(), + CalibratedClassifierCV(SVC(gamma="scale", random_state=0), ensemble=False), + ], ) @pytest.mark.parametrize("y", [y_train_missing_labels, y_train_missing_strings]) def test_zero_iterations(estimator, y): @@ -205,8 +209,8 @@ def test_no_unlabeled(): def test_early_stopping(): - svc = SVC(gamma="scale", probability=True) - st = SelfTrainingClassifier(svc) + lr = LogisticRegression() + st = SelfTrainingClassifier(lr) X_train_easy = [[1], [0], [1], [0.5]] y_train_easy = [1, 0, -1, -1] # X = [[0.5]] cannot be predicted on with a high confidence, so training @@ -294,10 +298,10 @@ def test_estimator_meta_estimator(): estimator = StackingClassifier( estimators=[ - ("svc_1", SVC(probability=True)), - ("svc_2", SVC(probability=True)), + ("clf_1", LogisticRegression()), + ("clf_2", LogisticRegression()), ], - final_estimator=SVC(probability=True), + final_estimator=LogisticRegression(), cv=2, ) @@ -308,10 +312,10 @@ def test_estimator_meta_estimator(): estimator = StackingClassifier( estimators=[ - ("svc_1", SVC(probability=False)), - ("svc_2", SVC(probability=False)), + ("svc_1", SVC()), + ("svc_2", SVC()), ], - final_estimator=SVC(probability=False), + final_estimator=SVC(), cv=2, ) @@ -332,7 +336,7 @@ def test_self_training_estimator_attribute_error(): # `SVC` with `probability=False` does not implement 'predict_proba' that # is required internally in `fit` of `SelfTrainingClassifier`. We expect # an AttributeError to be raised. - estimator = SVC(probability=False, gamma="scale") + estimator = SVC(gamma="scale") self_training = SelfTrainingClassifier(estimator) with pytest.raises(AttributeError, match="has no attribute 'predict_proba'"): diff --git a/sklearn/svm/_base.py b/sklearn/svm/_base.py index 693967182ec81..b4b0ccbb854a3 100644 --- a/sklearn/svm/_base.py +++ b/sklearn/svm/_base.py @@ -23,7 +23,7 @@ column_or_1d, compute_class_weight, ) -from sklearn.utils._param_validation import Interval, StrOptions +from sklearn.utils._param_validation import Hidden, Interval, StrOptions from sklearn.utils.extmath import safe_sparse_dot from sklearn.utils.metaestimators import available_if from sklearn.utils.multiclass import ( @@ -98,7 +98,7 @@ class BaseLibSVM(BaseEstimator, metaclass=ABCMeta): "nu": [Interval(Real, 0.0, 1.0, closed="right")], "epsilon": [Interval(Real, 0.0, None, closed="left")], "shrinking": ["boolean"], - "probability": ["boolean"], + "probability": ["boolean", Hidden(StrOptions({"deprecated"}))], "cache_size": [Interval(Real, 0, None, closed="neither")], "class_weight": [StrOptions({"balanced"}), dict, None], "verbose": ["verbose"], @@ -219,6 +219,24 @@ def fit(self, X, y, sample_weight=None): ) solver_type = LIBSVM_IMPL.index(self._impl) + # TODO(1.11): remove probability + self._effective_probability = self.probability + if self._impl in ["c_svc", "nu_svc"]: + if self._impl == "nu_scv": + est_dep = "NuSVC" + else: + est_dep = "SVC" + if self.probability != "deprecated": + warnings.warn( + f"The `probability` parameter was deprecated in 1.9 and " + f"will be removed in version 1.11. " + f"Use `CalibratedClassifierCV({est_dep}(), ensemble=False)` " + f"instead of `{est_dep}(probability=True)`", + FutureWarning, + ) + else: + self._effective_probability = False + # input validation n_samples = _num_samples(X) if solver_type != 2 and n_samples != y.shape[0]: @@ -350,7 +368,7 @@ def _dense_fit(self, X, y, sample_weight, solver_type, kernel, random_seed): kernel=kernel, C=self.C, nu=self.nu, - probability=self.probability, + probability=self._effective_probability, degree=self.degree, shrinking=self.shrinking, tol=self.tol, @@ -401,7 +419,7 @@ def _sparse_fit(self, X, y, sample_weight, solver_type, kernel, random_seed): self.cache_size, self.epsilon, int(self.shrinking), - int(self.probability), + int(self._effective_probability), self.max_iter, random_seed, ) @@ -509,7 +527,7 @@ def _sparse_predict(self, X): self.nu, self.epsilon, self.shrinking, - self.probability, + self._effective_probability, self._n_support, self._probA, self._probB, @@ -609,7 +627,7 @@ def _sparse_decision_function(self, X): self.nu, self.epsilon, self.shrinking, - self.probability, + self._effective_probability, self._n_support, self._probA, self._probB, @@ -835,7 +853,7 @@ def predict(self, X): # probabilities are not available depending on a setting, introduce two # estimators. def _check_proba(self): - if not self.probability: + if self.probability == "deprecated" or not self.probability: raise AttributeError( "predict_proba is not available when probability=False" ) @@ -966,7 +984,7 @@ def _sparse_predict_proba(self, X): self.nu, self.epsilon, self.shrinking, - self.probability, + self._effective_probability, self._n_support, self._probA, self._probB, diff --git a/sklearn/svm/_classes.py b/sklearn/svm/_classes.py index aa216fcc1b0f0..bf1fdac34e95d 100644 --- a/sklearn/svm/_classes.py +++ b/sklearn/svm/_classes.py @@ -690,6 +690,11 @@ class SVC(BaseSVC): 5-fold cross-validation, and `predict_proba` may be inconsistent with `predict`. Read more in the :ref:`User Guide `. + ..deprecated:: 1.9 + The `probability` parameter is deprecated and will be removed in 1.11. + Use `CalibratedClassifierCV(SVC(), ensemble=False)` instead of + `SVC(probability=True)`. + tol : float, default=1e-3 Tolerance for stopping criterion. @@ -867,7 +872,7 @@ def __init__( gamma="scale", coef0=0.0, shrinking=True, - probability=False, + probability="deprecated", tol=1e-3, cache_size=200, class_weight=None, @@ -951,6 +956,11 @@ class NuSVC(BaseSVC): 5-fold cross-validation, and `predict_proba` may be inconsistent with `predict`. Read more in the :ref:`User Guide `. + ..deprecated:: 1.9 + The `probability` parameter is deprecated and will be removed in version 1.11. + Use `CalibratedClassifierCV(NuSVC(), ensemble=False)` + instead of `NuSVC(probability=True)`. + tol : float, default=1e-3 Tolerance for stopping criterion. @@ -1130,7 +1140,7 @@ def __init__( gamma="scale", coef0=0.0, shrinking=True, - probability=False, + probability="deprecated", tol=1e-3, cache_size=200, class_weight=None, diff --git a/sklearn/svm/tests/test_sparse.py b/sklearn/svm/tests/test_sparse.py index 7b9012ded8aba..60aa74e344bb8 100644 --- a/sklearn/svm/tests/test_sparse.py +++ b/sklearn/svm/tests/test_sparse.py @@ -94,6 +94,7 @@ def check_svm_model_equal(dense_svm, X_train, y_train, X_test): # XXX: probability=True is not thread-safe: # https://github.com/scikit-learn/scikit-learn/issues/31885 +# TODO(1.11): remove probability=True and adapt check_svm_model_equal accordingly. @pytest.mark.thread_unsafe @skip_if_32bit @pytest.mark.parametrize( @@ -107,6 +108,7 @@ def check_svm_model_equal(dense_svm, X_train, y_train, X_test): ) @pytest.mark.parametrize("kernel", ["linear", "poly", "rbf", "sigmoid"]) @pytest.mark.parametrize("sparse_container", CSR_CONTAINERS + LIL_CONTAINERS) +@pytest.mark.filterwarnings("ignore::FutureWarning") def test_svc(X_train, y_train, X_test, kernel, sparse_container): """Check that sparse SVC gives the same result as SVC.""" X_train = sparse_container(X_train) @@ -122,6 +124,8 @@ def test_svc(X_train, y_train, X_test, kernel, sparse_container): @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) +# TODO(1.11): remove probability=True and calls to predict_proba. +@pytest.mark.filterwarnings("ignore::FutureWarning") def test_unsorted_indices(csr_container): # test that the result with sorted and unsorted indices in csr is the same # we use a subset of digits as iris, blobs or make_classification didn't @@ -458,6 +462,8 @@ def test_sparse_realdata(csr_container): @pytest.mark.parametrize("lil_container", LIL_CONTAINERS) +# TODO(1.11): remove probability=True and calls to predict_proba. +@pytest.mark.filterwarnings("ignore::FutureWarning") def test_sparse_svc_clone_with_callable_kernel(lil_container): # Test that the "dense_fit" is called even though we use sparse input # meaning that everything works fine. @@ -479,9 +485,7 @@ def test_sparse_svc_clone_with_callable_kernel(lil_container): @pytest.mark.parametrize("lil_container", LIL_CONTAINERS) def test_timeout(lil_container): - sp = svm.SVC( - C=1, kernel=lambda x, y: x @ y.T, probability=True, random_state=0, max_iter=1 - ) + sp = svm.SVC(C=1, kernel=lambda x, y: x @ y.T, random_state=0, max_iter=1) warning_msg = ( r"Solver terminated early \(max_iter=1\). Consider pre-processing " r"your data with StandardScaler or MinMaxScaler." @@ -490,14 +494,11 @@ def test_timeout(lil_container): sp.fit(lil_container(X), Y) -# XXX: probability=True is not thread-safe: -# https://github.com/scikit-learn/scikit-learn/issues/31885 -@pytest.mark.thread_unsafe -def test_consistent_proba(): - a = svm.SVC(probability=True, max_iter=1, random_state=0) +def test_consistent_decision_function(): + a = svm.SVC(max_iter=1, random_state=0) with ignore_warnings(category=ConvergenceWarning): - proba_1 = a.fit(X, Y).predict_proba(X) - a = svm.SVC(probability=True, max_iter=1, random_state=0) + proba_1 = a.fit(X, Y).decision_function(X) + a = svm.SVC(max_iter=1, random_state=0) with ignore_warnings(category=ConvergenceWarning): - proba_2 = a.fit(X, Y).predict_proba(X) + proba_2 = a.fit(X, Y).decision_function(X) assert_allclose(proba_1, proba_2) diff --git a/sklearn/svm/tests/test_svm.py b/sklearn/svm/tests/test_svm.py index 6bb5d5b00d641..da5b6efb6a8c9 100644 --- a/sklearn/svm/tests/test_svm.py +++ b/sklearn/svm/tests/test_svm.py @@ -66,6 +66,7 @@ def test_libsvm_parameters(): # XXX: this test is thread-unsafe because it uses _libsvm.cross_validation: # https://github.com/scikit-learn/scikit-learn/issues/31885 +# TODO: investigate why assertion on L148 fails. @pytest.mark.thread_unsafe def test_libsvm_iris(global_random_seed): # Check consistency on dataset iris. @@ -378,7 +379,9 @@ def test_tweak_params(): # XXX: this test is thread-unsafe because it uses probability=True: # https://github.com/scikit-learn/scikit-learn/issues/31885 +# TODO(1.11): remove this test entirely @pytest.mark.thread_unsafe +@pytest.mark.filterwarnings("ignore::FutureWarning") def test_probability(global_random_seed): # Predict probabilities using SVC # This uses cross validation, so we use a slightly bigger testing set. @@ -768,18 +771,6 @@ def test_svc_nonfinite_params(global_random_seed): clf.fit(X, y) -def test_unicode_kernel(global_random_seed): - # Test that a unicode kernel name does not cause a TypeError - iris = get_iris_dataset(global_random_seed) - - clf = svm.SVC(kernel="linear", probability=True) - clf.fit(X, Y) - clf.predict_proba(T) - _libsvm.cross_validation( - iris.data, iris.target.astype(np.float64), 5, kernel="linear", random_seed=0 - ) - - @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) def test_sparse_precomputed(csr_container): clf = svm.SVC(kernel="precomputed") @@ -1056,9 +1047,6 @@ def test_linearsvc_verbose(): os.dup2(stdout, 1) # restore original stdout -# XXX: this test is thread-unsafe because it uses probability=True: -# https://github.com/scikit-learn/scikit-learn/issues/31885 -@pytest.mark.thread_unsafe def test_svc_clone_with_callable_kernel(): iris = get_iris_dataset(42) @@ -1066,7 +1054,6 @@ def test_svc_clone_with_callable_kernel(): # as with built-in linear kernel svm_callable = svm.SVC( kernel=lambda x, y: np.dot(x, y.T), - probability=True, random_state=0, decision_function_shape="ovr", ) @@ -1076,21 +1063,16 @@ def test_svc_clone_with_callable_kernel(): svm_builtin = svm.SVC( kernel="linear", - probability=True, random_state=0, decision_function_shape="ovr", ) + svm_builtin.fit(iris.data, iris.target) assert_array_almost_equal(svm_cloned.dual_coef_, svm_builtin.dual_coef_) assert_array_almost_equal(svm_cloned.intercept_, svm_builtin.intercept_) assert_array_equal(svm_cloned.predict(iris.data), svm_builtin.predict(iris.data)) - assert_array_almost_equal( - svm_cloned.predict_proba(iris.data), - svm_builtin.predict_proba(iris.data), - decimal=4, - ) assert_array_almost_equal( svm_cloned.decision_function(iris.data), svm_builtin.decision_function(iris.data), @@ -1103,13 +1085,9 @@ def test_svc_bad_kernel(): svc.fit(X, Y) -# XXX: this test is thread-unsafe because it uses probability=True: -# https://github.com/scikit-learn/scikit-learn/issues/31885 -@pytest.mark.thread_unsafe def test_libsvm_convergence_warnings(global_random_seed): a = svm.SVC( kernel=lambda x, y: np.dot(x, y.T), - probability=True, random_state=global_random_seed, max_iter=2, ) @@ -1134,16 +1112,11 @@ def test_unfitted(): clf.predict(X) -# ignore convergence warnings from max_iter=1 -# XXX: this test is thread-unsafe because it uses probability=True: -# https://github.com/scikit-learn/scikit-learn/issues/31885 -@pytest.mark.thread_unsafe -@pytest.mark.filterwarnings("ignore::sklearn.exceptions.ConvergenceWarning") -def test_consistent_proba(global_random_seed): - a = svm.SVC(probability=True, max_iter=1, random_state=global_random_seed) - proba_1 = a.fit(X, Y).predict_proba(X) - a = svm.SVC(probability=True, max_iter=1, random_state=global_random_seed) - proba_2 = a.fit(X, Y).predict_proba(X) +def test_consistent_decision_function(global_random_seed): + a = svm.SVC(max_iter=1, random_state=global_random_seed) + proba_1 = a.fit(X, Y).decision_function(X) + a = svm.SVC(max_iter=1, random_state=global_random_seed) + proba_2 = a.fit(X, Y).decision_function(X) assert_array_almost_equal(proba_1, proba_2) @@ -1194,6 +1167,8 @@ def test_lsvc_intercept_scaling_zero(): assert lsvc.intercept_ == 0.0 +# TODO(1.11): remove test entirely. +@pytest.mark.filterwarnings("ignore::FutureWarning") def test_hasattr_predict_proba(global_random_seed): iris = get_iris_dataset(global_random_seed) @@ -1538,3 +1513,14 @@ def test_svm_with_infinite_C(Estimator, make_dataset, C_inf, global_random_seed) estimator_C_large = Estimator(C=1e10).fit(X, y) assert_allclose(estimator_C_large.predict(X), estimator_C_inf.predict(X)) + + +@pytest.mark.parametrize( + "Estimator, name", + [(svm.SVC, "SVC"), (svm.NuSVC, "NuSVC")], +) +@pytest.mark.parametrize("probability", [True, False]) +def test_probability_raises_futurewarning(Estimator, name, probability): + X, y = make_classification() + with pytest.warns(FutureWarning, match="probability.+parameter.+deprecated"): + Estimator(probability=probability).fit(X, y) diff --git a/sklearn/tests/test_base.py b/sklearn/tests/test_base.py index 66830a3d57b21..f5ff8c25f7356 100644 --- a/sklearn/tests/test_base.py +++ b/sklearn/tests/test_base.py @@ -237,6 +237,7 @@ def test_clone_class_rather_than_instance(): clone(MyEstimator) +# TODO (1.11): remove svc test for predict_proba after it is deprecated def test_conditional_attrs_not_in_dir(): # Test that __dir__ includes only relevant attributes. #28558 diff --git a/sklearn/tests/test_multiclass.py b/sklearn/tests/test_multiclass.py index 66bbb039606f5..50c47857324b7 100644 --- a/sklearn/tests/test_multiclass.py +++ b/sklearn/tests/test_multiclass.py @@ -327,7 +327,10 @@ def conduct_test(base_clf, test_predict_proba=False): ): conduct_test(base_clf) - for base_clf in (MultinomialNB(), SVC(probability=True), LogisticRegression()): + for base_clf in ( + MultinomialNB(), + LogisticRegression(), + ): conduct_test(base_clf, test_predict_proba=True) @@ -404,21 +407,12 @@ def test_ovr_multilabel_predict_proba(): assert not hasattr(decision_only, "predict_proba") # Estimator with predict_proba disabled, depending on parameters. - decision_only = OneVsRestClassifier(svm.SVC(probability=False)) + decision_only = OneVsRestClassifier(svm.SVC()) assert not hasattr(decision_only, "predict_proba") decision_only.fit(X_train, Y_train) assert not hasattr(decision_only, "predict_proba") assert hasattr(decision_only, "decision_function") - # Estimator which can get predict_proba enabled after fitting - gs = GridSearchCV( - svm.SVC(probability=False), param_grid={"probability": [True]} - ) - proba_after_fit = OneVsRestClassifier(gs) - assert not hasattr(proba_after_fit, "predict_proba") - proba_after_fit.fit(X_train, Y_train) - assert hasattr(proba_after_fit, "predict_proba") - Y_pred = clf.predict(X_test) Y_proba = clf.predict_proba(X_test) diff --git a/sklearn/tests/test_pipeline.py b/sklearn/tests/test_pipeline.py index 26cb4a49f1c0b..4c0268fa8851e 100644 --- a/sklearn/tests/test_pipeline.py +++ b/sklearn/tests/test_pipeline.py @@ -418,14 +418,14 @@ def test_pipeline_raise_set_params_error(): pipe.set_params(cls__invalid_param="nope") -def test_pipeline_methods_pca_svm(): +def test_pipeline_methods_pca_classifier(): # Test the various methods of the pipeline (pca + svm). X = iris.data y = iris.target - # Test with PCA + SVC - clf = SVC(probability=True, random_state=0) + # Test with PCA + LogisticRegression + clf = LogisticRegression() pca = PCA(svd_solver="full", n_components="mle", whiten=True) - pipe = Pipeline([("pca", pca), ("svc", clf)]) + pipe = Pipeline([("pca", pca), ("classifier", clf)]) pipe.fit(X, y) pipe.predict(X) pipe.predict_proba(X) @@ -466,7 +466,7 @@ def test_score_samples_on_pipeline_without_score_samples(): assert inner_msg in str(exec_info.value.__cause__) -def test_pipeline_methods_preprocessing_svm(): +def test_pipeline_methods_preprocessing_classifier(): # Test the various methods of the pipeline (preprocessing + svm). X = iris.data y = iris.target @@ -474,7 +474,7 @@ def test_pipeline_methods_preprocessing_svm(): n_classes = len(np.unique(y)) scaler = StandardScaler() pca = PCA(n_components=2, svd_solver="randomized", whiten=True) - clf = SVC(probability=True, random_state=0, decision_function_shape="ovr") + clf = LogisticRegression() for preprocessing in [scaler, pca]: pipe = Pipeline([("preprocess", preprocessing), ("svc", clf)]) From 174de74e29881db0b8abc00b13804b640213149b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= Date: Tue, 17 Feb 2026 00:51:53 +0100 Subject: [PATCH 218/462] MNT Removed unused param in `_preprocess_data` (#33279) Co-authored-by: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> --- sklearn/linear_model/_base.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sklearn/linear_model/_base.py b/sklearn/linear_model/_base.py index 0c881a27427e1..a4878203ce883 100644 --- a/sklearn/linear_model/_base.py +++ b/sklearn/linear_model/_base.py @@ -116,7 +116,6 @@ def _preprocess_data( *, fit_intercept, copy=True, - copy_y=True, sample_weight=None, check_input=True, rescale_with_sw=True, @@ -155,8 +154,7 @@ def _preprocess_data( inplace. If input X is dense, then X_out is centered. y_out : {ndarray, sparse matrix} of shape (n_samples,) or (n_samples, n_targets) - Centered version of y. Possibly performed inplace on input y depending - on the copy_y parameter. + Centered copy of y. X_offset : ndarray of shape (n_features,) The mean per column of input X. y_offset : float or ndarray of shape (n_features,) @@ -174,9 +172,9 @@ def _preprocess_data( X = check_array( X, copy=copy, accept_sparse=["csr", "csc"], dtype=supported_float_dtypes(xp) ) - y = check_array(y, dtype=X.dtype, copy=copy_y, ensure_2d=False) + y = check_array(y, dtype=X.dtype, copy=True, ensure_2d=False) else: - y = xp.astype(y, X.dtype, copy=copy_y) + y = xp.astype(y, X.dtype) if copy: if X_is_sparse: X = X.copy() From b94868a73ff5d5b26213173c2aa2cb75899f1723 Mon Sep 17 00:00:00 2001 From: Virgil Chan Date: Mon, 16 Feb 2026 16:38:10 -0800 Subject: [PATCH 219/462] DOC Update california housing dataset URL (#33296) --- sklearn/datasets/_california_housing.py | 2 +- sklearn/datasets/descr/california_housing.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sklearn/datasets/_california_housing.py b/sklearn/datasets/_california_housing.py index ed2fbde9583c4..0cfbfe3f6adb8 100644 --- a/sklearn/datasets/_california_housing.py +++ b/sklearn/datasets/_california_housing.py @@ -43,7 +43,7 @@ from sklearn.utils._param_validation import Interval, validate_params # The original data can be found at: -# https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.tgz +# https://lib.stat.cmu.edu/datasets/houses.zip ARCHIVE = RemoteFileMetadata( filename="cal_housing.tgz", url="https://ndownloader.figshare.com/files/5976036", diff --git a/sklearn/datasets/descr/california_housing.rst b/sklearn/datasets/descr/california_housing.rst index 47a25b9ba272a..599b0b69723ec 100644 --- a/sklearn/datasets/descr/california_housing.rst +++ b/sklearn/datasets/descr/california_housing.rst @@ -21,8 +21,8 @@ California Housing dataset :Missing Attribute Values: None -This dataset was obtained from the StatLib repository. -https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html +This dataset was obtained from the StatLib: +https://lib.stat.cmu.edu/datasets/houses.zip The target variable is the median house value for California districts, expressed in hundreds of thousands of dollars ($100,000). From dce0550faf6131b94bc4cc9a2b768ce477e410bb Mon Sep 17 00:00:00 2001 From: DhyeyTeraiya Date: Tue, 17 Feb 2026 15:52:23 +0530 Subject: [PATCH 220/462] DOC: Fix typos in loss.py (#33297) --- sklearn/_loss/loss.py | 6 +++--- sklearn/metrics/tests/test_classification.py | 8 ++++---- sklearn/metrics/tests/test_common.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sklearn/_loss/loss.py b/sklearn/_loss/loss.py index 3e46fc7602de5..bd72bc0c9559c 100644 --- a/sklearn/_loss/loss.py +++ b/sklearn/_loss/loss.py @@ -114,7 +114,7 @@ class BaseLoss: Indicates whether or not loss function is differentiable in raw_prediction everywhere. need_update_leaves_values : bool - Indicates whether decision trees in gradient boosting need to uptade + Indicates whether decision trees in gradient boosting need to update leave values after having been fit to the (negative) gradients. approx_hessian : bool Indicates whether the hessian is approximated or exact. If, @@ -1352,7 +1352,7 @@ def _log1pexp(raw_prediction, raw_prediction_exp, xp): class HalfBinomialLossArrayAPI(ArrayAPILossMixin, HalfBinomialLoss): - """A version of the the HalfBinomialLoss that is compatible with + """A version of the HalfBinomialLoss that is compatible with the array API. """ @@ -1456,7 +1456,7 @@ def _compute_gradient( class HalfMultinomialLossArrayAPI(ArrayAPILossMixin, HalfMultinomialLoss): - """A version of the the HalfMultinomialLoss that is compatible with + """A version of the HalfMultinomialLoss that is compatible with the array API. Parameters diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index 2b039a2d391dc..cd4c63d063eac 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -921,7 +921,7 @@ def test_cohen_kappa_undefined(test_case, replace_undefined_by): """Test that cohen_kappa_score handles divisions by 0 correctly by returning the `replace_undefined_by` param. (The first test case covers the first possible location in the function for an occurrence of a division by zero, the last three - test cases cover a zero division in the the second possible location in the + test cases cover a zero division in the second possible location in the function.""" y1, y2, labels, weights = test_case @@ -3711,9 +3711,9 @@ def test_confusion_matrix_array_api(array_namespace, device, _): def test_probabilistic_metrics_array_api( prob_metric, str_y_true, use_sample_weight, array_namespace, device_, dtype_name ): - """Test that :func:`brier_score_loss`, :func:`log_loss`, func:`d2_brier_score` + """Test that :func:`brier_score_loss`, :func:`log_loss`, :func:`d2_brier_score` and :func:`d2_log_loss_score` work correctly with the array API for binary - and mutli-class inputs. + and multi-class inputs. """ xp = _array_api_for_tests(array_namespace, device_) sample_weight = np.array([1, 2, 3, 1]) if use_sample_weight else None @@ -3778,7 +3778,7 @@ def test_probabilistic_metrics_array_api( def test_probabilistic_metrics_multilabel_array_api( prob_metric, use_sample_weight, array_namespace, device_, dtype_name ): - """Test that :func:`brier_score_loss`, :func:`log_loss`, func:`d2_brier_score` + """Test that :func:`brier_score_loss`, :func:`log_loss`, :func:`d2_brier_score` and :func:`d2_log_loss_score` work correctly with the array API for multi-label inputs. """ diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index d0406c507cf9b..7c41acb9570c8 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -216,7 +216,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): """ The dimensions of precision-recall pairs and the threshold array as returned by the precision_recall_curve do not match. See - func:`sklearn.metrics.precision_recall_curve` + :func:`sklearn.metrics.precision_recall_curve` This prevents implicit conversion of return value triple to a higher dimensional np.array of dtype('float64') (it will be of dtype('object) From 7e2a5414af9f0948169d59ff326dce3333749198 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Tue, 17 Feb 2026 14:37:32 +0100 Subject: [PATCH 221/462] ENH/FIX Array API in LinearModelLoss and newton solver (#33277) --- sklearn/linear_model/_glm/_newton_solver.py | 8 +++++++- sklearn/linear_model/_linear_loss.py | 14 ++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/sklearn/linear_model/_glm/_newton_solver.py b/sklearn/linear_model/_glm/_newton_solver.py index 61d75ffbcfd50..537be0b5ae098 100644 --- a/sklearn/linear_model/_glm/_newton_solver.py +++ b/sklearn/linear_model/_glm/_newton_solver.py @@ -179,6 +179,8 @@ def fallback_lbfgs_solve(self, X, y, sample_weight): - self.coef - self.converged """ + coef_shape = self.coef.shape + self.coef = self.coef.ravel(order="F") # scipy minimize expects 1d arrays max_iter = self.max_iter - self.iteration opt_res = scipy.optimize.minimize( self.linear_loss.loss_gradient, @@ -197,6 +199,8 @@ def fallback_lbfgs_solve(self, X, y, sample_weight): self.iteration += _check_optimize_result("lbfgs", opt_res, max_iter=max_iter) self.coef = opt_res.x self.converged = opt_res.status == 0 + if len(coef_shape) > 1: + self.coef = self.coef.reshape(coef_shape, order="F") def line_search(self, X, y, sample_weight): """Backtracking line search. @@ -212,7 +216,9 @@ def line_search(self, X, y, sample_weight): """ # line search parameters beta, sigma = 0.5, 0.00048828125 # 1/2, 1/2**11 - eps = 16 * np.finfo(self.loss_value.dtype).eps + # Remember: dtype follows X, also the one of self.loss_value. For Array API + # support, self.loss_value might be float instead of np.floatXX. + eps = 16 * np.finfo(X.dtype).eps t = 1 # step size # gradient_times_newton = self.gradient @ self.coef_newton diff --git a/sklearn/linear_model/_linear_loss.py b/sklearn/linear_model/_linear_loss.py index 6194245505d13..a53c8b89ec58b 100644 --- a/sklearn/linear_model/_linear_loss.py +++ b/sklearn/linear_model/_linear_loss.py @@ -223,7 +223,7 @@ def weight_intercept_raw(self, coef, X): def l2_penalty(self, weights, l2_reg_strength): """Compute L2 penalty term l2_reg_strength/2 *||w||_2^2.""" norm2_w = weights @ weights if weights.ndim == 1 else squared_norm(weights) - return 0.5 * l2_reg_strength * norm2_w + return float(0.5 * l2_reg_strength * norm2_w) def loss( self, @@ -264,6 +264,7 @@ def loss( loss : float Weighted average of losses per sample, plus penalty. """ + n_samples = X.shape[0] if raw_prediction is None: weights, intercept, raw_prediction = self.weight_intercept_raw(coef, X) else: @@ -272,12 +273,17 @@ def loss( loss = self.base_loss.loss( y_true=y, raw_prediction=raw_prediction, - sample_weight=None, + sample_weight=sample_weight, n_threads=n_threads, ) - loss = np.average(loss, weights=sample_weight) + xp, _ = get_namespace(X, y, sample_weight) + sw_sum = n_samples if sample_weight is None else xp.sum(sample_weight) + loss = float(xp.sum(loss) / sw_sum) + + if l2_reg_strength > 0: + loss += self.l2_penalty(weights, l2_reg_strength) - return loss + self.l2_penalty(weights, l2_reg_strength) + return loss def loss_gradient( self, From 3c8d10e670e72e3a96c753a1c943ec090b06dbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= Date: Tue, 17 Feb 2026 14:41:43 +0100 Subject: [PATCH 222/462] DOC Remove deprecated SVC(probability=True) from examples (#33299) --- examples/model_selection/plot_confusion_matrix.py | 7 ++++--- examples/model_selection/plot_roc_crossval.py | 12 ++++++------ .../plot_release_highlights_0_22_0.py | 6 +++--- .../plot_release_highlights_0_24_0.py | 6 +++--- .../plot_self_training_varying_threshold.py | 3 ++- .../plot_semi_supervised_versus_svm_iris.py | 3 ++- 6 files changed, 20 insertions(+), 17 deletions(-) diff --git a/examples/model_selection/plot_confusion_matrix.py b/examples/model_selection/plot_confusion_matrix.py index d9df933e30b53..bf675e7fa3035 100644 --- a/examples/model_selection/plot_confusion_matrix.py +++ b/examples/model_selection/plot_confusion_matrix.py @@ -30,7 +30,8 @@ import matplotlib.pyplot as plt import numpy as np -from sklearn import datasets, svm +from sklearn import datasets +from sklearn.linear_model import LogisticRegression from sklearn.metrics import ConfusionMatrixDisplay from sklearn.model_selection import train_test_split @@ -45,7 +46,7 @@ # Run classifier, using a model that is too regularized (C too low) to see # the impact on the results -classifier = svm.SVC(kernel="linear", C=0.01).fit(X_train, y_train) +classifier = LogisticRegression(C=0.01).fit(X_train, y_train) np.set_printoptions(precision=2) @@ -101,7 +102,7 @@ X, y, test_size=0.3, random_state=42 ) -classifier = svm.SVC(kernel="linear", C=0.01, probability=True) +classifier = LogisticRegression(C=0.01) classifier.fit(X_train, y_train) y_score = classifier.predict_proba(X_test)[:, 1] diff --git a/examples/model_selection/plot_roc_crossval.py b/examples/model_selection/plot_roc_crossval.py index 3c5c3fc9119b7..b927346b34148 100644 --- a/examples/model_selection/plot_roc_crossval.py +++ b/examples/model_selection/plot_roc_crossval.py @@ -63,20 +63,20 @@ # ------------------------------- # # Here we run :func:`~sklearn.model_selection.cross_validate` on a -# :class:`~sklearn.svm.SVC` classifier, then use the computed cross-validation results -# to plot the ROC curves fold-wise. Notice that the baseline to define the chance -# level (dashed ROC curve) is a classifier that would always predict the most -# frequent class. +# :class:`~sklearn.linear_model.LogisticRegression` classifier, then use the computed +# cross-validation results to plot the ROC curves fold-wise. Notice that the baseline +# to define the chance level (dashed ROC curve) is a classifier that would always +# predict the most frequent class. import matplotlib.pyplot as plt -from sklearn import svm +from sklearn.linear_model import LogisticRegression from sklearn.metrics import RocCurveDisplay, auc from sklearn.model_selection import StratifiedKFold, cross_validate n_splits = 6 cv = StratifiedKFold(n_splits=n_splits) -classifier = svm.SVC(kernel="linear", probability=True, random_state=random_state) +classifier = LogisticRegression(random_state=random_state).fit(X, y) cv_results = cross_validate( classifier, X, y, cv=cv, return_estimator=True, return_indices=True ) diff --git a/examples/release_highlights/plot_release_highlights_0_22_0.py b/examples/release_highlights/plot_release_highlights_0_22_0.py index 8d5648188f0fe..8a920b585edc6 100644 --- a/examples/release_highlights/plot_release_highlights_0_22_0.py +++ b/examples/release_highlights/plot_release_highlights_0_22_0.py @@ -288,9 +288,9 @@ def test_sklearn_compatible_estimator(estimator, check): from sklearn.datasets import make_classification +from sklearn.linear_model import LogisticRegression from sklearn.metrics import roc_auc_score -from sklearn.svm import SVC X, y = make_classification(n_classes=4, n_informative=16) -clf = SVC(decision_function_shape="ovo", probability=True).fit(X, y) -print(roc_auc_score(y, clf.predict_proba(X), multi_class="ovo")) +clf = LogisticRegression().fit(X, y) +print(roc_auc_score(y, clf.predict_proba(X), multi_class="ovr")) diff --git a/examples/release_highlights/plot_release_highlights_0_24_0.py b/examples/release_highlights/plot_release_highlights_0_24_0.py index d09250ba6ff64..1f64ac42cd478 100644 --- a/examples/release_highlights/plot_release_highlights_0_24_0.py +++ b/examples/release_highlights/plot_release_highlights_0_24_0.py @@ -121,15 +121,15 @@ import numpy as np from sklearn import datasets +from sklearn.linear_model import LogisticRegression from sklearn.semi_supervised import SelfTrainingClassifier -from sklearn.svm import SVC rng = np.random.RandomState(42) iris = datasets.load_iris() random_unlabeled_points = rng.rand(iris.target.shape[0]) < 0.3 iris.target[random_unlabeled_points] = -1 -svc = SVC(probability=True, gamma="auto") -self_training_model = SelfTrainingClassifier(svc) +clf = LogisticRegression() +self_training_model = SelfTrainingClassifier(clf) self_training_model.fit(iris.data, iris.target) ############################################################################## diff --git a/examples/semi_supervised/plot_self_training_varying_threshold.py b/examples/semi_supervised/plot_self_training_varying_threshold.py index bbdaeb634f570..bd64f4aaca5a5 100644 --- a/examples/semi_supervised/plot_self_training_varying_threshold.py +++ b/examples/semi_supervised/plot_self_training_varying_threshold.py @@ -36,6 +36,7 @@ import numpy as np from sklearn import datasets +from sklearn.calibration import CalibratedClassifierCV from sklearn.metrics import accuracy_score from sklearn.model_selection import StratifiedKFold from sklearn.semi_supervised import SelfTrainingClassifier @@ -50,7 +51,7 @@ y[50:] = -1 total_samples = y.shape[0] -base_classifier = SVC(probability=True, gamma=0.001, random_state=42) +base_classifier = CalibratedClassifierCV(SVC(gamma=0.001, random_state=42)) x_values = np.arange(0.4, 1.05, 0.05) x_values = np.append(x_values, 0.99999) diff --git a/examples/semi_supervised/plot_semi_supervised_versus_svm_iris.py b/examples/semi_supervised/plot_semi_supervised_versus_svm_iris.py index 333b80ee88812..b511af9716a46 100644 --- a/examples/semi_supervised/plot_semi_supervised_versus_svm_iris.py +++ b/examples/semi_supervised/plot_semi_supervised_versus_svm_iris.py @@ -33,6 +33,7 @@ import matplotlib.pyplot as plt import numpy as np +from sklearn.calibration import CalibratedClassifierCV from sklearn.datasets import load_iris from sklearn.inspection import DecisionBoundaryDisplay from sklearn.semi_supervised import LabelSpreading, SelfTrainingClassifier @@ -53,7 +54,7 @@ ls30 = (LabelSpreading().fit(X, y_30), y_30, "LabelSpreading with 30% labeled data") ls100 = (LabelSpreading().fit(X, y), y, "LabelSpreading with 100% labeled data") -base_classifier = SVC(gamma=0.5, probability=True, random_state=42) +base_classifier = CalibratedClassifierCV(SVC(gamma=0.5, random_state=42)) st10 = ( SelfTrainingClassifier(base_classifier).fit(X, y_10), y_10, From 2380b8a901eece092130910798a27a6f049fb175 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= Date: Wed, 18 Feb 2026 09:04:05 +0100 Subject: [PATCH 223/462] MNT Clean up dead code related to deprecated classes (#33306) --- sklearn/base.py | 8 +++----- sklearn/gaussian_process/kernels.py | 3 +-- sklearn/model_selection/_split.py | 4 +--- sklearn/utils/_pprint.py | 3 +-- sklearn/utils/deprecation.py | 1 - sklearn/utils/estimator_checks.py | 9 +-------- 6 files changed, 7 insertions(+), 21 deletions(-) diff --git a/sklearn/base.py b/sklearn/base.py index 2854334450006..f8be470dd5f03 100644 --- a/sklearn/base.py +++ b/sklearn/base.py @@ -209,9 +209,8 @@ def __dir__(self): @classmethod def _get_param_names(cls): """Get parameter names for the estimator""" - # fetch the constructor or the original constructor before - # deprecation wrapping if any - init = getattr(cls.__init__, "deprecated_original", cls.__init__) + # fetch the constructor + init = cls.__init__ if init is object.__init__: # No explicit constructor to introspect return [] @@ -285,8 +284,7 @@ def _get_params_html(self, deep=True, doc_link=""): """ out = self.get_params(deep=deep) - init_func = getattr(self.__init__, "deprecated_original", self.__init__) - init_default_params = inspect.signature(init_func).parameters + init_default_params = inspect.signature(self.__init__).parameters init_default_params = { name: param.default for name, param in init_default_params.items() } diff --git a/sklearn/gaussian_process/kernels.py b/sklearn/gaussian_process/kernels.py index 8b4a16cb76adf..c6cf14518753a 100644 --- a/sklearn/gaussian_process/kernels.py +++ b/sklearn/gaussian_process/kernels.py @@ -194,8 +194,7 @@ def get_params(self, deep=True): # introspect the constructor arguments to find the model parameters # to represent cls = self.__class__ - init = getattr(cls.__init__, "deprecated_original", cls.__init__) - init_sign = signature(init) + init_sign = signature(cls.__init__) args, varargs = [], [] for parameter in init_sign.parameters.values(): if parameter.kind != parameter.VAR_KEYWORD and parameter.name != "self": diff --git a/sklearn/model_selection/_split.py b/sklearn/model_selection/_split.py index 0719fbd2b11f1..4a63e262b1af8 100644 --- a/sklearn/model_selection/_split.py +++ b/sklearn/model_selection/_split.py @@ -3026,9 +3026,7 @@ def _pprint(params, offset=0, printer=repr): def _build_repr(self): - # XXX This is copied from BaseEstimator's get_params - cls = self.__class__ - init = getattr(cls.__init__, "deprecated_original", cls.__init__) + init = self.__class__.__init__ # Ignore varargs, kw and default values and pop self init_signature = signature(init) # Consider the constructor parameters excluding 'self' diff --git a/sklearn/utils/_pprint.py b/sklearn/utils/_pprint.py index 936c93d6c7765..3d8067c4a6857 100644 --- a/sklearn/utils/_pprint.py +++ b/sklearn/utils/_pprint.py @@ -93,8 +93,7 @@ def _changed_params(estimator): estimator with non-default values.""" params = estimator.get_params(deep=False) - init_func = getattr(estimator.__init__, "deprecated_original", estimator.__init__) - init_params = inspect.signature(init_func).parameters + init_params = inspect.signature(estimator.__init__).parameters init_params = {name: param.default for name, param in init_params.items()} def has_changed(k, v): diff --git a/sklearn/utils/deprecation.py b/sklearn/utils/deprecation.py index b727ac172fbdf..26f3c3034a60b 100644 --- a/sklearn/utils/deprecation.py +++ b/sklearn/utils/deprecation.py @@ -77,7 +77,6 @@ def wrapped(cls, *args, **kwargs): cls.__new__ = wrapped wrapped.__name__ = "__new__" - wrapped.deprecated_original = new # Restore the original signature, see PEP 362. cls.__signature__ = sig diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index 6502de34bd345..215728b2ebcc8 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -1778,9 +1778,6 @@ def _is_public_parameter(attr): @ignore_warnings(category=FutureWarning) def check_dont_overwrite_parameters(name, estimator_orig): # check that fit method only changes or sets private attributes - if hasattr(estimator_orig.__init__, "deprecated_original"): - # to not check deprecated classes - return estimator = clone(estimator_orig) rnd = np.random.RandomState(0) X = 3 * rnd.uniform(size=(20, 3)) @@ -3709,9 +3706,6 @@ def check_no_attributes_set_in_init(name, estimator_orig): f"Estimator {name} should store all parameters as an attribute during init." ) - if hasattr(type(estimator).__init__, "deprecated_original"): - return - init_params = _get_args(type(estimator).__init__) parents_init_params = [ param @@ -3880,8 +3874,7 @@ def check_parameters_default_constructible(name, estimator_orig): # We get the default parameters from init and then # compare these against the actual values of the attributes. - # this comes from getattr. Gets rid of deprecation decorator. - init = getattr(estimator.__init__, "deprecated_original", estimator.__init__) + init = estimator.__init__ try: From 77aa5816faed5a756a772268a968c03ad45e3add Mon Sep 17 00:00:00 2001 From: cui Date: Wed, 18 Feb 2026 21:51:09 +0800 Subject: [PATCH 224/462] chore: remove redundant . (#33309) --- sklearn/utils/sparsefuncs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/utils/sparsefuncs.py b/sklearn/utils/sparsefuncs.py index 1b0f1bb3a389d..e7c00f9391dae 100644 --- a/sklearn/utils/sparsefuncs.py +++ b/sklearn/utils/sparsefuncs.py @@ -783,7 +783,7 @@ def sparse_matmul_to_dense(A, B, out=None): if out.shape[0] != n1 or out.shape[1] != n3: raise ValueError("Shape of out must be ({n1}, {n3}), got {out.shape}.") if out.dtype != A.data.dtype: - raise ValueError("Dtype of out must match that of input A..") + raise ValueError("Dtype of out must match that of input A.") transpose_out = False if A.format == "csc": From 4229556a8d416c49810ca893d2d8364060c29f26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= Date: Wed, 18 Feb 2026 15:22:30 +0100 Subject: [PATCH 225/462] MNT Small refactor of common functions used by HTML displays (#33301) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger --- sklearn/utils/_repr_html/common.py | 82 +++++++++++++++++++ sklearn/utils/_repr_html/params.py | 59 ++----------- sklearn/utils/_repr_html/tests/test_params.py | 16 ++-- 3 files changed, 96 insertions(+), 61 deletions(-) create mode 100644 sklearn/utils/_repr_html/common.py diff --git a/sklearn/utils/_repr_html/common.py b/sklearn/utils/_repr_html/common.py new file mode 100644 index 0000000000000..1c1f610778e9d --- /dev/null +++ b/sklearn/utils/_repr_html/common.py @@ -0,0 +1,82 @@ +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +import html +import inspect +import re +from functools import lru_cache +from urllib.parse import quote + +from sklearn.externals._numpydoc import docscrape + + +def generate_link_to_param_doc(estimator_class, param_name, doc_link): + """URL to the relevant section of the docstring using a Text Fragment + + https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Fragment/Text_fragments + """ + docstring = estimator_class.__doc__ + + m = re.search(f"{param_name} : (.+)\\n", docstring or "") + + if m is None: + # No match found in the docstring, return None to indicate that we + # cannot link. + return None + + # Extract the whole line of the type information, up to the line break as + # disambiguation suffix to build the fragment + param_type = m.group(1) + text_fragment = f"{quote(param_name)},-{quote(param_type)}" + + return f"{doc_link}#:~:text={text_fragment}" + + +@lru_cache +def scrape_estimator_docstring(docstring): + return docscrape.NumpyDocString(docstring) + + +def get_docstring(estimator_class, section_name, item): + """Extract and format docstring information for a specific item. + + Parses the estimator's docstring to retrieve documentation for a + specific parameter or attribute, formatting it as HTML-escaped text. + + Parameters + ---------- + estimator_class : type + The estimator class whose docstring will be parsed. + + section_name : str + The numpydoc section to search in (e.g., "Parameters", "Attributes"). + + item : str + The name of the parameter or attribute to retrieve documentation for. + + Returns + ------- + item_description : str or None + HTML-formatted docstring to be used as a tooltip. Returns None if the + estimator has no docstring or if the item is not found in the + specified section. + """ + estimator_class_docs = inspect.getdoc(estimator_class) + if estimator_class_docs and ( + structured_docstring := scrape_estimator_docstring(estimator_class_docs) + ): + docstring_map = { + item_docstring.name: item_docstring + for item_docstring in structured_docstring[section_name] + } + else: + docstring_map = {} + if item_numpydoc := docstring_map.get(item, None): + item_description = ( + f"{html.escape(item_numpydoc.name)}: " + f"{html.escape(item_numpydoc.type)}

" + f"{'
'.join(html.escape(line) for line in item_numpydoc.desc)}" + ) + else: + item_description = None + return item_description diff --git a/sklearn/utils/_repr_html/params.py b/sklearn/utils/_repr_html/params.py index 3bf858f5aef11..213a9feeb2029 100644 --- a/sklearn/utils/_repr_html/params.py +++ b/sklearn/utils/_repr_html/params.py @@ -2,37 +2,14 @@ # SPDX-License-Identifier: BSD-3-Clause import html -import inspect -import re import reprlib from collections import UserDict -from functools import lru_cache -from urllib.parse import quote -from sklearn.externals._numpydoc import docscrape from sklearn.utils._repr_html.base import ReprHTMLMixin - - -def _generate_link_to_param_doc(estimator_class, param_name, doc_link): - """URL to the relevant section of the docstring using a Text Fragment - - https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Fragment/Text_fragments - """ - docstring = estimator_class.__doc__ - - m = re.search(f"{param_name} : (.+)\\n", docstring or "") - - if m is None: - # No match found in the docstring, return None to indicate that we - # cannot link. - return None - - # Extract the whole line of the type information, up to the line break as - # disambiguation suffix to build the fragment - param_type = m.group(1) - text_fragment = f"{quote(param_name)},-{quote(param_type)}" - - return f"{doc_link}#:~:text={text_fragment}" +from sklearn.utils._repr_html.common import ( + generate_link_to_param_doc, + get_docstring, +) def _read_params(name, value, non_default_params): @@ -51,11 +28,6 @@ def _read_params(name, value, non_default_params): return {"param_type": param_type, "param_name": name, "param_value": cleaned_value} -@lru_cache -def _scrape_estimator_docstring(docstring): - return docscrape.NumpyDocString(docstring) - - def _params_html_repr(params): """Generate HTML representation of estimator parameters. @@ -97,28 +69,13 @@ def _params_html_repr(params): {param_description}
""" - estimator_class_docs = inspect.getdoc(params.estimator_class) - if estimator_class_docs and ( - structured_docstring := _scrape_estimator_docstring(estimator_class_docs) - ): - param_map = { - param_docstring.name: param_docstring - for param_docstring in structured_docstring["Parameters"] - } - else: - param_map = {} + rows = [] for row in params: param = _read_params(row, params[row], params.non_default) - link = _generate_link_to_param_doc(params.estimator_class, row, params.doc_link) - if param_numpydoc := param_map.get(row, None): - param_description = ( - f"{html.escape(param_numpydoc.name)}: " - f"{html.escape(param_numpydoc.type)}

" - f"{'
'.join(html.escape(line) for line in param_numpydoc.desc)}" - ) - else: - param_description = None + link = generate_link_to_param_doc(params.estimator_class, row, params.doc_link) + + param_description = get_docstring(params.estimator_class, "Parameters", row) if params.doc_link and link and param_description: # Create clickable parameter name with documentation link diff --git a/sklearn/utils/_repr_html/tests/test_params.py b/sklearn/utils/_repr_html/tests/test_params.py index ef41c4c725638..8310da7a2cdb1 100644 --- a/sklearn/utils/_repr_html/tests/test_params.py +++ b/sklearn/utils/_repr_html/tests/test_params.py @@ -3,12 +3,8 @@ import pytest from sklearn import config_context -from sklearn.utils._repr_html.params import ( - ParamsDict, - _generate_link_to_param_doc, - _params_html_repr, - _read_params, -) +from sklearn.utils._repr_html.common import generate_link_to_param_doc +from sklearn.utils._repr_html.params import ParamsDict, _params_html_repr, _read_params def test_params_dict_content(): @@ -182,10 +178,10 @@ class MockEstimator: """ doc_link = "mock_module.MockEstimator.html" - url = _generate_link_to_param_doc(MockEstimator, "alpha", doc_link) + url = generate_link_to_param_doc(MockEstimator, "alpha", doc_link) assert url == "mock_module.MockEstimator.html#:~:text=alpha,-float" - url = _generate_link_to_param_doc(MockEstimator, "beta", doc_link) + url = generate_link_to_param_doc(MockEstimator, "beta", doc_link) assert url == "mock_module.MockEstimator.html#:~:text=beta,-int" @@ -202,7 +198,7 @@ class MockEstimator: """ doc_link = "mock_module.MockEstimator.html" - url = _generate_link_to_param_doc(MockEstimator, "gamma", doc_link) + url = generate_link_to_param_doc(MockEstimator, "gamma", doc_link) assert url is None @@ -214,5 +210,5 @@ class MockEstimator: pass doc_link = "mock_module.MockEstimator.html" - url = _generate_link_to_param_doc(MockEstimator, "alpha", doc_link) + url = generate_link_to_param_doc(MockEstimator, "alpha", doc_link) assert url is None From febdaad3c6f963c419a0a49e9d492f19d23af997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Wed, 18 Feb 2026 16:43:20 +0100 Subject: [PATCH 226/462] CI Test only 20 random seeds in nightly scheduled run (#33310) --- .github/workflows/unit-tests.yml | 4 ++-- build_tools/azure/test_script.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 741d346438af1..c49dbfc92aad4 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -256,7 +256,7 @@ jobs: - name: Set random seed for nightly/manual runs if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' - run: echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 100))" >> $GITHUB_ENV + run: echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 20))" >> $GITHUB_ENV shell: bash - name: Run tests @@ -366,7 +366,7 @@ jobs: - name: Set random seed for nightly/manual runs if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' - run: echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 100))" >> $GITHUB_ENV + run: echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 20))" >> $GITHUB_ENV - name: Start container # Environment variable are passed when starting the container rather diff --git a/build_tools/azure/test_script.sh b/build_tools/azure/test_script.sh index 5e48f6701ea87..3f47c1455932f 100755 --- a/build_tools/azure/test_script.sh +++ b/build_tools/azure/test_script.sh @@ -11,7 +11,7 @@ if [[ "$BUILD_REASON" == "Schedule" ]]; then # Enable global random seed randomization to discover seed-sensitive tests # only on nightly builds. # https://scikit-learn.org/stable/computing/parallelism.html#environment-variables - export SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$(($RANDOM % 100)) + export SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$(($RANDOM % 20)) echo "To reproduce this test run, set the following environment variable:" echo " SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$SKLEARN_TESTS_GLOBAL_RANDOM_SEED", echo "See: https://scikit-learn.org/dev/computing/parallelism.html#sklearn-tests-global-random-seed" From e8b86c20a0d8405aaf32844e684d1ac1348e5f26 Mon Sep 17 00:00:00 2001 From: Florian Bourgey Date: Wed, 18 Feb 2026 20:49:42 +0100 Subject: [PATCH 227/462] DOC: Fix some typos in Lasso (#33280) Co-authored-by: Christian Lorentzen --- sklearn/linear_model/_coordinate_descent.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index ca160d5f63705..5c49722ee2638 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -1284,12 +1284,12 @@ class Lasso(ElasticNet): Parameter vector (w in the cost function formula). dual_gap_ : float or ndarray of shape (n_targets,) - Given param alpha, the dual gaps at the end of the optimization, + Given parameter ``alpha``, the dual gaps at the end of the optimization, same shape as each observation of y. sparse_coef_ : sparse matrix of shape (n_features, 1) or \ (n_targets, n_features) - Readonly property derived from ``coef_``. + Read-only property derived from ``coef_``. intercept_ : float or ndarray of shape (n_targets,) Independent term in decision function. @@ -1332,7 +1332,7 @@ class Lasso(ElasticNet): :class:`~sklearn.svm.LinearSVC`. The precise stopping criteria based on `tol` are the following: First, check that - that maximum coordinate update, i.e. :math:`\\max_j |w_j^{new} - w_j^{old}|` + the maximum coordinate update, i.e. :math:`\\max_j |w_j^{new} - w_j^{old}|` is smaller or equal to `tol` times the maximum absolute coefficient, :math:`\\max_j |w_j|`. If so, then additionally check whether the dual gap is smaller or equal to `tol` times :math:`||y||_2^2 / n_{\\text{samples}}`. @@ -2028,7 +2028,7 @@ class LassoCV(RegressorMixin, LinearModelCV): (n_features, n_features), default='auto' Whether to use a precomputed Gram matrix to speed up calculations. If set to ``'auto'`` let us decide. The Gram - matrix can also be passed as argument. + matrix can also be passed as an argument. max_iter : int, default=1000 The maximum number of iterations. @@ -2039,7 +2039,7 @@ class LassoCV(RegressorMixin, LinearModelCV): until it is smaller or equal to ``tol``. copy_X : bool, default=True - If ``True``, X will be copied; else, it may be overwritten. + If ``True``, `X` will be copied; otherwise, it may be overwritten. cv : int, cross-validation generator or iterable, default=None Determines the cross-validation splitting strategy. @@ -2148,7 +2148,7 @@ class LassoCV(RegressorMixin, LinearModelCV): regularization path. It tends to speed up the hyperparameter search. - The underlying coordinate descent solver uses gap safe screening rules to speedup + The underlying coordinate descent solver uses gap safe screening rules to speed up fitting time, see :ref:`User Guide on coordinate descent `. Examples From d16264e79dea5000acab280729508e93e705e4f1 Mon Sep 17 00:00:00 2001 From: Ben Pedigo Date: Thu, 19 Feb 2026 01:44:35 -0800 Subject: [PATCH 228/462] Fix MDS returning wrong number of components when using ClassicalMDS initialization (#33318) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève --- .../upcoming_changes/sklearn.manifold/33318.fix.rst | 3 +++ sklearn/manifold/_mds.py | 2 +- sklearn/manifold/tests/test_mds.py | 13 ++++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.manifold/33318.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.manifold/33318.fix.rst b/doc/whats_new/upcoming_changes/sklearn.manifold/33318.fix.rst new file mode 100644 index 0000000000000..a851f13c59fa3 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.manifold/33318.fix.rst @@ -0,0 +1,3 @@ +- :meth:`manifold.MDS.transform` returns the correct number of components when + using `init="classical_mds"`. + By :user:`Ben Pedigo `. diff --git a/sklearn/manifold/_mds.py b/sklearn/manifold/_mds.py index 0946d4dec0a67..72116d048a2b2 100644 --- a/sklearn/manifold/_mds.py +++ b/sklearn/manifold/_mds.py @@ -813,7 +813,7 @@ def fit_transform(self, X, y=None, init=None): if init is not None: init_array = init elif self._init == "classical_mds": - cmds = ClassicalMDS(metric="precomputed") + cmds = ClassicalMDS(metric="precomputed", n_components=self.n_components) init_array = cmds.fit_transform(self.dissimilarity_matrix_) else: init_array = None diff --git a/sklearn/manifold/tests/test_mds.py b/sklearn/manifold/tests/test_mds.py index 808856b1167ff..f703a38ac7fd0 100644 --- a/sklearn/manifold/tests/test_mds.py +++ b/sklearn/manifold/tests/test_mds.py @@ -4,7 +4,7 @@ import pytest from numpy.testing import assert_allclose, assert_array_almost_equal, assert_equal -from sklearn.datasets import load_digits, load_iris +from sklearn.datasets import load_digits, load_iris, make_blobs from sklearn.manifold import ClassicalMDS from sklearn.manifold import _mds as mds from sklearn.metrics import euclidean_distances @@ -303,3 +303,14 @@ def test_classical_mds_init_to_mds(): Z2 = mds1.fit_transform(X, init=Z_classical) assert_allclose(Z1, Z2) + + +@pytest.mark.parametrize("init", ["random", "classical_mds"]) +@pytest.mark.parametrize("n_components", [1, 2, 5, 10]) +def test_correct_n_components(init, n_components): + X, _ = make_blobs(n_features=10) + + model = mds.MDS(init=init, n_components=n_components, n_init=1) + Z = model.fit_transform(X) + + assert Z.shape[1] == n_components From 836d3ba01950c6eccded0ea796f17dec42530f14 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Thu, 19 Feb 2026 11:07:39 +0100 Subject: [PATCH 229/462] DOC remove sklearn-evaluation from related projects (#33311) --- doc/related_projects.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/related_projects.rst b/doc/related_projects.rst index 00c1572deb9ac..ae8d7d2ed165c 100644 --- a/doc/related_projects.rst +++ b/doc/related_projects.rst @@ -77,11 +77,6 @@ enhance the functionality of scikit-learn's estimators. - `model-diagnostics `_ Tools for diagnostics and assessment of (machine learning) models (in Python). -- `sklearn-evaluation `_ - Machine learning model evaluation made easy: plots, tables, HTML reports, - experiment tracking and Jupyter notebook analysis. Visual analysis, model - selection, evaluation and diagnostics. - - `yellowbrick `_ A suite of custom matplotlib visualizers for scikit-learn estimators to support visual feature analysis, model selection, evaluation, and diagnostics. From 16a9e1ff0d1e6b66f812bee0468702f5fe762b3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Fri, 20 Feb 2026 14:57:28 +0100 Subject: [PATCH 230/462] TST Xfail test for Python 3.13 free-threaded that fails intermittently in the Wheels CI (#33320) --- .../tests/test_gradient_boosting.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py index e32f6d868b4d5..e5992e27840b8 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py @@ -2,6 +2,8 @@ import io import pickle import re +import sys +import sysconfig import warnings from unittest.mock import Mock @@ -1349,6 +1351,12 @@ def test_interaction_cst_numerically(): ) +@pytest.mark.xfail( + sysconfig.get_config_var("Py_GIL_DISABLED") == 1 + and sys.version_info[:2] == (3, 13), + reason="Fails intermittently in the CI for Python 3.13 free-threaded," + " see https://github.com/scikit-learn/scikit-learn/issues/32631", +) def test_no_user_warning_with_scoring(): """Check that no UserWarning is raised when scoring is set. From 21b6b3765cf42a04313aaf50a431fa38594c288f Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Sat, 21 Feb 2026 07:44:15 +0100 Subject: [PATCH 231/462] MNT remove duplicate comment in loss module (#33341) --- sklearn/_loss/loss.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sklearn/_loss/loss.py b/sklearn/_loss/loss.py index bd72bc0c9559c..cbf2c65dc14be 100644 --- a/sklearn/_loss/loss.py +++ b/sklearn/_loss/loss.py @@ -538,10 +538,6 @@ def init_gradient_and_hessian(self, n_samples, dtype=np.float64, order="F"): return gradient, hessian -# Note: Naturally, we would inherit in the following order -# class HalfSquaredError(IdentityLink, CyHalfSquaredError, BaseLoss) -# But because of https://github.com/cython/cython/issues/4350 we -# set BaseLoss as the last one. This, of course, changes the MRO. class HalfSquaredError(BaseLoss): """Half squared error with identity link, for regression. @@ -1352,9 +1348,7 @@ def _log1pexp(raw_prediction, raw_prediction_exp, xp): class HalfBinomialLossArrayAPI(ArrayAPILossMixin, HalfBinomialLoss): - """A version of the HalfBinomialLoss that is compatible with - the array API. - """ + """A version of the HalfBinomialLoss that is compatible with the array API.""" def loss( self, @@ -1456,8 +1450,7 @@ def _compute_gradient( class HalfMultinomialLossArrayAPI(ArrayAPILossMixin, HalfMultinomialLoss): - """A version of the HalfMultinomialLoss that is compatible with - the array API. + """A version of the HalfMultinomialLoss that is compatible with the array API. Parameters ---------- From 9292c213eb426810a0d06b36c85039d9ef58c224 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Sat, 21 Feb 2026 12:57:35 +0100 Subject: [PATCH 232/462] FIX LogisticRegressionCV with explicit scorer and missing classes in CV folds (#32828) --- .../sklearn.linear_model/32828.fix.rst | 4 ++ sklearn/linear_model/_logistic.py | 62 ++++++++++++++--- sklearn/linear_model/tests/test_logistic.py | 68 +++++++++++++++---- 3 files changed, 110 insertions(+), 24 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/32828.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32828.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32828.fix.rst new file mode 100644 index 0000000000000..d16333467b187 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/32828.fix.rst @@ -0,0 +1,4 @@ +- :class:`linear_model.LogisticRegressionCV` now correctly handles the case when the + `scoring` parameter is set (to something not `None`) and when the CV splits result in + folds where some class labels are missing. + By :user:`Christian Lorentzen `. diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index 90875a32dca27..3a9104eb2c300 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -5,6 +5,7 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause +import inspect import numbers import warnings from numbers import Integral, Real @@ -27,7 +28,7 @@ from sklearn.linear_model._glm.glm import NewtonCholeskySolver from sklearn.linear_model._linear_loss import LinearModelLoss from sklearn.linear_model._sag import sag_solver -from sklearn.metrics import get_scorer, get_scorer_names +from sklearn.metrics import get_scorer, get_scorer_names, make_scorer from sklearn.model_selection import check_cv from sklearn.preprocessing import LabelEncoder from sklearn.svm._base import _fit_liblinear @@ -308,6 +309,7 @@ def _logistic_regression_path( w0 = np.zeros( n_features + int(fit_intercept), dtype=_matching_numpy_dtype(X, xp=xp) ) + # classes[1] is the "positive label" mask = xp.asarray(y == classes[1], device=device_) y_bin = xp.ones(y.shape, dtype=X.dtype, device=device_) if solver == "liblinear": @@ -749,8 +751,53 @@ def _log_reg_scoring_path( scores = list() + # Prepare the call to get the score per fold: calc_score scoring = get_scorer(scoring) - for w in coefs: + if scoring is None: + + def calc_score(log_reg): + return log_reg.score(X_test, y_test, sample_weight=sw_test) + + else: + is_binary = len(classes) <= 2 + score_params = score_params or {} + score_params = _check_method_params(X=X, params=score_params, indices=test) + # We need to pass the classes as "labels" argument to scorers that support + # it, e.g. scoring = "neg_brier_score", because y_test may not contain all + # class labels. + # There are at least 2 possibilities: + # 1. Metadata routing is enabled: A try except clause is possible with + # adding labels to score_params. We could then pass the already instantiated + # log_reg instance to scoring. + # 2. We reconstruct the scorer and pass labels as kwargs explicitly. + # We implement the 2nd option even if it seems a bit hacky because it works + # with and without metadata routing. + if hasattr(scoring, "_score_func"): + sig = inspect.signature(scoring._score_func).parameters + else: + sig = [] + + if (is_binary and "labels" in sig and "pos_label" in sig) or ( + len(classes) >= 3 and "labels" in sig + ): + pos_label_kwarg = {} + if is_binary: + # see _logistic_regression_path + pos_label_kwarg["pos_label"] = classes[-1] + scoring = make_scorer( + scoring._score_func, + greater_is_better=True if scoring._sign == 1 else False, + response_method=scoring._response_method, + labels=classes, + **pos_label_kwarg, + **getattr(scoring, "_kwargs", {}), + ) + + def calc_score(log_reg): + return scoring(log_reg, X_test, y_test, **score_params) + + for w, C in zip(coefs, Cs): + log_reg.C = C if fit_intercept: log_reg.coef_ = w[..., :-1] log_reg.intercept_ = w[..., -1] @@ -758,15 +805,8 @@ def _log_reg_scoring_path( log_reg.coef_ = w log_reg.intercept_ = 0.0 - if scoring is None: - scores.append(log_reg.score(X_test, y_test, sample_weight=sw_test)) - else: - score_params = score_params or {} - score_params = _check_method_params(X=X, params=score_params, indices=test) - # FIXME: If scoring = "neg_brier_score" and if not all class labels - # are present in y_test, the following fails. Maybe we can pass - # "labels=classes" to the call of scoring. - scores.append(scoring(log_reg, X_test, y_test, **score_params)) + scores.append(calc_score(log_reg)) + return coefs, Cs, np.array(scores), n_iter diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index 928c11c61953c..da5818b1d7139 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -23,7 +23,7 @@ _log_reg_scoring_path, _logistic_regression_path, ) -from sklearn.metrics import brier_score_loss, get_scorer, log_loss, make_scorer +from sklearn.metrics import brier_score_loss, get_scorer, log_loss from sklearn.model_selection import ( GridSearchCV, KFold, @@ -729,26 +729,68 @@ def test_multinomial_cv_iris(use_legacy_attributes): assert np.all(clf.scores_ == 0.0) # We use a proper scoring rule, i.e. the Brier score, to evaluate our classifier. - # Because of a bug in LogisticRegressionCV, we need to create our own scoring - # function to pass explicitly the labels. - scoring = make_scorer( - brier_score_loss, - greater_is_better=False, - response_method="predict_proba", - scale_by_half=True, - labels=classes, - ) # We set small Cs, that is strong penalty as the best C is likely the smallest one. clf = LogisticRegressionCV( - cv=cv, scoring=scoring, Cs=np.logspace(-6, 3, 10), use_legacy_attributes=False + cv=cv, + scoring="neg_brier_score", + Cs=np.logspace(-6, 3, 10), + use_legacy_attributes=False, ).fit(X, y) assert clf.C_ == 1e-6 # smallest value of provided Cs brier_scores = -clf.scores_ # We expect the scores to be bad because train and test sets have # non-overlapping labels - assert np.all(brier_scores > 0.7) + assert np.all(brier_scores > 0.7 * 2) # times 2 because scale_by_half=False # But the best score should be better than the worst value of 1. - assert np.min(brier_scores) < 0.8 + assert np.min(brier_scores) < 0.8 * 2 # times 2 because scale_by_half=False + + +@pytest.mark.parametrize("enable_metadata_routing", [False, True]) +@pytest.mark.parametrize("n_classes", [2, 3]) +def test_logistic_cv_folds_with_classes_missing(enable_metadata_routing, n_classes): + """Test that LogisticRegressionCV correctly computes scores even when classes are + missing on CV folds. + """ + with config_context(enable_metadata_routing=enable_metadata_routing): + y = np.array(["a", "a", "b", "b", "c", "c"])[: 2 * n_classes] + X = np.arange(2 * n_classes)[:, None] + + # Test CV folds have missing class labels. + cv = KFold(n_splits=n_classes) + # Check this assumption. + for train, test in cv.split(X, y): + assert len(np.unique(y[train])) == n_classes - 1 + assert len(np.unique(y[test])) == 1 + assert set(y[train]) & set(y[test]) == set() + + clf = LogisticRegressionCV( + cv=cv, + scoring="neg_brier_score", + Cs=np.logspace(-6, 6, 5), + l1_ratios=(0,), + use_legacy_attributes=False, + ).fit(X, y) + + assert clf.C_ == 1e-6 # smallest value of provided Cs + for i, (train, test) in enumerate(cv.split(X, y)): + # We need to construct the logistic regression model, clf2, as it was fit on + # a single training fold. + clf2 = LogisticRegression(C=clf.C_).fit(X, y) + clf2.coef_ = clf.coefs_paths_[i, 0, 0, :, :-1] + clf2.intercept_ = clf.coefs_paths_[i, 0, 0, :, -1] + if n_classes <= 2: + bs = brier_score_loss( + y[test], + clf2.predict_proba(X[test]), + pos_label="b", + labels=["a", "b"], + ) + else: + bs = brier_score_loss( + y[test], clf2.predict_proba(X[test]), labels=["a", "b", "c"] + ) + + assert_allclose(-clf.scores_[i, 0, 0], bs) def test_logistic_regression_solvers(global_random_seed): From c4f0dbb3f350ac015368b83ebca607d5d735c13d Mon Sep 17 00:00:00 2001 From: Christian Lorentzen Date: Sun, 22 Feb 2026 18:06:59 +0100 Subject: [PATCH 233/462] MNT remove unused need_update_leaves_values in private losses (#33347) --- sklearn/_loss/loss.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/sklearn/_loss/loss.py b/sklearn/_loss/loss.py index cbf2c65dc14be..429745a0c5462 100644 --- a/sklearn/_loss/loss.py +++ b/sklearn/_loss/loss.py @@ -113,9 +113,6 @@ class BaseLoss: differentiable : bool Indicates whether or not loss function is differentiable in raw_prediction everywhere. - need_update_leaves_values : bool - Indicates whether decision trees in gradient boosting need to update - leave values after having been fit to the (negative) gradients. approx_hessian : bool Indicates whether the hessian is approximated or exact. If, approximated, it should be larger or equal to the exact one. @@ -126,7 +123,7 @@ class BaseLoss: """ # For gradient boosted decision trees: - # This variable indicates whether the loss requires the leaves values to + # If differentiable = False for a loss, the leaves values are required to # be updated once the tree has been trained. The trees are trained to # predict a Newton-Raphson step (see grower._finalize_leaf()). But for # some losses (e.g. least absolute deviation) we need to adjust the tree @@ -135,7 +132,6 @@ class BaseLoss: # Gradient Boosting Machine by Friedman # (https://statweb.stanford.edu/~jhf/ftp/trebst.pdf) for the theory. differentiable = True - need_update_leaves_values = False is_multiclass = False def __init__(self, closs, link, n_classes=None): @@ -580,7 +576,6 @@ class AbsoluteError(BaseLoss): """ differentiable = False - need_update_leaves_values = True def __init__(self, sample_weight=None): super().__init__(closs=CyAbsoluteError(), link=IdentityLink()) @@ -630,7 +625,6 @@ class PinballLoss(BaseLoss): """ differentiable = False - need_update_leaves_values = True def __init__(self, sample_weight=None, quantile=0.5): check_scalar( @@ -697,7 +691,6 @@ class HuberLoss(BaseLoss): """ differentiable = False - need_update_leaves_values = True def __init__(self, sample_weight=None, quantile=0.9, delta=0.5): check_scalar( From 9e7b37ba397530f6b686a304d870d8bc9ab7374f Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 23 Feb 2026 04:14:47 -0500 Subject: [PATCH 234/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33367) Co-authored-by: Lock file bot --- .../pylatest_free_threaded_linux-64_conda.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index cce577798d031..0bbffd42aef26 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -5,23 +5,23 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#3251796e09870c978e0f69fa05e38fb6 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec From 075be81847e6cfa4fd6ef2891fd00efcaa267809 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 23 Feb 2026 04:15:07 -0500 Subject: [PATCH 235/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33368) Co-authored-by: Lock file bot --- .../azure/pylatest_pip_scipy_dev_linux-64_conda.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index ec24f8f7cec3d..12996217704ed 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -5,15 +5,15 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 From 7d5d2426f3f56057da3b47658414e75448955426 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 23 Feb 2026 04:15:33 -0500 Subject: [PATCH 236/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33369) Co-authored-by: Lock file bot --- ...a_forge_cuda_array-api_linux-64_conda.lock | 83 +++++++++---------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 17e257adec1f1..8d5202b4a2dc8 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -30,11 +30,11 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libnvptxcompiler-dev-12.9.86-ha770c72_2.conda#3fd926c321c6dbf386aa14bd8b125bfb https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 https://conda.anaconda.org/conda-forge/noarch/cuda-nvcc-dev_linux-64-12.9.86-he91c749_2.conda#19d4e090217f0ea89d30bedb7461c048 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-impl-12.9.86-h4bc722e_2.conda#82125dd3c0c4aa009faa00e2829b93d8 @@ -42,10 +42,10 @@ https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-tools-12.9.86-h4bc722e https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 @@ -53,7 +53,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb9d3cd8_0.conda#db63358239cbe1ff86242406d440e44a https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 @@ -67,9 +67,9 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.13-h2c9d079_1.conda#3c3d02681058c3d206b562b2e3bc337f -https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h8b1a151_9.conda#f7ec84186dfe7a9e3a9f9e5a4d023e75 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.2-h8b1a151_0.conda#f16f498641c9e05b645fe65902df661a https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h8b1a151_4.conda#c7e3e08b7b1b285524ab9d74162ce40b -https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h8b1a151_5.conda#68da5b56dde41e172b7b24f071c4b392 +https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.10-h8b1a151_0.conda#f8e1bcc5c7d839c5882e94498791be08 https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-12.9.79-h5888daf_0.conda#cb15315d19b58bd9cd424084e58ad081 https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-static-12.9.79-h5888daf_0.conda#d3c4ac48f4967f09dd910d9c15d40c81 https://conda.anaconda.org/conda-forge/linux-64/cuda-cupti-12.9.79-h676940d_1.conda#a2ddf359dcb9e6a3d0173b10f58f4db9 @@ -93,12 +93,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libnvjitlink-12.9.86-hecca717_2.conda#3461b0f2d5cbb7973d361f9e85241d98 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -108,7 +108,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/rapidsai/linux-64/rapids-logger-0.2.3-h98325ef_0.conda#81257f29bfcc1e58f0405d7bc9feb309 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.2-he8a4886_1.conda#bade189a194e66b93c03021bd36c337b +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.0-ha63dd3a_1.conda#f9bb0a7187f2e25b19cde17aa8c846c4 https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -117,7 +117,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.cond https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-hdaf4b65_5.conda#132e8f8f40f0ffc0bbde12bb4e8dd1a1 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-h3ca20c3_1.conda#c9aa75692f24cce182c3ecd001a1a595 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 @@ -131,7 +131,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.co https://conda.anaconda.org/conda-forge/linux-64/libcurand-dev-10.3.10.19-h676940d_1.conda#fc716aaff5af15b80ccbd28b3e67672c https://conda.anaconda.org/conda-forge/linux-64/libcusparse-12.5.10.65-hecca717_2.conda#890ebfaad48c887d3d82847ec9d6bc79 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_1.conda#5b5846bc2b23e07a1d61b89dcb67fcf0 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_0.conda#b7113551db5a3e2403cdd052c66e9999 https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-openmp_hd680484_4.conda#c0512e4f60d62ccccb4c3c8333b33608 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 @@ -149,8 +149,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.7-h28f887f_1.conda#7b8e3f846353b75db163ad93248e5f9d -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-ha8fc4e3_5.conda#3028f20dacafc00b22b88b324c8956cc +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.9-h841be55_2.conda#7e1ea1a67435a32e04305fda877acd1e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.10-hf621c6d_0.conda#977e7d3cba1ef84fc088869b292672fe https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvcc-impl-12.9.86-h85509e4_2.conda#67458d2685e7503933efa550f3ee40f3 https://conda.anaconda.org/conda-forge/linux-64/cuda-profiler-api-12.9.79-h7938cbb_1.conda#90d09865fb37d11d510444e34ebe6a09 @@ -181,8 +181,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.3-hef928c7_0.conda#bdd464b33f6540ed70845b946c11a7b8 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-hc63082f_11.conda#6a653aefdc5d83a4f959869d1759e6e3 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.6-hb9c0fe4_1.conda#b1143a5b5a03ee174b3f3f7c49df3c09 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.14.0-ha25ca29_1.conda#a827b063719f5aac504d06ac77cc3125 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b @@ -190,8 +190,8 @@ https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.3.4-pyhcf101f3_0 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-64/fastrlock-0.8.3-py313h5d5ffb9_2.conda#9bcbd351966dc56a24fc0c368da5ad99 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.0-pyhd8ed1ab_0.conda#69296c50b5876a09be85c512985b922a +https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.3-pyhd8ed1ab_0.conda#9dbb20eec24beb026291c20a35ce1ff9 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 @@ -219,7 +219,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py313h80991f8_0.co https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.2-pyhc7ab6ef_0.conda#0c2d37c332453bd66b254bc71311fa30 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 @@ -237,13 +237,13 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.3-h06ab39a_1.conda#3689a4290319587e3b54a4f9e68f70c8 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h9b5df67_3.conda#1f130ac4eb7f1dea1ae4b5f53683e3aa https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py313h3dea7bd_0.conda#77e1fc7133e03ccd62070f2405c82ea9 https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.5-py313h929d4db_0.conda#f2416964cdb2808dd2ed5be276a8fcdb https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py313h3dea7bd_0.conda#c0f36dfbb130da4f6ce2df31f6b25ea8 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d @@ -258,37 +258,36 @@ https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63 https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 -https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.2-pyh7a1b43c_0.conda#44dff15b5d850481807888197b254b46 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.12-h4df99d1_100.conda#3d92938d5b83c49162ade038aab58a59 -https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py313h246eb7c_0.conda#932203205c4cf6f661180b98a48f195a +https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py313h246eb7c_1.conda#8526afdb4ae2d95db733c4188f092f01 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.4-h8824e59_0.conda#113b9d9913280474c0868b0e290c0326 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.2-hb153662_3.conda#c3bb19fc041068029018ab183baa8982 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.5.1-cuda12_py313hacc9b55_1.conda#808c80c320dfd77ba5da9f6a35b07503 https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.5-pyh698daf1_0.conda#a4fb0d4ffdac1cf2cda9318d2f789d20 -https://conda.anaconda.org/conda-forge/linux-64/cupy-core-13.6.0-py313h28b6081_2.conda#388fb72307f756f7f2c7f5928647bc6b +https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py313h28b6081_0.conda#fe933a91c19fa88788b4204b6ba67ba2 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_1.conda#384a1730ea66a72692e377cb45996d61 https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_hb019b6b_202.conda#20529bf89b9dad005a5ace8bc5408624 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.conda#84cef0ce56c6db53edb3f8b83bdbb364 https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py313hbfd7664_0.conda#ab6d05e915ab2ae4c41d275b14592151 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py313hbfd7664_0.conda#1c8807728f0333228766dee685394e16 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10.conda#937d1d4c233adc6eeb2ac3d6e9a73e53 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-hc9b1074_13.conda#e7b0b55965db0d2b85c9ae1397d14012 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 -https://conda.anaconda.org/conda-forge/linux-64/cupy-13.6.0-py313h586c94b_2.conda#0685ae3980f823b2ca78552f7d8d4033 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a +https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py313h7fc6698_0.conda#41368ea5c4c7c607ac98ecab56833535 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hffdcd12_0.conda#b659a59ec7b67623dcaec02388e06fb9 @@ -296,24 +295,24 @@ https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.cond https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_hb8e8477_202.conda#d0429f5f90f804183a84c3f861a7eaa2 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h2603568_3_cpu.conda#4952208743759431df21f01aba7466dd +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-h3e112c1_2_cpu.conda#f5c13f8872a5b4450e95411f7bd18135 https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313h85046ba_0.conda#f6161781ceb86e9f5da1b532e4c4453c https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_202.conda#1efceead0b494f34670136ce6de29e79 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h53684a4_3_cpu.conda#8ffa55113b6ade32fe4a51d480f0b806 -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_3_cpu.conda#e3eef5f398cccdd73d3ff2e3c8ec0793 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_2_cpu.conda#d57c916f0036b8c29f99924e62a29a2b +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_2_cpu.conda#d2b6e411baf659ad8ec33941b75cc767 https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313h85046ba_0.conda#f6161781ceb86e9f5da1b532e4c4453c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_3_cpu.conda#c2415c2264b6b5e4ef45019ce6aa9579 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_2_cpu.conda#b3b15f7f4a368d9e542ca37e739ff5d1 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py313h98bfbea_0_cpu.conda#c8d1ba76789588fdf7fddc213a25137e -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_3_cpu.conda#22beeb3b36026e14f509a8b62ca58f1a +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py313h98bfbea_0_cpu.conda#d2b771a9050c52941a61a72f2d161c64 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_2_cpu.conda#1213e3cebce15e93ed92105a47178168 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.02.00-cuda12_260204_a2f5a8b7.conda#361cae27e77618c6ba9f943807471f9f https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.02.00-cuda12_py313_260204_c212ab9b.conda#14933b753ec82f9d5a61d7cb4b5e2e71 https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.02.00-cuda12_py313_260204_a2f5a8b7.conda#c46807878ad576379e7be3acc187d13a -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-hb4dd7c2_3_cpu.conda#c582146e900636a8db83955cc15eadd5 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.0-py313h78bf25f_0.conda#a6e89cb214f318db9548b791ba27f862 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_2_cpu.conda#b9ba37f40b02eecf9701527650c50b0e +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py313h78bf25f_0.conda#bd299f66ab2d10d1e03d4148397fe263 From c83733128e2ca835674442927dfbbe2c3da93db0 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 23 Feb 2026 04:16:46 -0500 Subject: [PATCH 237/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33370) Co-authored-by: Lock file bot --- ...latest_conda_forge_mkl_linux-64_conda.lock | 80 +++++++++---------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 12 +-- .../pylatest_conda_forge_osx-arm64_conda.lock | 20 ++--- ...st_pip_openblas_pandas_linux-64_conda.lock | 14 ++-- ...nblas_min_dependencies_linux-64_conda.lock | 42 +++++----- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 18 ++--- ...min_conda_forge_openblas_win-64_conda.lock | 14 ++-- build_tools/circle/doc_linux-64_conda.lock | 64 +++++++-------- .../doc_min_dependencies_linux-64_conda.lock | 66 +++++++-------- ...n_conda_forge_arm_linux-aarch64_conda.lock | 26 +++--- 10 files changed, 178 insertions(+), 178 deletions(-) diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock index e5dece942f515..4888a1815813f 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -20,25 +20,25 @@ https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.con https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 @@ -52,9 +52,9 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.13-h2c9d079_1.conda#3c3d02681058c3d206b562b2e3bc337f -https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.1-h8b1a151_9.conda#f7ec84186dfe7a9e3a9f9e5a4d023e75 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.2-h8b1a151_0.conda#f16f498641c9e05b645fe65902df661a https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h8b1a151_4.conda#c7e3e08b7b1b285524ab9d74162ce40b -https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.7-h8b1a151_5.conda#68da5b56dde41e172b7b24f071c4b392 +https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.2.10-h8b1a151_0.conda#f8e1bcc5c7d839c5882e94498791be08 https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717_0.conda#dbe3ec0f120af456b3477743ffd99b74 https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda#f7d7a4104082b39e3b3473fbd4a38229 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 @@ -68,11 +68,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -80,7 +80,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.6.2-he8a4886_1.conda#bade189a194e66b93c03021bd36c337b +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.0-ha63dd3a_1.conda#f9bb0a7187f2e25b19cde17aa8c846c4 https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -89,7 +89,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.cond https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.23.3-hdaf4b65_5.conda#132e8f8f40f0ffc0bbde12bb4e8dd1a1 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-h3ca20c3_1.conda#c9aa75692f24cce182c3ecd001a1a595 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca @@ -98,7 +98,7 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f4 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_1.conda#5b5846bc2b23e07a1d61b89dcb67fcf0 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_0.conda#b7113551db5a3e2403cdd052c66e9999 https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 @@ -106,15 +106,14 @@ https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.cond https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 -https://conda.anaconda.org/conda-forge/linux-64/nodejs-22.21.1-h273caaf_2.conda#264e1ba248b109705429b4375888467a https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.7-h28f887f_1.conda#7b8e3f846353b75db163ad93248e5f9d -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.7-ha8fc4e3_5.conda#3028f20dacafc00b22b88b324c8956cc +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.9-h841be55_2.conda#7e1ea1a67435a32e04305fda877acd1e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.10-hf621c6d_0.conda#977e7d3cba1ef84fc088869b292672fe https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 @@ -125,9 +124,9 @@ https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.co https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 +https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.13.1-h3d65ac4_0.conda#45fe531d027ce218b895565110a79a1f https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-hbb90d81_1.conda#9269175175f18091b8844c8e9f213205 -https://conda.anaconda.org/conda-forge/linux-64/playwright-1.58.2-h0bd9c3d_0.conda#9d161e4e16adbf1155a12470ced3c4cc https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 @@ -135,8 +134,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.3-hef928c7_0.conda#bdd464b33f6540ed70845b946c11a7b8 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.13.3-hc63082f_11.conda#6a653aefdc5d83a4f959869d1759e6e3 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.6-hb9c0fe4_1.conda#b1143a5b5a03ee174b3f3f7c49df3c09 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.14.0-ha25ca29_1.conda#a827b063719f5aac504d06ac77cc3125 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a @@ -147,10 +146,11 @@ https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.c https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.0-pyhd8ed1ab_0.conda#69296c50b5876a09be85c512985b922a +https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.3-pyhd8ed1ab_0.conda#9dbb20eec24beb026291c20a35ce1ff9 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 -https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.1-py314h42812f9_1.conda#cca70a5a85afb519e8c839ae80dc9334 +https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.2-py314h42812f9_0.conda#511748f9debe034ff88eef99bc215fd3 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -172,9 +172,10 @@ https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py314h8ec4b1a_0.conda#79678378ae235e24b3aa83cee1b38207 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f +https://conda.anaconda.org/conda-forge/linux-64/playwright-1.58.2-h5585027_0.conda#1650804f26dd992fd7418fe603f1c653 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.2-pyhc7ab6ef_0.conda#0c2d37c332453bd66b254bc71311fa30 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac @@ -194,12 +195,12 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.3-h06ab39a_1.conda#3689a4290319587e3b54a4f9e68f70c8 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h9b5df67_3.conda#1f130ac4eb7f1dea1ae4b5f53683e3aa https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py314h67df5f8_0.conda#6c7efc167cee337d9c41200506d022b8 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py314h28848ee_2.conda#6958d0a4028e0b3ffd80ce539482c605 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 @@ -211,7 +212,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-h9d11ab5_ https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-h9692893_2.conda#c3de1cc30bc11edbc98aed352381449d https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 -https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.2-pyh7a1b43c_0.conda#44dff15b5d850481807888197b254b46 https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.0-pyhd8ed1ab_0.conda#ec33a030c3bc90f0131305a8eba5f8a3 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -221,9 +222,9 @@ https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.35.4-h8824e59_0.conda#113b9d9913280474c0868b0e290c0326 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.2-hb153662_3.conda#c3bb19fc041068029018ab183baa8982 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_1.conda#384a1730ea66a72692e377cb45996d61 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 @@ -232,42 +233,41 @@ https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.58.0-pyhcf101f https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-h20b40b1_10.conda#937d1d4c233adc6eeb2ac3d6e9a73e53 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-hc9b1074_13.conda#e7b0b55965db0d2b85c9ae1397d14012 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hffdcd12_0.conda#b659a59ec7b67623dcaec02388e06fb9 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.0-h2603568_3_cpu.conda#4952208743759431df21f01aba7466dd +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-h3e112c1_2_cpu.conda#f5c13f8872a5b4450e95411f7bd18135 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py314hf36963e_0.conda#46a2b79da4213038907306040c9c9fd8 https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.0-h53684a4_3_cpu.conda#8ffa55113b6ade32fe4a51d480f0b806 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_2_cpu.conda#d57c916f0036b8c29f99924e62a29a2b https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.0-h7376487_3_cpu.conda#e3eef5f398cccdd73d3ff2e3c8ec0793 +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_2_cpu.conda#d2b6e411baf659ad8ec33941b75cc767 https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h7058990_102.conda#478b66bfe4b3b33f92442eb2131cc42b https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_1.conda#4ea6b620fdf24a1a0bc4f1c7134dfafb -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py314hf36963e_0.conda#46a2b79da4213038907306040c9c9fd8 https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.0-h635bf11_3_cpu.conda#c2415c2264b6b5e4ef45019ce6aa9579 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py314hb4ffadd_0.conda#90e3461036907dcd77c950308c1033d2 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.0-py314h969be7f_0_cpu.conda#66b6069247a271f2792ecb90e1087fde +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_2_cpu.conda#b3b15f7f4a368d9e542ca37e739ff5d1 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py314hb4ffadd_0.conda#23fc526360815090f6bfcd7c6c8e4954 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py314h969be7f_0_cpu.conda#97c21b0d5952f4e0f80bb790df1a5c88 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h6018c46_102.conda#1719e8fde93354419f0f6e1b46d67fcf https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py314hf07bd8e_1.conda#c7df812186fb1290bc00d9b7b5a50b18 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.1.0-pyhcf101f3_0.conda#57d364589a8c710c5b34e8b4a5312ea6 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.0-h635bf11_3_cpu.conda#22beeb3b36026e14f509a8b62ca58f1a +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_2_cpu.conda#1213e3cebce15e93ed92105a47178168 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_102.conda#9061f7a9fc6c51108ecfb97132161167 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.0-hb4dd7c2_3_cpu.conda#c582146e900636a8db83955cc15eadd5 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_2_cpu.conda#b9ba37f40b02eecf9701527650c50b0e https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.0-py314hdafbbf9_0.conda#f63f85bccdd104d2ffa341fd705f86d9 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py314hdafbbf9_0.conda#860f29e99f5b5f15b0d6a21166588bab diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 5728134da66e5..53dc3dc045c2a 100644 --- a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -5,12 +5,12 @@ https://conda.anaconda.org/conda-forge/osx-64/mkl-include-2023.2.0-h694c41f_50502.conda#f394610725ab086080230c5d8fd96cd4 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda#97c4b3bd8a90722104798175a1bdddbf +https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda#4173ac3b19ec0a4f400b4f782910368b https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.8-h4fb565c_2.conda#1ac756454e65fb3fd7bc7de599526e43 https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 -https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda#222e0732a1d0780a622926265bee14ef +https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda#a684eb8a19b2aa68fde0267df172a1e3 https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda#66a0dc7464927d0853b590b6f53ba3ea https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda#210a85a1119f97ea7887188d176db135 https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.2-h8616949_0.conda#48dda187f169f5a8f1e5e07701d5cdd9 @@ -43,7 +43,7 @@ https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109 https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf https://conda.anaconda.org/conda-forge/osx-64/ccache-4.12.3-h23dfd00_0.conda#9184b1fd28dd26fafba199afd2a2b713 https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.conda#dfbdc8fd781dc3111541e4234c19fdbd -https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_17.conda#500bac4a846e5001cbf05572df6c3654 +https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda#9a5cb96e43f5c2296690186e15b3296f https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h745d5cb_1.conda#1fd2c75a8a9adc629983ed629dec42e1 https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda#030ec23658b941438ac42303aff0db2b @@ -56,7 +56,7 @@ https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.9-py314hf3ac25a_2.conda#28a77c52c425fa9c6d914c609c626b1a https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.18-h90db99b_0.conda#753acc10c7277f953f168890e5397c80 https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.1-h694c41f_0.conda#e0e2edaf5e0c71b843e25a7ecc451cc9 -https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_17.conda#bb0c5b043c41c27f4f73a103c6ad0c7f +https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda#ca52daf58cea766656266c8771d8be81 https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 @@ -79,7 +79,7 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.1-h694c41f_0.conda#ca641fdf8b7803f4b7212b6d66375930 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_17.conda#218faf079bac8521ccf3f8542feeb51d +https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda#34a9f67498721abcfef00178bcf4b190 https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.1-py314hf9dbaa9_0.conda#9a35ec32776ac587bf178233fd2176e4 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -97,7 +97,7 @@ https://conda.anaconda.org/conda-forge/osx-64/liblapacke-3.9.0-20_osx64_mkl.cond https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.2-py314hfc4c462_1.conda#891bda68803fbbcf08d37f94981b650a https://conda.anaconda.org/conda-forge/osx-64/blas-devel-3.9.0-20_osx64_mkl.conda#cc3260179093918b801e373c6e888e02 https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h22a2ed9_4.conda#511f02f632e1fb0555da3cb4261851d9 -https://conda.anaconda.org/conda-forge/osx-64/pandas-3.0.0-py314h550b3c8_0.conda#6c2fa7e6dc0b23634f2f19d7054516b1 +https://conda.anaconda.org/conda-forge/osx-64/pandas-3.0.1-py314h99bb933_0.conda#8efb0ea54eaf4aff69a0a16a5e5efb4c https://conda.anaconda.org/conda-forge/osx-64/scipy-1.17.0-py314h6328ba2_1.conda#e519933e2e628d7cd159147c224366bf https://conda.anaconda.org/conda-forge/osx-64/blas-2.120-mkl.conda#b041a7677a412f3d925d8208936cb1e2 https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.8-py314hd47142c_0.conda#91d76a5937b47f7f0894857ce88feb9f diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock index 7971a75fe0eae..d5d55aa80af95 100644 --- a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock @@ -6,16 +6,16 @@ https://conda.anaconda.org/conda-forge/noarch/libgfortran-devel_osx-arm64-14.3.0 https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a66894dfd07c4510beb6b3f9672ccc0 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 -https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_6.conda#4cd4e8d9e11f08dfba7b48f6b3eae8cb +https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_7.conda#5f0ebbfea12d8e5bddff157e271fdb2f https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda#58fd217444c2a5701a44244faf518206 +https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda#620b85a3f45526a8bc4d23fd78fc22f0 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-h38cb7af_0.conda#1e93aca311da0210e660d2247812fa02 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda#4cb5878bdb9ebfa65b7cdff5445087c5 https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c -https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda#b79875dbb5b1db9a4a22a4520f918e1a +https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda#a92e310ae8dfc206ff449f362fc4217f https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda#43c04d9cb46ef176bb2a4c77e324d599 https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda#4d5a7445f0b25b6a3ddbb56e790f5251 https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda#f0695fbecf1006f27f4395d64bd0c4b8 @@ -57,7 +57,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab1 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.12.3-h414bf82_0.conda#11dee8592fccf816ae8bd46f08c3ca31 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda#6d4ede03e2a8e20eb51f7f681d2a2550 -https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_17.conda#65c07cee234440ae4d5d340fc4b2e69a +https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda#92df6107310b1fff92c4cc84f0de247b https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.33.5-h4a5acfd_0.conda#b839e3295b66434f20969c8b940f056a https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda#c08557d00807785decafb932b5be7ef5 https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 @@ -70,13 +70,13 @@ https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.c https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py314hc6117b3_0.conda#1289de88f884ac89144949cb97ccabe7 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.0-pyhd8ed1ab_0.conda#69296c50b5876a09be85c512985b922a +https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.3-pyhd8ed1ab_0.conda#9dbb20eec24beb026291c20a35ce1ff9 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py314h42813c9_2.conda#9aa431bf603c231e8c77a1b0842a85ed https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.18-hdfa7624_0.conda#6631a7bd2335bb9699b1dbc234b19784 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda#f35fb38e89e2776994131fbf961fa44b -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_17.conda#c6329d871fb3207e9657c384128f5488 +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda#c4a6f7989cffb0544bfd9207b6789971 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda#fab1be106a50e20f10fe5228fd1d1651 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f @@ -88,7 +88,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hbfb3c88_0.conda https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.2-pyhc7ab6ef_0.conda#0c2d37c332453bd66b254bc71311fa30 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 @@ -109,10 +109,10 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_4.conda#eaf3d06e3a8a10dee7565e8d76ae618d https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_7.conda#5600ae1b88144099572939e773f4b20b -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_17.conda#45ba22eb5381fb602a45233d89ba27ae +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda#26981599908ed2205366e8fc91b37fc6 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.1.1-py314hab283cf_0.conda#bcb38a8005e93a3b240a0dbcf28df87a -https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.2-pyh7a1b43c_0.conda#44dff15b5d850481807888197b254b46 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 @@ -137,7 +137,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.2-py314hae46ccb_1.con https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-5_h55bc449_accelerate.conda#6696b095e91860523bcc97303e11d30d https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py314hf8a3a22_4.conda#cddc851000ce131d757678c2f329eaad -https://conda.anaconda.org/conda-forge/osx-arm64/pandas-3.0.0-py314h5e21a50_0.conda#1594f26f007c3f2ef7ad789b4a651082 +https://conda.anaconda.org/conda-forge/osx-arm64/pandas-3.0.1-py314h5e21a50_0.conda#840cec8154769d52f65f0fdaaf4aa4c9 https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.10.0-cpu_generic_py314_he36690f_2.conda#58e87541ac9cbcbf6761d85a95b88578 https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.0-py314hfc1f868_1.conda#09978c420b2e017134c825c06250bf23 https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.305-accelerate.conda#5f941c90faaca70599ef8302d0c2738f diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock index 92b80f1ee85af..6c598f2736a02 100644 --- a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -5,15 +5,15 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -71,11 +71,11 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 -# pip scipy @ https://files.pythonhosted.org/packages/63/1e/12fbf2a3bb240161651c94bb5cdd0eae5d4e8cc6eaeceb74ab07b12a753d/scipy-1.17.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=6680f2dfd4f6182e7d6db161344537da644d1cf85cf293f015c60a17ecf08752 +# pip scipy @ https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 # pip lightgbm @ https://files.pythonhosted.org/packages/42/86/dabda8fbcb1b00bcfb0003c3776e8ade1aa7b413dff0a2c08f457dace22f/lightgbm-4.6.0-py3-none-manylinux_2_28_x86_64.whl#sha256=cb19b5afea55b5b61cbb2131095f50538bd608a00655f23ad5d25ae3e3bf1c8d # pip matplotlib @ https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486 # pip meson-python @ https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl#sha256=67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298 -# pip pandas @ https://files.pythonhosted.org/packages/f7/a3/51e02ebc2a14974170d51e2410dfdab58870ea9bcd37cda15bd553d24dc4/pandas-3.0.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=95683af6175d884ee89471842acfca29172a85031fccdabc35e50c0984470a0e +# pip pandas @ https://files.pythonhosted.org/packages/f2/85/ab6d04733a7d6ff32bfc8382bf1b07078228f5d6ebec5266b91bfc5c4ff7/pandas-3.0.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=1ff8cf1d2896e34343197685f432450ec99a85ba8d90cce2030c5eee2ef98791 # pip pyamg @ https://files.pythonhosted.org/packages/63/f3/c13ae1422434baeefe4d4f306a1cc77f024fe96d2abab3c212cfa1bf3ff8/pyamg-5.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=5cc223c66a7aca06fba898eb5e8ede6bb7974a9ddf7b8a98f56143c829e63631 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index d5267642ced6a..60d040339ba52 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -16,18 +16,18 @@ https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.con https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda#f9f81ea472684d75b9dd8d0b328cf655 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 @@ -37,7 +37,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb9d3cd8_3.conda# https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -63,11 +63,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -96,8 +96,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.co https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.conda#1f0a03af852a9659ed2bf08f2f1704fd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_17.conda#d7954bb54fc77e7952a78e5e0d134df5 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_1.conda#5b5846bc2b23e07a1d61b89dcb67fcf0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_0.conda#b7113551db5a3e2403cdd052c66e9999 https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 @@ -119,7 +119,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.13.27-h3870b5a_0.cond https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.conda#d47dee1856d9cb955b8076eeff304a5b https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_1.conda#5ebd79c20c7ecf979f20e26fedc0a4fd +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_0.conda#70a09b6817c7ad694ef4543204c59c25 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 @@ -148,6 +148,7 @@ https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda# https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac @@ -165,7 +166,7 @@ https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.1-pyhcf101f3_0.conda#9402ece5651f956de34cf0dc20dfc3a5 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda#4fefefb892ce9cc1539405bec2f1a6cd https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 @@ -186,12 +187,12 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.0-h435f46f_0.conda#c7726f96aab024855ede05e0ca6e94a0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.8.13-hd4f18eb_5.conda#860fb8c0efec64a4a678eb2ea066ff65 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py311h3778330_0.conda#6b1b19bdc407007d5e41079eab797ddc https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 -https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.3-h5192d8d_1.conda#aefbd04e8e6cabe1d24eb8ffa6c48fd5 +https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_0.conda#937834a2fb235626c3f8e8a83afd6b75 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 @@ -204,8 +205,8 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 @@ -216,24 +217,23 @@ https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1 https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.20.2-h2a5cb19_18.conda#7313674073496cec938f73b71163bc31 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-20_linux64_openblas.conda#9932a1d4e9ecf2d35fb19475446e361e https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a +https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h7b9373a_16.conda#54db1af780a69493a2e0675113a027f9 https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 +https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 -https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 -https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.0-py311h39c9aba_9_cpu.conda#c35fe329bcc51a1a3a254c990ba8f738 https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-hc240232_7.conda#fa3bbe293d907990f3ca5b8b9d4b10f0 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 -https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.0-py311h39c9aba_9_cpu.conda#c35fe329bcc51a1a3a254c990ba8f738 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af +https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b # pip pytz @ https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl#sha256=5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 # pip pandas @ https://files.pythonhosted.org/packages/fa/fe/c81ad3991f2c6aeacf01973f1d37b1dc76c0682f312f104741602a9557f1/pandas-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=e252a9e49b233ff96e2815c67c29702ac3a062098d80a170c506dff3470fd060 diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index e9c19a640ce61..3790d3c3dad73 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -5,19 +5,19 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 @@ -29,7 +29,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.c https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -95,7 +95,7 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py311h8032f78_0.conda#78d3e3073a999e662385c9a80d84ecec +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.conda#3ac73c673df24589b5b84d43a4afd235 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_1.conda#f4dda6316cc4718cbcab7009b5d60c41 diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock index 0dd79cc08c351..4a8d9e79263a5 100644 --- a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock @@ -14,20 +14,20 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda#8a86073cf3b343b87d03f41790d8b4e5 https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda#242d9f25d2ae60c76b38a5e42858e51d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_17.conda#18f0da832fb73029007218f0c56939f8 +https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_18.conda#939fb173e2a4d4e980ef689e99b35223 https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda#37eb311485d2d8b2c419449582046a42 https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda#1626967b574d1784b578b52eaeb071e7 https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda#1e610f2416b6acdd231c5f573d754a0f -https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda#1077e9333c41ff0be8edd1a5ec0ddace +https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda#4cb8e6b48f67de0b018719cdf1136306 https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_0.conda#3d3caf4ccc6415023640af4b1b33060a https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda#b785694dd3ec77a011ccf0c24725382b https://conda.anaconda.org/conda-forge/win-64/icu-78.2-h637d24d_0.conda#0ee3bb487600d5e71ab7d28951b2016a https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda#c1b81da6d29a14b542da14a36c9fbf3f https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda#444b0a45bbd1cb24f82eedb56721b9c4 https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e -https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda#8c9e4f1a0e688eef2e95711178061a0f +https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda#1c1ced969021592407f16ada4573586d https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda#720b39f5ec0610457b725eb3f396219a -https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_17.conda#3b93f0d28aa246cb74ed9b65250cae70 +https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda#b085746891cca3bd2704a450a7b4b5ce https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#64571d1dd6cdcfa25d0664a5950fdaa2 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda#56a686f92ac0273c0f6af58858a3f013 https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda#ba0bfd4c3cf73f299ffe46ff0eaeb8e3 @@ -66,7 +66,7 @@ https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py311h275cad7_2.c https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a8eebe_openblas.conda#1db756824d3aec6a25599c7821cb3e24 https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_3.conda#06e385238457018ad1071179b67e39d1 https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda#6e7c5c5ab485057b5d07fd8188ba5c28 -https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.3-h0c9aed9_1.conda#72e868a2bc363563f7a4bda95113c717 +https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.4-h0c9aed9_0.conda#275eb125dd1490f287e85ffd544b6403 https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hd232482_openblas.conda#78240c2b4322025a74e7e6edad247103 https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c @@ -100,6 +100,7 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-5_ha590de0_openblas.conda#e19a49b16cf765708e6d8676a50f74e1 https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h275cad7_4.conda#9fb1f375c704c5287c97c60f6a88d137 +https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda#a0b1b87e871011ca3b783bbf410bc39f https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py311h3f79411_0.conda#e5445b571c6e2919198c40c6db3d25c5 https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda#d69c21967f35eb2ce7f1f85d6b6022d3 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 @@ -108,11 +109,10 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bd https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.0-py311h9c22a71_1.conda#0d03c857517a5db3c1af5b553a528fac https://conda.anaconda.org/conda-forge/win-64/blas-2.305-openblas.conda#19bbf270f61bbef238e16a9509377a52 -https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.15.0-h765892d_1.conda#9bb0026a2131b09404c59c4290c697cd +https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda#52ea1beba35b69852d210242dd20f97d https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda#52ea1beba35b69852d210242dd20f97d https://conda.anaconda.org/conda-forge/win-64/harfbuzz-12.3.2-h5a1b470_0.conda#fb5d7b9527b418f83e3316f3e6daa8a2 https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.10.2-h68b6638_4.conda#f2dc18a6006aac4ac0050861c6df4120 https://conda.anaconda.org/conda-forge/win-64/pyside6-6.10.2-py311hf70c7b4_0.conda#8512eff5fd02b371f36b0da26f5a78ee diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 82bac4174f8c8..05dccd161d9d8 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -11,32 +11,32 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_117.conda#50d5470d29a25808d108d3917426d24b +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda#06901733131833f5edd68cf3d9679798 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_117.conda#97f8b7e451f960200c057ca83d92f9be +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 @@ -60,12 +60,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_17.conda#5edfb6baf1af52fa7c0a7072a42d1558 +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda#a587892d3c13b6621a6091be690dbca2 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -90,7 +90,7 @@ https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#43 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_1.conda#5b5846bc2b23e07a1d61b89dcb67fcf0 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_0.conda#b7113551db5a3e2403cdd052c66e9999 https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 @@ -116,7 +116,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.1-h8d634f6_0.conda#cc109dc1a4bedbd4f66c15502cb5df5b +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.3-h8d634f6_0.conda#792d5b6e99677177f5527a758a02bc07 https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 @@ -142,8 +142,9 @@ https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar. https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 https://conda.anaconda.org/conda-forge/noarch/doit-0.37.0-pyhcf101f3_0.conda#37b3d4c558f2bb2b5378c43f4d6f1fb5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hb1e0a52_17.conda#f5c501fe2a016ed0103f7a89d2ac0412 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -170,7 +171,7 @@ https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda# https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.1-pyhcf101f3_0.conda#9402ece5651f956de34cf0dc20dfc3a5 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda#4fefefb892ce9cc1539405bec2f1a6cd https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.24.1-pyhd8ed1ab_0.conda#7526d20621b53440b0aae45d4797847e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f @@ -184,7 +185,7 @@ https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1a https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda#a24add9a3bababee946f3bc1c829acfe -https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h2315fbb_0.conda#6c87a0f4566469af3585b11d89163fd7 +https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h57d2397_2.conda#759edfe34f07c5c4565b6c5ec0c7fb17 https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda#3893f7b40738f9fe87510cb4468cdda5 @@ -217,14 +218,14 @@ https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1 https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_0.conda#ea5be9abc2939c8431893b4e123a2065 https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda#7c5ebdc286220e8021bf55e6384acd67 https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_17.conda#4e58f090f75b2941346da3685564e7a7 +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_17.conda#ea4724804b89ddc81d16cabe3f4719b5 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_17.conda#8f02f68c780b0a6eeba034af3ed1c00a +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 @@ -261,12 +262,12 @@ https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda#85c https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda#f11a319b9700b203aa14c295858782b6 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311h724c32c_4.conda#d04e508f5a03162c8bab4586a65d00bf https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_17.conda#dfcfcc0c20762eeb840771eda366940e +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h9837d23_1.conda#e30309a8776e0e969fa7092d7801641b https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 @@ -277,7 +278,7 @@ https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.1-pyhcf101f3_ https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.0-py311h8032f78_0.conda#78d3e3073a999e662385c9a80d84ecec +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.conda#3ac73c673df24589b5b84d43a4afd235 https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 @@ -286,9 +287,8 @@ https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_17.conda#329ef645bc2f75b4025cba573810e178 -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_17.conda#eae8e3fb1f5eecb829dd7347d33ecacb -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.0-pyhcf101f3_0.conda#97624651e6fc9ca05effe0b4a80766e3 @@ -296,9 +296,10 @@ https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.1.28-pyhd8ed1ab_0.conda#e8d6529858171ac4babb28c334306c0d +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.2.20-pyhd8ed1ab_0.conda#9ee854e39faa623a8e79ae20ac374f1f https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f @@ -306,20 +307,19 @@ https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py311he4c1a5a_0.conda#7287f5cca6b7f82571c1911a43e924b0 https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py311h2a99c40_0.conda#557f5d7ca735d89d706742bc19cd7e26 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyhe01879c_0.conda#31e11c30bbee1682a55627f953c6725a https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.1-pyhbbac1ac_0.conda#d8f030e3730713c93a358fdb46f08281 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py311he4c1a5a_0.conda#7287f5cca6b7f82571c1911a43e924b0 https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.0-pyhcf101f3_0.conda#b14079a39ae60ac7ad2ec3d9eab075ca https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda#d79a87dcfa726bcea8e61275feed6f83 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.0-pyhcf101f3_1.conda#e53b79419913df0b84f7c3af7727122b +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.1-pyhcf101f3_0.conda#1f90643873d0cc2f7b0bf2752db71016 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda#837aaf71ddf3b27acae0e7e9015eebc6 https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda#bf22cb9c439572760316ce0748af3713 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 43dfd51122332..670e19a21060b 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -12,28 +12,28 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_117.conda#50d5470d29a25808d108d3917426d24b +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda#06901733131833f5edd68cf3d9679798 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_17.conda#51b78c6a757575c0d12f4401ffc67029 -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_117.conda#97f8b7e451f960200c057ca83d92f9be +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_17.conda#3c281169ea25b987311400d7a7e28445 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 -https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda#51a19bba1b8ebfb60df25cde030b7ebc +https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda#f9f81ea472684d75b9dd8d0b328cf655 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda#8b09ae86839581147ef2e5c5e229d164 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_17.conda#1478bfa85224a65ab096d69ffd2af1e5 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_17.conda#202fdf8cad9eea704c2b0d823d1732bf +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 @@ -42,7 +42,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_17.conda#24c2fe35fa45cd71214beba6f337c071 +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 @@ -69,11 +69,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_17.conda#a6c682ac611cb1fa4d73478f9e6efb06 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_17.conda#5edfb6baf1af52fa7c0a7072a42d1558 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_17.conda#ea12f5a6bf12c88c06750d9803e1a570 +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -100,8 +100,8 @@ https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#43 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_17.conda#d7954bb54fc77e7952a78e5e0d134df5 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.3-h6548e54_1.conda#5b5846bc2b23e07a1d61b89dcb67fcf0 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_0.conda#b7113551db5a3e2403cdd052c66e9999 https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 @@ -118,7 +118,7 @@ https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-de https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.3-hf516916_1.conda#5ebd79c20c7ecf979f20e26fedc0a4fd +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_0.conda#70a09b6817c7ad694ef4543204c59c25 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda#22d5cc5fb45aab8ed3c00cde2938b825 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e @@ -127,7 +127,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.1-h8d634f6_0.conda#cc109dc1a4bedbd4f66c15502cb5df5b +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.3-h8d634f6_0.conda#792d5b6e99677177f5527a758a02bc07 https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 @@ -147,8 +147,9 @@ https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4 https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hb1e0a52_17.conda#f5c501fe2a016ed0103f7a89d2ac0412 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -166,7 +167,7 @@ https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.1-pyhcf101f3_0.conda#9402ece5651f956de34cf0dc20dfc3a5 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda#4fefefb892ce9cc1539405bec2f1a6cd https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f @@ -194,14 +195,14 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0 https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_0.conda#ea5be9abc2939c8431893b4e123a2065 -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_17.conda#4e58f090f75b2941346da3685564e7a7 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.15.0-h7e30c49_1.conda#8f5b0b297b59e1ac160ad4beec99dbee https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_17.conda#ea4724804b89ddc81d16cabe3f4719b5 -https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.3-h5192d8d_1.conda#aefbd04e8e6cabe1d24eb8ffa6c48fd5 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_17.conda#8f02f68c780b0a6eeba034af3ed1c00a +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd +https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_0.conda#937834a2fb235626c3f8e8a83afd6b75 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 @@ -219,11 +220,11 @@ https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_17.conda#dfcfcc0c20762eeb840771eda366940e +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 @@ -233,25 +234,25 @@ https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_ https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_17.conda#329ef645bc2f75b4025cba573810e178 -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_17.conda#eae8e3fb1f5eecb829dd7347d33ecacb -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.4-pyhd8ed1ab_2.conda#bb0230917e2473c77d615104dbe8a49d https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad +https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f +https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 -https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e -https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 +https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-hc240232_7.conda#fa3bbe293d907990f3ca5b8b9d4b10f0 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h9837d23_1.conda#e30309a8776e0e969fa7092d7801641b @@ -259,15 +260,14 @@ https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda# https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.conda#643f8cb35133eb1be4919fb953f0a25f https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 +https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.8.0-py311h9f3472d_0.conda#17334e5c12abdf2db6b25bd4187cd3e4 -https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-hc240232_7.conda#fa3bbe293d907990f3ca5b8b9d4b10f0 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b -https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.1.28-pyhd8ed1ab_0.conda#e8d6529858171ac4babb28c334306c0d +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.2.20-pyhd8ed1ab_0.conda#9ee854e39faa623a8e79ae20ac374f1f https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.22.0-py311h320fe9a_2.conda#e94b7f09b52628b89e66cdbd8c3029dd https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.12.0-pyhd8ed1ab_0.tar.bz2#05ee2fb22c1eca4309c06d11aff049f3 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 355dd9fe7c0be..5ea8743d3ed2b 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.conda#9e115653741810778c9a915a2f8439e7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_17.conda#0ad9074c91b35dbf8b58bc68a9f9bda0 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda#4faa39bf919939602e594253bd673958 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda#468fd3bb9e1f671d36c2cbc677e56f1d @@ -16,22 +16,22 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda#cf105bce884e4ef8c8ccdca9fe6695e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_17.conda#0d842d2053b95a6dbb83554948e7cbfe +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda#552567ea2b61e3a3035759b2fdb3f9a6 https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.3-he30d5cf_0.conda#4a98cbc4ade694520227402ff8880630 -https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_8.conda#2921ac0b541bf37c69e66bd6d9a43bca +https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda#840d8fc0d7b3209be93080bc20e07f2d https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda#e7df0aab10b9cbb73ab2a467ebfaf8c7 https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d5cf_1.conda#8ec1d03f3000108899d1799d9964f281 https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda#a9138815598fe6b91a1d6782ca657b0c -https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.3-hfae3067_0.conda#b414e36fbb7ca122030276c75fa9c34a +https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda#57f3b3da02a50a1be2a6fe847515417d https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda#2f364feefb6a7c00423e80dcb12db62a -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_17.conda#bcd31f4a57798bd158dfc0647fa77ca3 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_17.conda#577bd91c44237433e010e9b96aea7ee0 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda#4feebd0fbf61075a1a9c2e9b3936c257 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda#574d88ce3348331e962cfa5ed451b247 https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda#5a86bf847b9b926f3a4f203339748d78 https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda#5109d7f837a3dfdf5c60f60e311b041f https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda#96944e3c92386a12755b94619bae0b35 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_17.conda#500d275cb616d81b5d9828aedffc4bc3 +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda#cf2861212053d05f27ec49c3784ff8bb https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda#08aad7cbe9f5a6b460d0976076b6ae64 @@ -50,11 +50,11 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda#6553a5d017fe14859ea8a4e6ea5def8f https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda#2079727b538f6dd16f3fa579d4c3c53f https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda#fb640d776fc92b682a14e001980825b1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_17.conda#7fa4f07979f7aff0938e5664f43f7053 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda#41f261f5e4e2e8cbd236c2f1f15dae1b https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.3.0-h5ad3122_1.conda#c11818b31f7c054ce220041b2459aacb https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda#be4088903b94ea297975689b3c3aeb27 -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_17.conda#beb8c015b02b7a1c2eea6d7a9847f8f5 +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_18.conda#699d294376fe18d80b7ce7876c3a875d https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda#b4df5d7d4b63579d081fd3a4cf99740e https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda#8b5222a41b5d51fb1a5a2c514e770218 @@ -71,7 +71,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.12.3-h185addb_0.co https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.21.3-h50a48e9_0.conda#29c10432a2ca1472b53f299ffb2ffa37 https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda#35b2ae7fadf364b8e5fb8185aaeb80e5 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.1-hdae7a39_0.conda#9c2f56b6e011c6d8010ff43b796aab2f -https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.3-hf53f6bf_1.conda#9590055a5bc67692dbc2f6176df96a38 +https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_0.conda#81dd1078cd9366563f977918f60a1b31 https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.2-h10b116e_0.conda#4e3ba0d5d192f99217b85f07a0761e64 https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d @@ -103,6 +103,7 @@ https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda# https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.4-py311hdc11669_0.conda#931a90956062cc7219c6bce6c6ccfe7f https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 +https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda#0fed1ff55f4938a65907f3ecf62609db https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.1-h8af1aa0_0.conda#0c8f36ebd3678eed1685f0fc93fc2175 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.4.9-py311h229e7f7_2.conda#18358d47ebdc1f936003b7d407c9e16f @@ -135,9 +136,9 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdamage-1.1.6-h86ec https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda#eeee3bdb31c6acde2b81ad1b8c287087 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda#1f64c613f0b8d67e9fb0e165d898fb6b https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.7-he30d5cf_0.conda#b15ca02584678f38df6e114c32f93959 +https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.4-py311h2dad8b0_0.conda#6fcc144f2f5c3537297288e61d09e8f2 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.15.0-h8dda3cd_1.conda#112b71b6af28b47c624bcbeefeea685b https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.1-py311h164a683_0.conda#b59452fef1470e7e5c34a7c5deefe853 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_3.conda#4ba7653ca09e74e8968120c6aea4bfb1 @@ -151,14 +152,13 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-5_h9678261_openblas.conda#33a0e650392a79b56ae0bfa3db02ddbf -https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311h04741b4_4.conda#1eeea54b0c520a475db39f8c711de661 +https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-12.3.2-h1134a53_0.conda#f8ab08bc3716972b7bd47e48a6884260 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.0-py311h399493a_1.conda#ea481eda36e28a2487d0fe2891d168ff https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.305-openblas.conda#2efe635198609d0d2a122c6a0923b8f8 -https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-12.3.2-h1134a53_0.conda#f8ab08bc3716972b7bd47e48a6884260 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 From ce4f2340fecb280fc33163a1437042e1d98f2356 Mon Sep 17 00:00:00 2001 From: antoinebaker Date: Mon, 23 Feb 2026 11:29:27 +0100 Subject: [PATCH 238/462] FIX instability of `_RidgeGCV` (#33020) Co-authored-by: Olivier Grisel Co-authored-by: Omar Salman Co-authored-by: Christian Lorentzen --- doc/modules/array_api.rst | 4 +- doc/modules/linear_model.rst | 4 +- .../array-api/33020.enhancement.rst | 3 + .../sklearn.linear_model/33020.fix.rst | 10 + sklearn/linear_model/_ridge.py | 625 ++++++++++-------- sklearn/linear_model/tests/test_ridge.py | 303 +++++++-- 6 files changed, 598 insertions(+), 351 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/33020.enhancement.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33020.fix.rst diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index 5f5ef5c73326e..82cd26cf497a0 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -134,9 +134,9 @@ Estimators - :class:`kernel_approximation.Nystroem` - :class:`linear_model.LogisticRegression` (with `solver="lbfgs"`) - :class:`linear_model.Ridge` (with `solver="svd"`) -- :class:`linear_model.RidgeCV` (with `solver="svd"`, see :ref:`device_support_for_float64`) +- :class:`linear_model.RidgeCV` (see :ref:`device_support_for_float64`) - :class:`linear_model.RidgeClassifier` (with `solver="svd"`) -- :class:`linear_model.RidgeClassifierCV` (with `solver="svd"`, see :ref:`device_support_for_float64`) +- :class:`linear_model.RidgeClassifierCV` (see :ref:`device_support_for_float64`) - :class:`discriminant_analysis.LinearDiscriminantAnalysis` (with `solver="svd"`) - :class:`naive_bayes.GaussianNB` - :class:`preprocessing.Binarizer` diff --git a/doc/modules/linear_model.rst b/doc/modules/linear_model.rst index 179237441703a..5f1db0f6c4e3b 100644 --- a/doc/modules/linear_model.rst +++ b/doc/modules/linear_model.rst @@ -213,11 +213,11 @@ Usage example:: >>> import numpy as np >>> from sklearn import linear_model >>> reg = linear_model.RidgeCV(alphas=np.logspace(-6, 6, 13)) - >>> reg.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1]) + >>> reg.fit([[0, 0], [0, 0.1], [1, 1]], [0, -0.1, 1]) RidgeCV(alphas=array([1.e-06, 1.e-05, 1.e-04, 1.e-03, 1.e-02, 1.e-01, 1.e+00, 1.e+01, 1.e+02, 1.e+03, 1.e+04, 1.e+05, 1.e+06])) >>> reg.alpha_ - np.float64(0.01) + np.float64(0.1) Specifying the value of the :term:`cv` attribute will trigger the use of cross-validation with :class:`~sklearn.model_selection.GridSearchCV`, for diff --git a/doc/whats_new/upcoming_changes/array-api/33020.enhancement.rst b/doc/whats_new/upcoming_changes/array-api/33020.enhancement.rst new file mode 100644 index 0000000000000..ff677c1b30556 --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/33020.enhancement.rst @@ -0,0 +1,3 @@ +- :class:`linear_model.RidgeCV` now accepts array API compliant arrays + with `gcv_mode` set to `auto` or `eigen`. + By :user:`Antoine Baker ` diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33020.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33020.fix.rst new file mode 100644 index 0000000000000..5a4c715edbc12 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33020.fix.rst @@ -0,0 +1,10 @@ +- The leave-one out errors and model parameters estimated in + :class:`linear_model.RidgeCV` and :class:`linear_model.RidgeClassifierCV` when + `cv=None` are now numerically stable in the small `alpha` regime. The default + `auto` option is now equivalent to `eigen` and picks the cheaper option: + eigendecomposition of the covariance matrix when `n_features <= n_samples`, + respectively of the Gram matrix when `n_samples > n_features`. When + `store_cv_results=True` and `X` is an integer array, the `cv_results_` + attribute was wrongly coerced to the integer dtype of `X`, it now always has a + float dtype. + By :user:`Antoine Baker ` diff --git a/sklearn/linear_model/_ridge.py b/sklearn/linear_model/_ridge.py index 344ef1307b796..bc8c892f66564 100644 --- a/sklearn/linear_model/_ridge.py +++ b/sklearn/linear_model/_ridge.py @@ -60,7 +60,6 @@ _routing_enabled, process_routing, ) -from sklearn.utils.sparsefuncs import mean_variance_axis from sklearn.utils.validation import ( _check_sample_weight, check_is_fitted, @@ -1619,13 +1618,24 @@ def __sklearn_tags__(self): def _check_gcv_mode(X, gcv_mode): - if gcv_mode in ["eigen", "svd"]: - return gcv_mode - # if X has more rows than columns, use decomposition of X^T.X, - # otherwise X.X^T - if X.shape[0] > X.shape[1]: - return "svd" - return "eigen" + # svd only implemented for dense X + if gcv_mode == "svd": + if sparse.issparse(X): + # TODO(1.11) raise ValueError + msg = ( + "The 'svd' mode is not supported for sparse X, we fallback to " + "`gcv_mode='eigen'`. Passing `gcv_mode='svd'` on sparse X will raise " + "an error in 1.11, use the default or pass `gcv_mode='eigen'` to " + "suppress this warning." + ) + warnings.warn(msg, FutureWarning) + else: + return "svd" + + # All other cases ("auto", "eigen") + # fallbacks to gram (n <= p) or cov (p < n) + n, p = X.shape + return "gram" if n <= p else "cov" def _find_smallest_angle(query, vectors): @@ -1768,37 +1778,81 @@ class _RidgeGCV(LinearModel): Notes ----- - We want to solve (K + alpha*Id)c = y, - where K = X X^T is the kernel matrix. + 1. Unweighted and no intercept - Let G = (K + alpha*Id). + We start by the simplest case `fit_intercept=False` and `sample_weight=None`. + The other cases (see below) reduce to this one after proper scaling/centering + of the design matrix X. - Dual solution: c = G^-1y - Primal solution: w = X^T c + The design matrix X has shape (n, p) = (n_samples, n_features). - Compute eigendecomposition K = Q V Q^T. - Then G^-1 = Q (V + alpha*Id)^-1 Q^T, - where (V + alpha*Id) is diagonal. - It is thus inexpensive to inverse for many alphas. + Let G = (K + alpha*Id_n) where K = X X' is the Gram matrix and Id_n is the + identity matrix of size n. - Let loov be the vector of prediction values for each example - when the model was fitted with all examples but this example. + Let H = (C + alpha*Id_p) where C = X' X is the covariance matrix and Id_p + is the identity matrix of size p. - loov = (KG^-1Y - diag(KG^-1)Y) / diag(I-KG^-1) + The solution of the regularized least square (fitted `coef_`) is given by: + w = H^-1 X' y = X' c where c = G^-1 y. - Let looe be the vector of prediction errors for each example - when the model was fitted with all examples but this example. - - looe = y - loov = c / diag(G^-1) + Let loov (resp looe) be the leave-one-out values (resp errors), that is the + vector of predictions (resp errors) for each single observation when the model + was fitted with all examples but this example. As shown in [1]: + looe = y - loov = c / d where d = diag(G^-1). The best score (negative mean squared error or user-provided scoring) is stored in the `best_score_` attribute, and the selected hyperparameter in `alpha_`. + 2. Leveraging a precomputed matrix decomposition + + The leave-one-out errors and coefficients can be efficiently computed for any + alpha from the SVD of X, or the eigendecomposition of K = X X' or C = X' X. + + Reduced SVD X = U S V' when n < p (wide X) + Let D = 1 / (S^2 + alpha) + c = U D U' y + d = diag(U D U') + w = V S / (S^2 + alpha) U' y + + Eigendecomposition K = U L U' + Let D = 1 / (L + alpha) + c = U D U' y + d = diag(U D U') + w = X' c. + + Reduced SVD X = U S V' when p < n (long X) + Let M = alpha / (S^2 + alpha) - 1 + alpha c = y + U M U' y + alpha d = 1 + diag(U M U') + w = V S / (S^2 + alpha) U' y + + Eigendecomposition C = V L V' + H^-1 = V 1 / (L + alpha) V' + alpha c = y - X H^-1 X' y + alpha d = 1 - diag(X H^-1 X') + w = H^-1 X' y + + 3. Fitting with intercept or sample weights + + Fitting with intercept and/or sample weights reduces to the unweigthed no + intercept case after centering and/or rescaling of X and y, as done in + `_preprocess_data`: + X <- sqrt(s) (X - X_mean) + y <- sqrt(s) (y - y_mean) + + The returned looe are also rescaled by sample weights: + looe <- sqrt(s) looe + + If we fit an intercept, there is the following correction term: + d <- d - sqrt(s) * G^-1 sqrt(s) / sum(s) + References ---------- - [1] http://cbcl.mit.edu/publications/ps/MIT-CSAIL-TR-2007-025.pdf - [2] https://www.mit.edu/~9.520/spring07/Classes/rlsslides.pdf + .. [1] R. Rifkin and R. Lippert (2007). "Notes on Regularized Least Squares." + https://dspace.mit.edu/bitstream/handle/1721.1/37318/MIT-CSAIL-TR-2007-025.pdf + .. [2] R. Rifkin (2007). "Regularized Least Squares." + https://www.mit.edu/~9.520/spring07/Classes/rlsslides.pdf """ def __init__( @@ -1824,7 +1878,7 @@ def __init__( @staticmethod def _decomp_diag(v_prime, Q): - # compute diagonal of the matrix: dot(Q, dot(diag(v_prime), Q^T)) + # compute diagonal of the matrix: dot(Q, dot(diag(v_prime), Q.T)) xp, _ = get_namespace(v_prime, Q) return xp.sum(v_prime * Q**2, axis=1) @@ -1837,307 +1891,291 @@ def _diag_dot(D, B): D = D[(slice(None),) + (None,) * (len(B.shape) - 1)] return D * B - def _compute_gram(self, X, sqrt_sw): - """Computes the Gram matrix XX^T with possible centering. + def _compute_gram(self, X, X_mean, sqrt_sw): + """Computes the Gram matrix X X' with possible centering. Parameters ---------- - X : {ndarray, sparse matrix} of shape (n_samples, n_features) + X : {ndarray, sparse matrix, sparse array} of shape (n_samples, n_features) The preprocessed design matrix. + X_mean : ndarray of shape (n_feature,) + The weighted mean of X for each feature. + sqrt_sw : ndarray of shape (n_samples,) - square roots of sample weights + Square roots of sample weights. Returns ------- gram : ndarray of shape (n_samples, n_samples) The Gram matrix. - X_mean : ndarray of shape (n_feature,) - The weighted mean of ``X`` for each feature. Notes ----- - When X is dense the centering has been done in preprocessing - so the mean is 0 and we just compute XX^T. - - When X is sparse it has not been centered in preprocessing, but it has - been scaled by sqrt(sample weights). - When self.fit_intercept is False no centering is done. - The centered X is never actually computed because centering would break - the sparsity of X. + When X is dense the centering has been done in preprocessing + so the mean is 0 and we just compute X X'. + + When X is sparse it has not been centered in preprocessing, but + it has been scaled by sqrt_sw. The centered X is never actually + computed because centering would break the sparsity of X. """ - xp, _ = get_namespace(X) center = self.fit_intercept and sparse.issparse(X) if not center: # in this case centering has been done in preprocessing # or we are not fitting an intercept. - X_mean = xp.zeros(X.shape[1], dtype=X.dtype) - return safe_sparse_dot(X, X.T, dense_output=True), X_mean - # X is sparse - n_samples = X.shape[0] - sample_weight_matrix = sparse.dia_matrix( - (sqrt_sw, 0), shape=(n_samples, n_samples) - ) - X_weighted = sample_weight_matrix.dot(X) - X_mean, _ = mean_variance_axis(X_weighted, axis=0) - X_mean *= n_samples / sqrt_sw.dot(sqrt_sw) - X_mX = sqrt_sw[:, None] * safe_sparse_dot(X_mean, X.T, dense_output=True) - X_mX_m = np.outer(sqrt_sw, sqrt_sw) * np.dot(X_mean, X_mean) + return safe_sparse_dot(X, X.T, dense_output=True) + # X is sparse and fit_intercept is True + # centered matrix = X - sqrt_sw X_mean' + X_Xm = safe_sparse_dot(X, X_mean, dense_output=True) return ( - safe_sparse_dot(X, X.T, dense_output=True) + X_mX_m - X_mX - X_mX.T, - X_mean, + safe_sparse_dot(X, X.T, dense_output=True) + - X_Xm[:, None] * sqrt_sw[None, :] + - sqrt_sw[:, None] * X_Xm[None, :] + + (X_mean @ X_mean) * sqrt_sw[:, None] * sqrt_sw[None, :] ) - def _compute_covariance(self, X, sqrt_sw): - """Computes covariance matrix X^TX with possible centering. + def _compute_covariance(self, X, X_mean, sqrt_sw): + """Computes covariance matrix X' X with possible centering. Parameters ---------- - X : sparse matrix of shape (n_samples, n_features) + X : {ndarray, sparse matrix, sparse array} of shape (n_samples, n_features) The preprocessed design matrix. + X_mean : ndarray of shape (n_feature,) + The weighted mean of X for each feature. + sqrt_sw : ndarray of shape (n_samples,) - square roots of sample weights + Square roots of sample weights. Returns ------- covariance : ndarray of shape (n_features, n_features) The covariance matrix. - X_mean : ndarray of shape (n_feature,) - The weighted mean of ``X`` for each feature. Notes ----- - Since X is sparse it has not been centered in preprocessing, but it has - been scaled by sqrt(sample weights). - When self.fit_intercept is False no centering is done. - The centered X is never actually computed because centering would break - the sparsity of X. + When X is dense the centering has been done in preprocessing + so the mean is 0 and we just compute X' X. + + When X is sparse it has not been centered in preprocessing, but + it has been scaled by sqrt_sw. The centered X is never actually + computed because centering would break the sparsity of X. """ - if not self.fit_intercept: + center = self.fit_intercept and sparse.issparse(X) + if not center: # in this case centering has been done in preprocessing # or we are not fitting an intercept. - X_mean = np.zeros(X.shape[1], dtype=X.dtype) - return safe_sparse_dot(X.T, X, dense_output=True), X_mean - # this function only gets called for sparse X - n_samples = X.shape[0] - sample_weight_matrix = sparse.dia_matrix( - (sqrt_sw, 0), shape=(n_samples, n_samples) - ) - X_weighted = sample_weight_matrix.dot(X) - X_mean, _ = mean_variance_axis(X_weighted, axis=0) - X_mean = X_mean * n_samples / sqrt_sw.dot(sqrt_sw) - weight_sum = sqrt_sw.dot(sqrt_sw) + return safe_sparse_dot(X.T, X, dense_output=True) + # X is sparse and fit_intercept is True + # centered matrix = X - sqrt_sw X_mean' + sw_sum = sqrt_sw @ sqrt_sw return ( safe_sparse_dot(X.T, X, dense_output=True) - - weight_sum * np.outer(X_mean, X_mean), - X_mean, + - sw_sum * X_mean[:, None] * X_mean[None, :] ) def _sparse_multidot_diag(self, X, A, X_mean, sqrt_sw): - """Compute the diagonal of (X - X_mean).dot(A).dot((X - X_mean).T) - without explicitly centering X nor computing X.dot(A) - when X is sparse. + """Compute the diagonal of X A X' with possible centering. Parameters ---------- - X : sparse matrix of shape (n_samples, n_features) + X : {ndarray, sparse matrix, sparse array} of shape (n_samples, n_features) + The preprocessed design matrix. A : ndarray of shape (n_features, n_features) + The inner matrix. - X_mean : ndarray of shape (n_features,) + X_mean : ndarray of shape (n_feature,) + The weighted mean of X for each feature. - sqrt_sw : ndarray of shape (n_features,) - square roots of sample weights + sqrt_sw : ndarray of shape (n_samples,) + Square roots of sample weights. Returns ------- diag : np.ndarray, shape (n_samples,) The computed diagonal. - """ - intercept_col = scale = sqrt_sw - batch_size = X.shape[1] - diag = np.empty(X.shape[0], dtype=X.dtype) - for start in range(0, X.shape[0], batch_size): - batch = slice(start, min(X.shape[0], start + batch_size), 1) - X_batch = np.empty( - (X[batch].shape[0], X.shape[1] + self.fit_intercept), dtype=X.dtype - ) - if self.fit_intercept: - X_batch[:, :-1] = X[batch].toarray() - X_mean * scale[batch][:, None] - X_batch[:, -1] = intercept_col[batch] - else: - X_batch = X[batch].toarray() - diag[batch] = (X_batch.dot(A) * X_batch).sum(axis=1) - return diag - def _eigen_decompose_gram(self, X, y, sqrt_sw): - """Eigendecomposition of X.X^T, used when n_samples <= n_features.""" - # if X is dense it has already been centered in preprocessing - xp, is_array_api = get_namespace(X) - K, X_mean = self._compute_gram(X, sqrt_sw) - if self.fit_intercept: - # to emulate centering X with sample weights, - # ie removing the weighted average, we add a column - # containing the square roots of the sample weights. - # by centering, it is orthogonal to the other columns - K += xp.linalg.outer(sqrt_sw, sqrt_sw) - eigvals, Q = xp.linalg.eigh(K) - QT_y = Q.T @ y - return X_mean, eigvals, Q, QT_y + Notes + ----- + When self.fit_intercept is False no centering is done. - def _solve_eigen_gram(self, alpha, y, sqrt_sw, X_mean, eigvals, Q, QT_y): - """Compute dual coefficients and diagonal of G^-1. + When X is dense the centering has been done in preprocessing + so the mean is 0 and we just compute diag(X A X'). - Used when we have a decomposition of X.X^T (n_samples <= n_features). + When X is sparse it has not been centered in preprocessing, but + it has been scaled by sqrt_sw. The centered X is never actually + computed because centering would break the sparsity of X. """ - xp, is_array_api = get_namespace(eigvals) - w = 1.0 / (eigvals + alpha) - if self.fit_intercept: - # the vector containing the square roots of the sample weights (1 - # when no sample weights) is the eigenvector of XX^T which - # corresponds to the intercept; we cancel the regularization on - # this dimension. the corresponding eigenvalue is - # sum(sample_weight). - norm = xp.linalg.vector_norm if is_array_api else np.linalg.norm - normalized_sw = sqrt_sw / norm(sqrt_sw) - intercept_dim = _find_smallest_angle(normalized_sw, Q) - w[intercept_dim] = 0 # cancel regularization for the intercept - - c = Q @ self._diag_dot(w, QT_y) - G_inverse_diag = self._decomp_diag(w, Q) - # handle case where y is 2-d - if len(y.shape) != 1: - G_inverse_diag = G_inverse_diag[:, None] - return G_inverse_diag, c - - def _eigen_decompose_covariance(self, X, y, sqrt_sw): - """Eigendecomposition of X^T.X, used when n_samples > n_features - and X is sparse. - """ - n_samples, n_features = X.shape - cov = np.empty((n_features + 1, n_features + 1), dtype=X.dtype) - cov[:-1, :-1], X_mean = self._compute_covariance(X, sqrt_sw) - if not self.fit_intercept: - cov = cov[:-1, :-1] - # to emulate centering X with sample weights, - # ie removing the weighted average, we add a column - # containing the square roots of the sample weights. - # by centering, it is orthogonal to the other columns - # when all samples have the same weight we add a column of 1 + xp, _ = get_namespace(X) + XA = X @ A + if sparse.isspmatrix(X): + # sparse matrix use multiply for element wise multiplication + XAX = np.ravel(X.multiply(XA).sum(axis=1)) else: - cov[-1] = 0 - cov[:, -1] = 0 - cov[-1, -1] = sqrt_sw.dot(sqrt_sw) - nullspace_dim = max(0, n_features - n_samples) - eigvals, V = linalg.eigh(cov) - # remove eigenvalues and vectors in the null space of X^T.X - eigvals = eigvals[nullspace_dim:] - V = V[:, nullspace_dim:] - return X_mean, eigvals, V, X - - def _solve_eigen_covariance_no_intercept( - self, alpha, y, sqrt_sw, X_mean, eigvals, V, X + XAX = xp.sum(XA * X, axis=1) + center = self.fit_intercept and sparse.issparse(X) + if not center: + # in this case centering has been done in preprocessing + # or we are not fitting an intercept. + return XAX + # X is sparse and fit_intercept is True + # centered matrix = X - sqrt_sw X_mean' + XA_Xm = XA @ X_mean + A_Xm = A @ X_mean + sw = sqrt_sw * sqrt_sw + return XAX - 2 * sqrt_sw * XA_Xm + sw * (X_mean @ A_Xm) + + def _eigen_decompose_gram(self, X, X_mean, y, sqrt_sw): + """Eigendecomposition of Gram matrix X X'""" + xp, is_array_api = get_namespace(X) + K = self._compute_gram(X, X_mean, sqrt_sw) + eigvals, Q = xp.linalg.eigh(K) + QT_y = Q.T @ y + QT_sqrt_sw = Q.T @ sqrt_sw + XT = X.T + return eigvals, Q, QT_y, QT_sqrt_sw, XT, X_mean + + def _solve_eigen_gram( + self, alpha, y, sqrt_sw, eigvals, Q, QT_y, QT_sqrt_sw, XT, X_mean ): - """Compute dual coefficients and diagonal of G^-1. + """Compute looe and coef when we have a decomposition of X X'""" + D = 1.0 / (eigvals + alpha) + c = Q @ self._diag_dot(D, QT_y) + d = self._decomp_diag(D, Q) + if self.fit_intercept: + sw_sum = sqrt_sw @ sqrt_sw + Ginv_sqrt_sw = Q @ self._diag_dot(D, QT_sqrt_sw) + d -= Ginv_sqrt_sw * sqrt_sw / sw_sum + if y.ndim == 2: + d = d[:, None] + XT_c = XT @ c + if self.fit_intercept and sparse.issparse(XT): + # centered matrix = X - sqrt_sw X_mean' + if y.ndim == 2: + XT_c -= X_mean[:, None] * (sqrt_sw @ c) + else: + XT_c -= X_mean * (sqrt_sw @ c) + looe = c / d + coef = XT_c + return looe, coef - Used when we have a decomposition of X^T.X - (n_samples > n_features and X is sparse), and not fitting an intercept. - """ - w = 1 / (eigvals + alpha) - A = (V * w).dot(V.T) - AXy = A.dot(safe_sparse_dot(X.T, y, dense_output=True)) - y_hat = safe_sparse_dot(X, AXy, dense_output=True) - hat_diag = self._sparse_multidot_diag(X, A, X_mean, sqrt_sw) - if len(y.shape) != 1: - # handle case where y is 2-d - hat_diag = hat_diag[:, np.newaxis] - return (1 - hat_diag) / alpha, (y - y_hat) / alpha + def _eigen_decompose_covariance(self, X, X_mean, y, sqrt_sw): + """Eigendecomposition of covariance matrix X' X""" + xp, is_array_api = get_namespace(X) + cov = self._compute_covariance(X, X_mean, sqrt_sw) + eigvals, V = xp.linalg.eigh(cov) + XT_y = safe_sparse_dot(X.T, y, dense_output=True) + XT_sqrt_sw = safe_sparse_dot(X.T, sqrt_sw, dense_output=True) + if self.fit_intercept and sparse.issparse(X): + # centered matrix = X - sqrt_sw X_mean' + if y.ndim == 2: + XT_y -= X_mean[:, None] * (sqrt_sw @ y) + else: + XT_y -= X_mean * (sqrt_sw @ y) + XT_sqrt_sw -= X_mean * (sqrt_sw @ sqrt_sw) + return eigvals, V, X, X_mean, XT_y, XT_sqrt_sw - def _solve_eigen_covariance_intercept( - self, alpha, y, sqrt_sw, X_mean, eigvals, V, X + def _solve_eigen_covariance( + self, alpha, y, sqrt_sw, eigvals, V, X, X_mean, XT_y, XT_sqrt_sw ): - """Compute dual coefficients and diagonal of G^-1. - - Used when we have a decomposition of X^T.X - (n_samples > n_features and X is sparse), - and we are fitting an intercept. - """ - # the vector [0, 0, ..., 0, 1] - # is the eigenvector of X^TX which - # corresponds to the intercept; we cancel the regularization on - # this dimension. the corresponding eigenvalue is - # sum(sample_weight), e.g. n when uniform sample weights. - intercept_sv = np.zeros(V.shape[0]) - intercept_sv[-1] = 1 - intercept_dim = _find_smallest_angle(intercept_sv, V) - w = 1 / (eigvals + alpha) - w[intercept_dim] = 1 / eigvals[intercept_dim] - A = (V * w).dot(V.T) - # add a column to X containing the square roots of sample weights - X_op = _X_CenterStackOp(X, X_mean, sqrt_sw) - AXy = A.dot(X_op.T.dot(y)) - y_hat = X_op.dot(AXy) - hat_diag = self._sparse_multidot_diag(X, A, X_mean, sqrt_sw) - # return (1 - hat_diag), (y - y_hat) - if len(y.shape) != 1: - # handle case where y is 2-d - hat_diag = hat_diag[:, np.newaxis] - return (1 - hat_diag) / alpha, (y - y_hat) / alpha + """Compute looe and coef when we have a decomposition of X' X""" + D = 1 / (eigvals + alpha) + Hinv = (V * D) @ V.T + Hinv_XT_y = Hinv @ XT_y + Hinv_XT_sqrt_sw = Hinv @ XT_sqrt_sw + X_Hinv_XT_y = safe_sparse_dot(X, Hinv_XT_y, dense_output=True) + X_Hinv_XT_sqrt_sw = safe_sparse_dot(X, Hinv_XT_sqrt_sw, dense_output=True) + if self.fit_intercept and sparse.issparse(X): + # centered = X - sqrt_sw X_mean' + if y.ndim == 2: + X_Hinv_XT_y -= sqrt_sw[:, None] * (X_mean @ Hinv_XT_y) + else: + X_Hinv_XT_y -= sqrt_sw * (X_mean @ Hinv_XT_y) + X_Hinv_XT_sqrt_sw -= sqrt_sw * (X_mean @ Hinv_XT_sqrt_sw) + alpha_c = y - X_Hinv_XT_y + alpha_d = 1 - self._sparse_multidot_diag(X, Hinv, X_mean, sqrt_sw) + if self.fit_intercept: + sw_sum = sqrt_sw @ sqrt_sw + alpha_Ginv_sqrt_sw = sqrt_sw - X_Hinv_XT_sqrt_sw + alpha_d -= alpha_Ginv_sqrt_sw * sqrt_sw / sw_sum + if y.ndim == 2: + alpha_d = alpha_d[:, None] + looe = alpha_c / alpha_d + coef = Hinv_XT_y + return looe, coef + + def _svd_decompose_design_matrix(self, X, X_mean, y, sqrt_sw): + """Reduced SVD decomposition of X""" + xp, _ = get_namespace(X) + # reduced svd + U, singvals, VT = xp.linalg.svd(X, full_matrices=False) + UT_y = U.T @ y + UT_sqrt_sw = U.T @ sqrt_sw + V = VT.T + return singvals, U, V, UT_y, UT_sqrt_sw - def _solve_eigen_covariance(self, alpha, y, sqrt_sw, X_mean, eigvals, V, X): - """Compute dual coefficients and diagonal of G^-1. + def _solve_svd_design_matrix_long( + self, alpha, y, sqrt_sw, singvals, U, V, UT_y, UT_sqrt_sw + ): + """Compute looe and coef when we have an SVD decomposition of X. - Used when we have a decomposition of X^T.X - (n_samples > n_features and X is sparse). + Long X case (n_features < n_samples). """ + M = alpha / (singvals**2 + alpha) - 1 + alpha_c = U @ self._diag_dot(M, UT_y) + y + alpha_d = self._decomp_diag(M, U) + 1 if self.fit_intercept: - return self._solve_eigen_covariance_intercept( - alpha, y, sqrt_sw, X_mean, eigvals, V, X - ) - return self._solve_eigen_covariance_no_intercept( - alpha, y, sqrt_sw, X_mean, eigvals, V, X - ) - - def _svd_decompose_design_matrix(self, X, y, sqrt_sw): - xp, _, device_ = get_namespace_and_device(X) - # X already centered - X_mean = xp.zeros(X.shape[1], dtype=X.dtype, device=device_) - if self.fit_intercept: - # to emulate fit_intercept=True situation, add a column - # containing the square roots of the sample weights - # by centering, the other columns are orthogonal to that one - intercept_column = sqrt_sw[:, None] - X = xp.concat((X, intercept_column), axis=1) - U, singvals, _ = xp.linalg.svd(X, full_matrices=False) - singvals_sq = singvals**2 - UT_y = U.T @ y - return X_mean, singvals_sq, U, UT_y + sw_sum = sqrt_sw @ sqrt_sw + alpha_Ginv_sqrt_sw = U @ self._diag_dot(M, UT_sqrt_sw) + sqrt_sw + alpha_d -= alpha_Ginv_sqrt_sw * sqrt_sw / sw_sum + if y.ndim == 2: + # handle case where y is 2-d + alpha_d = alpha_d[:, None] + looe = alpha_c / alpha_d + coef = V @ self._diag_dot(singvals / (singvals**2 + alpha), UT_y) + return looe, coef - def _solve_svd_design_matrix(self, alpha, y, sqrt_sw, X_mean, singvals_sq, U, UT_y): - """Compute dual coefficients and diagonal of G^-1. + def _solve_svd_design_matrix_wide( + self, alpha, y, sqrt_sw, singvals, U, V, UT_y, UT_sqrt_sw + ): + """Compute looe and coef when we have an SVD decomposition of X. - Used when we have an SVD decomposition of X - (n_samples > n_features and X is dense). + Wide X case (n_samples < n_features). """ - xp, is_array_api = get_namespace(U) - w = ((singvals_sq + alpha) ** -1) - (alpha**-1) + alpha_D = alpha / (singvals**2 + alpha) + alpha_c = U @ self._diag_dot(alpha_D, UT_y) + alpha_d = self._decomp_diag(alpha_D, U) if self.fit_intercept: - # detect intercept column - normalized_sw = sqrt_sw / xp.linalg.vector_norm(sqrt_sw) - intercept_dim = int(_find_smallest_angle(normalized_sw, U)) - # cancel the regularization for the intercept - w[intercept_dim] = -(alpha**-1) - c = U @ self._diag_dot(w, UT_y) + (alpha**-1) * y - G_inverse_diag = self._decomp_diag(w, U) + (alpha**-1) - if len(y.shape) != 1: + sw_sum = sqrt_sw @ sqrt_sw + alpha_Ginv_sqrt_sw = U @ self._diag_dot(alpha_D, UT_sqrt_sw) + alpha_d -= alpha_Ginv_sqrt_sw * sqrt_sw / sw_sum + if y.ndim == 2: # handle case where y is 2-d - G_inverse_diag = G_inverse_diag[:, None] - return G_inverse_diag, c + alpha_d = alpha_d[:, None] + looe = alpha_c / alpha_d + coef = V @ self._diag_dot(singvals / (singvals**2 + alpha), UT_y) + return looe, coef + + def _solve_svd_design_matrix( + self, alpha, y, sqrt_sw, singvals, U, V, UT_y, UT_sqrt_sw + ): + """Compute looe and coef when we have an SVD decomposition of X.""" + n_samples = U.shape[0] + n_features = V.shape[0] + if n_samples <= n_features: + return self._solve_svd_design_matrix_wide( + alpha, y, sqrt_sw, singvals, U, V, UT_y, UT_sqrt_sw + ) + else: + return self._solve_svd_design_matrix_long( + alpha, y, sqrt_sw, singvals, U, V, UT_y, UT_sqrt_sw + ) def fit(self, X, y, sample_weight=None, score_params=None): """Fit Ridge regression model with gcv. @@ -2169,13 +2207,15 @@ def fit(self, X, y, sample_weight=None, score_params=None): """ xp, is_array_api, device_ = get_namespace_and_device(X) y, sample_weight = move_to(y, sample_weight, xp=xp, device=device_) - if is_array_api or hasattr(getattr(X, "dtype", None), "kind"): - original_dtype = X.dtype + if (is_array_api and xp.isdtype(X.dtype, "real floating")) or getattr( + getattr(X, "dtype", None), "kind", None + ) == "f": + original_floating_dtype = X.dtype else: # for X that does not have a simple dtype (e.g. pandas dataframe) # the attributes will be stored in the dtype chosen by # `validate_data``, i.e. np.float64 - original_dtype = None + original_floating_dtype = None # Using float32 can be numerically unstable for this estimator. So if # the array API namespace and device allow, convert the input values # to float64 whenever possible before converting the results back to @@ -2213,25 +2253,25 @@ def fit(self, X, y, sample_weight=None, score_params=None): gcv_mode = _check_gcv_mode(X, self.gcv_mode) - if gcv_mode == "eigen": + n_samples, n_features = X.shape + if gcv_mode == "gram": decompose = self._eigen_decompose_gram solve = self._solve_eigen_gram + elif gcv_mode == "cov": + decompose = self._eigen_decompose_covariance + solve = self._solve_eigen_covariance elif gcv_mode == "svd": - if sparse.issparse(X): - decompose = self._eigen_decompose_covariance - solve = self._solve_eigen_covariance - else: - decompose = self._svd_decompose_design_matrix - solve = self._solve_svd_design_matrix - - n_samples = X.shape[0] + decompose = self._svd_decompose_design_matrix + solve = self._solve_svd_design_matrix + else: + raise ValueError(f"Unknown {gcv_mode=}") if sqrt_sw is None: sqrt_sw = xp.ones(n_samples, dtype=X.dtype, device=device_) - X_mean, *decomposition = decompose(X, y, sqrt_sw) + decomposition = decompose(X, X_offset, y, sqrt_sw) - n_y = 1 if len(y.shape) == 1 else y.shape[1] + n_y = 1 if y.ndim == 1 else y.shape[1] if ( isinstance(self.alphas, numbers.Number) or getattr(self.alphas, "ndim", None) == 0 @@ -2243,20 +2283,20 @@ def fit(self, X, y, sample_weight=None, score_params=None): if self.store_cv_results: self.cv_results_ = xp.empty( - (n_samples * n_y, n_alphas), dtype=original_dtype, device=device_ + (n_samples * n_y, n_alphas), dtype=X.dtype, device=device_ ) best_coef, best_score, best_alpha = None, None, None for i, alpha in enumerate(alphas): - G_inverse_diag, c = solve(float(alpha), y, sqrt_sw, X_mean, *decomposition) + looe, coef = solve(float(alpha), y, sqrt_sw, *decomposition) if self.scoring is None: - squared_errors = (c / G_inverse_diag) ** 2 + squared_errors = looe**2 alpha_score = self._score_without_scorer(squared_errors=squared_errors) if self.store_cv_results: self.cv_results_[:, i] = _ravel(squared_errors) else: - predictions = y - (c / G_inverse_diag) + predictions = y - looe # Rescale predictions back to original scale if sample_weight is not None: # avoid the unnecessary division by ones if predictions.ndim > 1: @@ -2281,53 +2321,51 @@ def fit(self, X, y, sample_weight=None, score_params=None): if best_score is None: # initialize if self.alpha_per_target and n_y > 1: - best_coef = c + best_coef = coef best_score = xp.reshape(alpha_score, shape=(-1,)) best_alpha = xp.full(n_y, alpha, device=device_) else: - best_coef = c + best_coef = coef best_score = alpha_score best_alpha = alpha else: # update if self.alpha_per_target and n_y > 1: to_update = alpha_score > best_score - best_coef.T[to_update] = c.T[to_update] + best_coef[:, to_update] = coef[:, to_update] best_score[to_update] = alpha_score[to_update] best_alpha[to_update] = alpha elif alpha_score > best_score: - best_coef, best_score, best_alpha = c, alpha_score, alpha + best_coef, best_score, best_alpha = coef, alpha_score, alpha self.alpha_ = best_alpha self.best_score_ = best_score - self.dual_coef_ = best_coef - # avoid torch warning about x.T for x with ndim != 2 - if self.dual_coef_.ndim > 1: - dual_T = self.dual_coef_.T - else: - dual_T = self.dual_coef_ - self.coef_ = dual_T @ X + self.coef_ = best_coef + if y.ndim == 2: + self.coef_ = self.coef_.T if y.ndim == 1 or y.shape[1] == 1: self.coef_ = _ravel(self.coef_) - if sparse.issparse(X): - X_offset = X_mean * X_scale - else: - X_offset += X_mean * X_scale self._set_intercept(X_offset, y_offset, X_scale) if self.store_cv_results: - if len(y.shape) == 1: + if y.ndim == 1: cv_results_shape = n_samples, n_alphas else: cv_results_shape = n_samples, n_y, n_alphas self.cv_results_ = xp.reshape(self.cv_results_, shape=cv_results_shape) - if original_dtype is not None: + if original_floating_dtype: if type(self.intercept_) is not float: - self.intercept_ = xp.astype(self.intercept_, original_dtype, copy=False) - self.dual_coef_ = xp.astype(self.dual_coef_, original_dtype, copy=False) - self.coef_ = xp.astype(self.coef_, original_dtype, copy=False) + self.intercept_ = xp.astype( + self.intercept_, original_floating_dtype, copy=False + ) + self.coef_ = xp.astype(self.coef_, original_floating_dtype, copy=False) + if self.store_cv_results: + self.cv_results_ = xp.astype( + self.cv_results_, original_floating_dtype, copy=False + ) + return self def _score_without_scorer(self, squared_errors): @@ -2669,13 +2707,14 @@ class RidgeCV(MultiOutputMixin, RegressorMixin, _BaseRidgeCV): Flag indicating which strategy to use when performing Leave-One-Out Cross-Validation. Options are:: - 'auto' : use 'svd' if n_samples > n_features, otherwise use 'eigen' - 'svd' : force use of singular value decomposition of X when X is - dense, eigenvalue decomposition of X^T.X when X is sparse. - 'eigen' : force computation via eigendecomposition of X.X^T + 'auto' : same as 'eigen' + 'svd' : use singular value decomposition of X when X is dense, + fallback to 'eigen' when X is sparse + 'eigen' : use eigendecomposition of X X' when n_samples <= n_features + or X' X when n_features < n_samples The 'auto' mode is the default and is intended to pick the cheaper - option of the two depending on the shape of the training data. + option depending on the shape and sparsity of the training data. store_cv_results : bool, default=False Flag indicating if the cross-validation values corresponding to diff --git a/sklearn/linear_model/tests/test_ridge.py b/sklearn/linear_model/tests/test_ridge.py index b6032baa29e8e..fe9112bd757ab 100644 --- a/sklearn/linear_model/tests/test_ridge.py +++ b/sklearn/linear_model/tests/test_ridge.py @@ -46,7 +46,6 @@ _atol_for_type, _convert_to_numpy, _get_namespace_device_dtype_ids, - _max_precision_float_dtype, yield_namespace_device_dtype_combinations, yield_namespaces, ) @@ -665,8 +664,7 @@ def test_compute_gram(shape, uniform_weights, csr_container): true_gram = X_centered.dot(X_centered.T) X_sparse = csr_container(X * sqrt_sw[:, None]) gcv = _RidgeGCV(fit_intercept=True) - computed_gram, computed_mean = gcv._compute_gram(X_sparse, sqrt_sw) - assert_allclose(X_mean, computed_mean) + computed_gram = gcv._compute_gram(X_sparse, X_mean, sqrt_sw) assert_allclose(true_gram, computed_gram) @@ -686,8 +684,7 @@ def test_compute_covariance(shape, uniform_weights, csr_container): true_covariance = X_centered.T.dot(X_centered) X_sparse = csr_container(X * sqrt_sw[:, None]) gcv = _RidgeGCV(fit_intercept=True) - computed_cov, computed_mean = gcv._compute_covariance(X_sparse, sqrt_sw) - assert_allclose(X_mean, computed_mean) + computed_cov = gcv._compute_covariance(X_sparse, X_mean, sqrt_sw) assert_allclose(true_covariance, computed_cov) @@ -797,9 +794,32 @@ def test_solver_consistency( assert_allclose(ridge.intercept_, svd_ridge.intercept_, atol=1e-3, rtol=1e-3) +def test_ridge_gcv_integer_arrays(): + n_samples, n_features = 20, 10 + rng = np.random.RandomState(0) + X = rng.randint(0, 5, size=(n_samples, n_features)) + y = rng.randint(0, 5, size=(n_samples,)) + + X_float = X.astype(np.float64) + y_float = y.astype(np.float64) + + ridge_gcv = RidgeCV( + alphas=[0.1, 1.0, 10.0], scoring="neg_mean_squared_error", store_cv_results=True + ) + ridge_gcv.fit(X, y) + + ridge_gcv_float = clone(ridge_gcv) + ridge_gcv_float.fit(X_float, y_float) + + assert_allclose(ridge_gcv.coef_, ridge_gcv_float.coef_) + assert_allclose(ridge_gcv.cv_results_, ridge_gcv_float.cv_results_) + assert ridge_gcv.cv_results_.dtype == np.float64 + + @pytest.mark.parametrize("gcv_mode", ["svd", "eigen"]) +@pytest.mark.parametrize("dtype", [np.float32, np.float64]) @pytest.mark.parametrize("X_container", [np.asarray] + CSR_CONTAINERS) -@pytest.mark.parametrize("X_shape", [(11, 8), (11, 20)]) +@pytest.mark.parametrize("X_shape", [(11, 8), (11, 20)], ids=["tall", "wide"]) @pytest.mark.parametrize("fit_intercept", [True, False]) @pytest.mark.parametrize( "y_shape, noise", @@ -810,8 +830,10 @@ def test_solver_consistency( ], ) def test_ridge_gcv_vs_ridge_loo_cv( - gcv_mode, X_container, X_shape, y_shape, fit_intercept, noise + gcv_mode, dtype, X_container, X_shape, y_shape, fit_intercept, noise ): + if gcv_mode == "svd" and (X_container in CSR_CONTAINERS): + pytest.skip("`svd` mode not supported for sparse X.") n_samples, n_features = X_shape n_targets = y_shape[-1] if len(y_shape) == 2 else 1 X, y = _make_sparse_offset_regression( @@ -840,12 +862,153 @@ def test_ridge_gcv_vs_ridge_loo_cv( loo_ridge.fit(X, y) - X_gcv = X_container(X) - gcv_ridge.fit(X_gcv, y) + X = X_container(X) + X = X.astype(dtype) + y = y.astype(dtype) + gcv_ridge.fit(X, y) + atol = 1e-5 if dtype == np.float32 else 1e-10 assert gcv_ridge.alpha_ == pytest.approx(loo_ridge.alpha_) - assert_allclose(gcv_ridge.coef_, loo_ridge.coef_, rtol=1e-3) - assert_allclose(gcv_ridge.intercept_, loo_ridge.intercept_, rtol=1e-3) + assert_allclose(gcv_ridge.coef_, loo_ridge.coef_, atol=atol) + assert_allclose(gcv_ridge.intercept_, loo_ridge.intercept_, atol=atol) + + +def _ridge_regularization_limits(alpha, X, y, fit_intercept): + "Expected coef and intercept when alpha near 0 or inf" + if np.isclose(alpha, 0): + # Ridge should recover LinearRegression for near-zero alpha. + lin_reg = LinearRegression(fit_intercept=fit_intercept) + lin_reg.fit(X, y) + return lin_reg.coef_, lin_reg.intercept_ + else: + # Ridge should recover zero coefficients for near-infinite alpha. + n_features = X.shape[1] + return np.zeros(n_features), np.mean(y) if fit_intercept else 0.0 + + +@pytest.mark.parametrize("alpha", [1e-16, 1e16], ids=["zero_alpha", "inf_alpha"]) +@pytest.mark.parametrize("solver", ["svd", "cholesky", "lsqr", "sparse_cg"]) +@pytest.mark.parametrize("fit_intercept", [True, False]) +@pytest.mark.parametrize("X_shape", [(100, 50), (50, 100)], ids=["tall", "wide"]) +@pytest.mark.parametrize("X_container", [np.asarray] + CSR_CONTAINERS) +def test_regularization_limits_ridge( + alpha, solver, fit_intercept, X_shape, X_container +): + "Check regularization limits of Ridge (alpha near 0 or inf)" + sparse_X = X_container in CSR_CONTAINERS + if solver == "svd" and sparse_X: + pytest.skip("solver='svd' does not support sparse data") + if solver == "cholesky" and sparse_X and fit_intercept: + pytest.skip( + "solver='cholesky' does not support fitting the intercept on sparse data" + ) + n_samples, n_features = X_shape + X, y = make_regression( + n_samples=n_samples, n_features=n_features, noise=0, bias=10, random_state=42 + ) + expected_coef, expected_intercept = _ridge_regularization_limits( + alpha, X, y, fit_intercept + ) + X = X_container(X) + ridge = Ridge(alpha=alpha, solver=solver, fit_intercept=fit_intercept, tol=1e-12) + ridge.fit(X, y) + assert_allclose(ridge.coef_, expected_coef, atol=1e-10) + assert_allclose(ridge.intercept_, expected_intercept, atol=1e-10) + + +@pytest.mark.parametrize("alpha", [1e-16, 1e16], ids=["zero_alpha", "inf_alpha"]) +@pytest.mark.parametrize("gcv_mode", ["ignored"]) +@pytest.mark.parametrize("fit_intercept", [True, False]) +@pytest.mark.parametrize( + "X_shape", + [(100, 50), (50, 50), (50, 100)], + ids=["tall", "square", "wide"], +) +@pytest.mark.parametrize("dtype", [np.float32, np.float64]) +@pytest.mark.parametrize("X_container", [np.asarray] + CSR_CONTAINERS) +def test_regularization_limits_ridge_classifier_gcv( + alpha, gcv_mode, fit_intercept, X_shape, dtype, X_container +): + "Check regularization limits of RidgeClassifierCV (alpha near 0 or inf)" + sparse_X = X_container in CSR_CONTAINERS + alphas = [alpha] + n_samples, n_features = X_shape + X, y = make_classification( + n_samples=n_samples, n_features=n_features, random_state=42 + ) + # RidgeClassifier is Ridge with y mapped to {-1, +1} + y = 2 * y - 1 + if np.isclose(alpha, 0): + # FIXME : test fails on square or tall X + if n_features < n_samples: + pytest.xfail( + "RidgeClassifierCV does not recover LinearRegression " + "on tall X in the small alpha limit" + ) + elif n_features == n_samples: + pytest.xfail( + "RidgeClassifierCV does not recover LinearRegression " + "on square X in the small alpha limit" + ) + expected_coef, expected_intercept = _ridge_regularization_limits( + alpha, X, y, fit_intercept + ) + X = X_container(X) + X = X.astype(dtype) + y = y.astype(dtype) + # FIXME : add `gcv_mode` parameter to RidgeClassifierCV + gcv_ridge = RidgeClassifierCV(alphas=alphas, fit_intercept=fit_intercept) + if gcv_mode == "svd" and sparse_X: + # TODO(1.11) should raises ValueError + expected_msg = "The 'svd' mode is not supported for sparse X" + with pytest.warns(FutureWarning, match=expected_msg): + gcv_ridge.fit(X, y) + else: + gcv_ridge.fit(X, y) + + atol = 1e-5 if dtype == np.float32 else 1e-10 + assert_allclose(gcv_ridge.coef_, expected_coef, atol=atol) + assert_allclose(gcv_ridge.intercept_, expected_intercept, atol=atol) + + +@pytest.mark.parametrize("alpha", [1e-16, 1e16], ids=["zero_alpha", "inf_alpha"]) +@pytest.mark.parametrize("gcv_mode", ["svd", "eigen"]) +@pytest.mark.parametrize("fit_intercept", [True, False]) +@pytest.mark.parametrize( + "X_shape", + [(100, 50), (50, 50), (50, 100)], + ids=["tall", "square", "wide"], +) +@pytest.mark.parametrize("dtype", [np.float32, np.float64]) +@pytest.mark.parametrize("X_container", [np.asarray] + CSR_CONTAINERS) +def test_regularization_limits_ridge_gcv( + alpha, gcv_mode, fit_intercept, X_shape, dtype, X_container +): + "Check regularization limits of _RidgeGCV (alpha near 0 or inf)" + sparse_X = X_container in CSR_CONTAINERS + alphas = [alpha] + n_samples, n_features = X_shape + X, y = make_regression( + n_samples=n_samples, n_features=n_features, noise=0, bias=10, random_state=42 + ) + expected_coef, expected_intercept = _ridge_regularization_limits( + alpha, X, y, fit_intercept + ) + X = X_container(X) + X = X.astype(dtype) + y = y.astype(dtype) + gcv_ridge = RidgeCV(alphas=alphas, gcv_mode=gcv_mode, fit_intercept=fit_intercept) + if gcv_mode == "svd" and sparse_X: + # TODO(1.11) should raises ValueError + expected_msg = "The 'svd' mode is not supported for sparse X" + with pytest.warns(FutureWarning, match=expected_msg): + gcv_ridge.fit(X, y) + else: + gcv_ridge.fit(X, y) + + atol = 1e-5 if dtype == np.float32 else 1e-10 + assert_allclose(gcv_ridge.coef_, expected_coef, atol=atol) + assert_allclose(gcv_ridge.intercept_, expected_intercept, atol=atol) def test_ridge_loo_cv_asym_scoring(): @@ -895,6 +1058,8 @@ def test_ridge_loo_cv_asym_scoring(): def test_ridge_gcv_sample_weights( gcv_mode, X_container, fit_intercept, n_features, y_shape, noise ): + if gcv_mode == "svd" and (X_container in CSR_CONTAINERS): + pytest.skip("`svd` mode not supported for sparse X.") alphas = [1e-3, 0.1, 1.0, 10.0, 1e3] rng = np.random.RandomState(0) n_targets = y_shape[-1] if len(y_shape) == 2 else 1 @@ -956,22 +1121,29 @@ def test_ridge_gcv_sample_weights( @pytest.mark.parametrize("sparse_container", [None] + CSR_CONTAINERS) @pytest.mark.parametrize( - "mode, mode_n_greater_than_p, mode_p_greater_than_n", - [ - (None, "svd", "eigen"), - ("auto", "svd", "eigen"), - ("eigen", "eigen", "eigen"), - ("svd", "svd", "svd"), - ], + "X_shape", + [(5, 2), (5, 5), (2, 5)], + ids=["tall", "square", "wide"], ) -def test_check_gcv_mode_choice( - sparse_container, mode, mode_n_greater_than_p, mode_p_greater_than_n -): - X, _ = make_regression(n_samples=5, n_features=2) - if sparse_container is not None: +@pytest.mark.parametrize("gcv_mode", ["auto", "svd", "eigen"]) +def test_check_gcv_mode_choice(sparse_container, X_shape, gcv_mode): + n, p = X_shape + X, _ = make_regression(n_samples=n, n_features=p) + sparse_X = sparse_container is not None + if sparse_X: X = sparse_container(X) - assert _check_gcv_mode(X, mode) == mode_n_greater_than_p - assert _check_gcv_mode(X.T, mode) == mode_p_greater_than_n + eigen_mode = "gram" if n <= p else "cov" + + if gcv_mode == "svd" and not sparse_X: + assert _check_gcv_mode(X, gcv_mode) == "svd" + elif gcv_mode == "svd" and sparse_X: + # TODO(1.11) should raises ValueError + expected_msg = "The 'svd' mode is not supported for sparse X" + with pytest.warns(FutureWarning, match=expected_msg): + actual_gcv_mode = _check_gcv_mode(X, gcv_mode) + assert actual_gcv_mode == eigen_mode + else: + assert _check_gcv_mode(X, gcv_mode) == eigen_mode def _test_ridge_loo(sparse_container): @@ -1290,7 +1462,8 @@ def check_array_api_attributes( [ Ridge(solver="svd"), RidgeClassifier(solver="svd"), - RidgeCV(), + RidgeCV(gcv_mode="svd"), + RidgeCV(gcv_mode="eigen"), RidgeClassifierCV(), ], ids=_get_check_estimator_ids, @@ -1299,20 +1472,8 @@ def test_ridge_array_api_compliance( estimator, check, array_namespace, device, dtype_name ): name = estimator.__class__.__name__ - tols = {} xp = _array_api_for_tests(array_namespace, device) - if ( - "CV" in name - and check is check_array_api_attributes - and _max_precision_float_dtype(xp, device) == xp.float32 - ): - # RidgeGCV is not very numerically stable with float32. It casts the - # input to float64 unless the device and namespace combination does - # not allow float64 (specifically torch with mps) - tols["rtol"] = 1e-3 - check( - name, estimator, array_namespace, device=device, dtype_name=dtype_name, **tols - ) + check(name, estimator, array_namespace, device=device, dtype_name=dtype_name) @pytest.mark.parametrize( @@ -2297,10 +2458,16 @@ def test_ridge_sample_weight_consistency( assert_allclose(reg1.intercept_, reg2.intercept_) -@pytest.mark.parametrize("with_sample_weight", [False, True]) -@pytest.mark.parametrize("fit_intercept", [False, True]) +@pytest.mark.parametrize("X_shape", [(50, 10), (10, 50)], ids=["tall", "wide"]) +@pytest.mark.parametrize("with_sample_weight", [False, True], ids=["no_sw", "with_sw"]) +@pytest.mark.parametrize( + "fit_intercept", [False, True], ids=["no_intercept", "with_intercept"] +) +@pytest.mark.parametrize("gcv_mode", ["svd", "eigen"]) @pytest.mark.parametrize("n_targets", [1, 2]) -def test_ridge_cv_results_predictions(with_sample_weight, fit_intercept, n_targets): +def test_ridge_cv_results_predictions( + gcv_mode, X_shape, with_sample_weight, fit_intercept, n_targets +): """Check that the predictions stored in `cv_results_` are on the original scale. The GCV approach works on scaled data: centered by an offset and scaled by the @@ -2314,17 +2481,25 @@ def test_ridge_cv_results_predictions(with_sample_weight, fit_intercept, n_targe Non-regression test for: https://github.com/scikit-learn/scikit-learn/issues/13998 """ + n_samples, n_features = X_shape X, y = make_regression( - n_samples=100, n_features=10, n_targets=n_targets, random_state=0 + n_samples=n_samples, n_features=n_features, n_targets=n_targets, random_state=0 ) - sample_weight = np.ones(shape=(X.shape[0],)) if with_sample_weight: + sample_weight = np.ones(shape=(X.shape[0],)) sample_weight[::2] = 0.5 + else: + sample_weight = None - alphas = (0.1, 1.0, 10.0) + # TODO: widening the range of alphas causes failures in the test, in + # particular for wide datasets. Not sure if this is an intrinsic limitation + # of the underlying linear algebra or if this points to a numerical issue + # in RidgeCV or in Ridge(solver="svd"). + alphas = np.logspace(-5, 7, 5) # scoring should be set to store predictions and not the squared error ridge_cv = RidgeCV( + gcv_mode=gcv_mode, alphas=alphas, scoring="neg_mean_squared_error", fit_intercept=fit_intercept, @@ -2337,23 +2512,39 @@ def test_ridge_cv_results_predictions(with_sample_weight, fit_intercept, n_targe cv = LeaveOneOut() for alpha_idx, alpha in enumerate(alphas): for idx, (train_idx, test_idx) in enumerate(cv.split(X, y)): - ridge = Ridge(alpha=alpha, fit_intercept=fit_intercept) - ridge.fit(X[train_idx], y[train_idx], sample_weight[train_idx]) + ridge = Ridge(alpha=alpha, fit_intercept=fit_intercept, solver="svd") + if with_sample_weight: + ridge.fit( + X[train_idx], y[train_idx], sample_weight=sample_weight[train_idx] + ) + else: + ridge.fit(X[train_idx], y[train_idx]) predictions[idx, ..., alpha_idx] = ridge.predict(X[test_idx]) - assert_allclose(ridge_cv.cv_results_, predictions) + # A few cases are just above the rtol=1e-7 threshold + assert_allclose(ridge_cv.cv_results_, predictions, rtol=1e-6) -def test_ridge_cv_multioutput_sample_weight(global_random_seed): +@pytest.mark.parametrize("gcv_mode", ["svd", "eigen"]) +@pytest.mark.parametrize("X_shape", [(50, 10), (10, 50)], ids=["tall", "wide"]) +def test_ridge_cv_multioutput_sample_weight(gcv_mode, X_shape, global_random_seed): """Check that `RidgeCV` works properly with multioutput and sample_weight when `scoring != None`. We check the error reported by the RidgeCV is close to a naive LOO-CV using a Ridge estimator. """ - X, y = make_regression(n_targets=2, random_state=global_random_seed) - sample_weight = np.ones(shape=(X.shape[0],)) + n_samples, n_features = X_shape + X, y = make_regression( + n_samples=n_samples, + n_features=n_features, + n_targets=2, + random_state=global_random_seed, + ) + sample_weight = np.ones(n_samples) - ridge_cv = RidgeCV(scoring="neg_mean_squared_error", store_cv_results=True) + ridge_cv = RidgeCV( + gcv_mode=gcv_mode, scoring="neg_mean_squared_error", store_cv_results=True + ) ridge_cv.fit(X, y, sample_weight=sample_weight) cv = LeaveOneOut() @@ -2369,9 +2560,13 @@ def test_ridge_cv_multioutput_sample_weight(global_random_seed): assert_allclose(ridge_cv.best_score_, -mean_squared_error(y, y_pred_loo)) -def test_ridge_cv_custom_multioutput_scorer(): +@pytest.mark.parametrize("X_shape", [(50, 10), (10, 50)], ids=["tall", "wide"]) +def test_ridge_cv_custom_multioutput_scorer(X_shape): """Check that `RidgeCV` works properly with a custom multioutput scorer.""" - X, y = make_regression(n_targets=2, random_state=0) + n_samples, n_features = X_shape + X, y = make_regression( + n_samples=n_samples, n_features=n_features, n_targets=2, random_state=0 + ) def custom_error(y_true, y_pred): errors = (y_true - y_pred) ** 2 From 361a8e1cc81418f3f19014752da4817b94f72657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= Date: Mon, 23 Feb 2026 18:01:13 +0100 Subject: [PATCH 239/462] FIX make it possible to call `dir` on an empty pipeline (#33362) --- .../sklearn.pipeline/33362.fix.rst | 4 +++ sklearn/pipeline.py | 26 ++++++++++++++++--- sklearn/tests/test_pipeline.py | 7 +++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.pipeline/33362.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.pipeline/33362.fix.rst b/doc/whats_new/upcoming_changes/sklearn.pipeline/33362.fix.rst new file mode 100644 index 0000000000000..aed94f805bc99 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.pipeline/33362.fix.rst @@ -0,0 +1,4 @@ +- :class:`pipeline.Pipeline` now raises an `AttributeError` when accessing attributes + that are not available on an empty pipeline. It's therefore possible to call `dir` + on an empty pipeline. + By :user:`Jérémie du Boisberranger `. diff --git a/sklearn/pipeline.py b/sklearn/pipeline.py index f3f6bc7883c8e..ca5d1d0cf8e57 100644 --- a/sklearn/pipeline.py +++ b/sklearn/pipeline.py @@ -389,6 +389,11 @@ def _final_estimator(self): try: estimator = self.steps[-1][1] return "passthrough" if estimator is None else estimator + except IndexError: + # An empty pipeline has no final estimator + raise AttributeError( + f"'{type(self).__name__}' object has no attribute '_final_estimator'" + ) except (ValueError, AttributeError, TypeError): # This condition happens when a call to a method is first calling # `_available_if` and `fit` did not validate `steps` yet. We @@ -1149,7 +1154,12 @@ def score(self, X, y=None, sample_weight=None, **params): @property def classes_(self): """The classes labels. Only exist if the last step is a classifier.""" - return self.steps[-1][1].classes_ + try: + return self.steps[-1][1].classes_ + except IndexError: + raise AttributeError( + f"'{type(self).__name__}' object has no attribute 'classes_'" + ) def __sklearn_tags__(self): tags = super().__sklearn_tags__() @@ -1221,13 +1231,23 @@ def get_feature_names_out(self, input_features=None): def n_features_in_(self): """Number of features seen during first step `fit` method.""" # delegate to first step (which will call check_is_fitted) - return self.steps[0][1].n_features_in_ + try: + return self.steps[0][1].n_features_in_ + except IndexError: + raise AttributeError( + f"'{type(self).__name__}' object has no attribute 'n_features_in_'" + ) @property def feature_names_in_(self): """Names of features seen during first step `fit` method.""" # delegate to first step (which will call check_is_fitted) - return self.steps[0][1].feature_names_in_ + try: + return self.steps[0][1].feature_names_in_ + except IndexError: + raise AttributeError( + f"'{type(self).__name__}' object has no attribute 'feature_names_in_'" + ) def __sklearn_is_fitted__(self): """Indicate whether pipeline has been fit. diff --git a/sklearn/tests/test_pipeline.py b/sklearn/tests/test_pipeline.py index 4c0268fa8851e..c174af64ae8a8 100644 --- a/sklearn/tests/test_pipeline.py +++ b/sklearn/tests/test_pipeline.py @@ -324,6 +324,13 @@ def test_empty_pipeline(): pipe.fit(X, y) +def test_empty_pipeline_dir(): + """Check that dir() works on an empty pipeline""" + pipe = Pipeline([]) + attrs = dir(pipe) + assert "steps" in attrs + + def test_pipeline_init_tuple(): # Pipeline accepts steps as tuple X = np.array([[1, 2]]) From 7ea267fc73f6de3ebaffd409a5df9b96d5636b06 Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Tue, 24 Feb 2026 07:20:58 +1100 Subject: [PATCH 240/462] ENH add `from_cv_results` in `PrecisionRecallDisplay` (#30508) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Guillaume Lemaitre Co-authored-by: Guillaume Lemaitre Co-authored-by: Jérémie du Boisberranger --- .../sklearn.metrics/30508.feature.rst | 4 + .../model_selection/plot_precision_recall.py | 38 +- .../metrics/_plot/precision_recall_curve.py | 462 +++++++++++++-- sklearn/metrics/_plot/roc_curve.py | 13 +- .../_plot/tests/test_common_curve_display.py | 180 ++++-- .../tests/test_precision_recall_display.py | 533 ++++++++++++++---- .../_plot/tests/test_roc_curve_display.py | 66 --- sklearn/utils/_plotting.py | 30 +- sklearn/utils/tests/test_plotting.py | 5 +- 9 files changed, 1016 insertions(+), 315 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/30508.feature.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/30508.feature.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/30508.feature.rst new file mode 100644 index 0000000000000..eecf73a1e9c2a --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.metrics/30508.feature.rst @@ -0,0 +1,4 @@ +- Add class method `from_cv_results` to :class:`metrics.PrecisionRecallDisplay`, + which allows easy plotting of multiple precision-recall curves from + :func:`model_selection.cross_validate` results. + By :user:`Lucy Liu `. diff --git a/examples/model_selection/plot_precision_recall.py b/examples/model_selection/plot_precision_recall.py index c7ff06d3f8fcb..e3be77d50569e 100644 --- a/examples/model_selection/plot_precision_recall.py +++ b/examples/model_selection/plot_precision_recall.py @@ -136,9 +136,18 @@ # ............................... # # To plot the precision-recall curve, you should use -# :class:`~sklearn.metrics.PrecisionRecallDisplay`. Indeed, there is two -# methods available depending if you already computed the predictions of the -# classifier or not. +# :class:`~sklearn.metrics.PrecisionRecallDisplay`. There are three +# methods available: +# +# * for plotting a single curve: +# +# * :func:`~sklearn.metrics.PrecisionRecallDisplay.from_estimator` for when you +# have not computed the predictions +# * :func:`~sklearn.metrics.PrecisionRecallDisplay.from_predictions` for when +# you already have the predictions +# +# * for plotting multiple curves using cross-validation results: +# :func:`~sklearn.metrics.PrecisionRecallDisplay.from_cv_results` # # Let's first plot the precision-recall curve without the classifier # predictions. We use @@ -162,6 +171,20 @@ ) _ = display.ax_.set_title("2-class Precision-Recall curve") +# %% +# The :func:`~sklearn.metrics.PrecisionRecallDisplay.from_cv_results` takes the +# cross-validation results from :func:`~sklearn.model_selection.cross_validate` +# and plots a precision-recall curve for each fold. + +from sklearn.model_selection import cross_validate + +classifier = make_pipeline(StandardScaler(), LinearSVC(random_state=random_state)) +cv_results = cross_validate( + classifier, X_train, y_train, return_estimator=True, return_indices=True +) +display = PrecisionRecallDisplay.from_cv_results(cv_results, X_train, y_train) +_ = display.ax_.set_title("Cross-validation Precision-Recall curves") + # %% # In multi-label settings # ----------------------- @@ -256,7 +279,9 @@ precision=precision["micro"], average_precision=average_precision["micro"], ) -display.plot(ax=ax, name="Micro-average precision-recall", color="gold") +display.plot( + ax=ax, name="Micro-average precision-recall", curve_kwargs={"color": "gold"} +) for i, color in zip(range(n_classes), colors): display = PrecisionRecallDisplay( @@ -265,7 +290,10 @@ average_precision=average_precision[i], ) display.plot( - ax=ax, name=f"Precision-recall for class {i}", color=color, despine=True + ax=ax, + name=f"Precision-recall for class {i}", + curve_kwargs={"color": color}, + despine=True, ) # add the legend for the iso-f1 curves diff --git a/sklearn/metrics/_plot/precision_recall_curve.py b/sklearn/metrics/_plot/precision_recall_curve.py index 43d24cac4d530..9302a073d38e3 100644 --- a/sklearn/metrics/_plot/precision_recall_curve.py +++ b/sklearn/metrics/_plot/precision_recall_curve.py @@ -3,14 +3,20 @@ from collections import Counter +import numpy as np + from sklearn.metrics._ranking import average_precision_score, precision_recall_curve +from sklearn.utils import _safe_indexing from sklearn.utils._plotting import ( _BinaryClassifierCurveDisplayMixin, + _check_param_lengths, + _convert_to_list_leaving_none, _deprecate_estimator_name, _deprecate_y_pred_parameter, _despine, _validate_style_kwargs, ) +from sklearn.utils._response import _get_response_values_binary class PrecisionRecallDisplay(_BinaryClassifierCurveDisplayMixin): @@ -29,34 +35,64 @@ class PrecisionRecallDisplay(_BinaryClassifierCurveDisplayMixin): Parameters ---------- - precision : ndarray - Precision values. + precision : ndarray or list of ndarrays + Precision values. Each ndarray should contain values for a single curve. + If plotting multiple curves, list should be of same length as `recall`. + + .. versionchanged:: 1.9 + Now accepts a list for plotting multiple curves. + + recall : ndarray or list of ndarrays + Recall values. Each ndarray should contain values for a single curve. + If plotting multiple curves, list should be of same length as `precision`. + + .. versionchanged:: 1.9 + Now accepts a list for plotting multiple curves. + + average_precision : float or list of floats, default=None + Average precision, used for labeling each curve in the legend. + If plotting multiple curves, should be a list of the same length as `precision` + and `recall`. If `None`, average precision values are not shown in the legend. - recall : ndarray - Recall values. + .. versionchanged:: 1.9 + Now accepts a list for plotting multiple curves. - average_precision : float, default=None - Average precision. If None, the average precision is not shown. + name : str or list of str, default=None + Name for labeling legend entries. The number of legend entries is determined + by the `curve_kwargs` passed to `plot`, and is not affected by `name`. - name : str, default=None - Name of estimator. If None, then the estimator name is not shown. + If a string is provided, it will be used to either label the single legend + entry or if there are multiple legend entries, label each individual curve + with the same name. + + If a list is provided, it will be used to label each curve individually. + Passing a list will raise an error if `curve_kwargs` is not a list to avoid + labeling individual curves that have the same appearance. + + If `None`, no name is shown in the legend. .. versionchanged:: 1.8 `estimator_name` was deprecated in favor of `name`. + .. versionchanged:: 1.9 + `name` can now take a list of str for multiple curves. + pos_label : int, float, bool or str, default=None The class considered the positive class when precision and recall metrics computed. If not `None`, this value is displayed in the x- and y-axes labels. .. versionadded:: 0.24 - prevalence_pos_label : float, default=None + prevalence_pos_label : float or list of floats, default=None The prevalence of the positive label. It is used for plotting the - chance level line. If None, the chance level line will not be plotted + chance level lines. If None, no chance level line will be plotted even if `plot_chance_level` is set to True when plotting. .. versionadded:: 1.3 + .. versionchanged:: 1.9 + May now be list of floats for when multiple curves plotted. + estimator_name : str, default=None Name of estimator. If None, the estimator name is not shown. @@ -66,14 +102,22 @@ class PrecisionRecallDisplay(_BinaryClassifierCurveDisplayMixin): Attributes ---------- - line_ : matplotlib Artist - Precision recall curve. + line_ : matplotlib Artist or list of Artists + Precision recall curve(s). + + .. versionchanged:: 1.9 + This attribute can now be a list of Artists, for when multiple curves + are plotted. - chance_level_ : matplotlib Artist or None - The chance level line. It is `None` if the chance level is not plotted. + chance_level_ : matplotlib Artist or list of Artists or None + Chance level line(s). It is `None` if the chance level is not plotted. .. versionadded:: 1.3 + .. versionchanged:: 1.9 + This attribute can now be a list of Artists, for when multiple curves + are plotted. + ax_ : matplotlib Axes Axes with precision recall curve. @@ -96,10 +140,10 @@ class PrecisionRecallDisplay(_BinaryClassifierCurveDisplayMixin): this metric, the precision-recall curve is plotted without any interpolation as well (step-wise style). - You can change this style by passing the keyword argument - `drawstyle="default"` in :meth:`plot`, :meth:`from_estimator`, or - :meth:`from_predictions`. However, the curve will not be strictly - consistent with the reported average precision. + To enable interpolation, pass `curve_kwargs={"drawstyle": "default"}` to + meth:`plot`, :meth:`from_estimator`, or :meth:`from_predictions`. + However, the curve will not be strictly consistent with the reported + average precision. Examples -------- @@ -134,18 +178,41 @@ def __init__( prevalence_pos_label=None, estimator_name="deprecated", ): - self.name = _deprecate_estimator_name(estimator_name, name, "1.8") self.precision = precision self.recall = recall self.average_precision = average_precision + self.name = _deprecate_estimator_name(estimator_name, name, "1.8") self.pos_label = pos_label self.prevalence_pos_label = prevalence_pos_label + def _validate_plot_params(self, *, ax, name): + self.ax_, self.figure_, name = super()._validate_plot_params(ax=ax, name=name) + + precision = _convert_to_list_leaving_none(self.precision) + recall = _convert_to_list_leaving_none(self.recall) + average_precision = _convert_to_list_leaving_none(self.average_precision) + prevalence_pos_label = _convert_to_list_leaving_none(self.prevalence_pos_label) + name = _convert_to_list_leaving_none(name) + + optional = { + "self.average_precision": average_precision, + "self.prevalence_pos_label": prevalence_pos_label, + } + if isinstance(name, list) and len(name) != 1: + optional.update({"'name' (or self.name)": name}) + _check_param_lengths( + required={"self.precision": precision, "self.recall": recall}, + optional=optional, + class_name="PrecisionRecallDisplay", + ) + return precision, recall, average_precision, name, prevalence_pos_label + def plot( self, ax=None, *, name=None, + curve_kwargs=None, plot_chance_level=False, chance_level_kw=None, despine=False, @@ -153,17 +220,41 @@ def plot( ): """Plot visualization. - Extra keyword arguments will be passed to matplotlib's `plot`. - Parameters ---------- ax : Matplotlib Axes, default=None Axes object to plot on. If `None`, a new figure and axes is created. - name : str, default=None - Name of precision recall curve for labeling. If `None`, use - `name` if not `None`, otherwise no labeling is shown. + name : str or list of str, default=None + Name for labeling legend entries. The number of legend entries + is determined by `curve_kwargs`, and is not affected by `name`. + + If a string is provided, it will be used to either label the single legend + entry or if there are multiple legend entries, label each individual curve + with the same name. + + If a list is provided, it will be used to label each curve individually. + Passing a list will raise an error if `curve_kwargs` is not a list to avoid + labeling individual curves that have the same appearance. + + If `None`, set to `name` provided at `PrecisionRecallDisplay` + initialization. If still `None`, no name is shown in the legend. + + .. versionchanged:: 1.9 + Now accepts a list for plotting multiple curves. + + curve_kwargs : dict or list of dict, default=None + Keywords arguments to be passed to matplotlib's `plot` function + to draw individual precision-recall curves. For single curve plotting, this + should be a dictionary. For multi-curve plotting, if a list is provided, + the parameters are applied to each precision-recall curve + sequentially and a legend entry is added for each curve. + If a single dictionary is provided, the same parameters are applied + to all curves and a single legend entry for all curves is added, + labeled with the mean average precision. + + .. versionadded:: 1.9 plot_chance_level : bool, default=False Whether to plot the chance level. The chance level is the prevalence @@ -186,6 +277,10 @@ def plot( **kwargs : dict Keyword arguments to be passed to matplotlib's `plot`. + .. deprecated:: 1.9 + kwargs is deprecated and will be removed in 1.11. Pass matplotlib + arguments to `curve_kwargs` as a dictionary instead. + Returns ------- display : :class:`~sklearn.metrics.PrecisionRecallDisplay` @@ -198,25 +293,41 @@ def plot( with this metric, the precision-recall curve is plotted without any interpolation as well (step-wise style). - You can change this style by passing the keyword argument - `drawstyle="default"`. However, the curve will not be strictly - consistent with the reported average precision. + To enable interpolation, pass `curve_kwargs={"drawstyle": "default"}`. + However, the curve will not be strictly consistent with the reported + average precision. """ - self.ax_, self.figure_, name = self._validate_plot_params(ax=ax, name=name) - - default_line_kwargs = {"drawstyle": "steps-post"} - if self.average_precision is not None and name is not None: - default_line_kwargs["label"] = ( - f"{name} (AP = {self.average_precision:0.2f})" - ) - elif self.average_precision is not None: - default_line_kwargs["label"] = f"AP = {self.average_precision:0.2f}" - elif name is not None: - default_line_kwargs["label"] = name - - line_kwargs = _validate_style_kwargs(default_line_kwargs, kwargs) + precision, recall, average_precision, name, prevalence_pos_label = ( + self._validate_plot_params(ax=ax, name=name) + ) + n_curves = len(precision) + average_precision, legend_metric = self._get_legend_metric( + curve_kwargs, n_curves, average_precision + ) - (self.line_,) = self.ax_.plot(self.recall, self.precision, **line_kwargs) + curve_kwargs = self._validate_curve_kwargs( + n_curves, + name, + legend_metric, + "AP", + curve_kwargs=curve_kwargs, + default_curve_kwargs={"drawstyle": "steps-post"}, + default_multi_curve_kwargs={ + "alpha": 0.5, + "linestyle": "--", + "color": "blue", + }, + removed_version="1.11", + **kwargs, + ) + self.line_ = [] + for recall_val, precision_val, curve_kwarg in zip( + recall, precision, curve_kwargs + ): + self.line_.extend(self.ax_.plot(recall_val, precision_val, **curve_kwarg)) + # Return single artist if only one curve is plotted + if len(self.line_) == 1: + self.line_ = self.line_[0] info_pos_label = ( f" (Positive label: {self.pos_label})" if self.pos_label is not None else "" @@ -243,31 +354,52 @@ def plot( "to automatically set prevalence_pos_label" ) - default_chance_level_line_kw = { - "label": f"Chance level (AP = {self.prevalence_pos_label:0.2f})", + default_chance_level_kwargs = { "color": "k", "linestyle": "--", } + if n_curves > 1: + default_chance_level_kwargs["alpha"] = 0.3 if chance_level_kw is None: chance_level_kw = {} - chance_level_line_kw = _validate_style_kwargs( - default_chance_level_line_kw, chance_level_kw + chance_level_kw = _validate_style_kwargs( + default_chance_level_kwargs, chance_level_kw ) + self.chance_level_ = [] + for prevalence in prevalence_pos_label: + self.chance_level_.extend( + self.ax_.plot( + (0, 1), + (prevalence, prevalence), + **chance_level_kw, + ) + ) - (self.chance_level_,) = self.ax_.plot( - (0, 1), - (self.prevalence_pos_label, self.prevalence_pos_label), - **chance_level_line_kw, - ) + if "label" not in chance_level_kw: + label = ( + f"Chance level (AP = {prevalence_pos_label[0]:0.2f})" + if n_curves == 1 + else f"Chance level (AP = {np.mean(prevalence_pos_label):0.2f} " + f"+/- {np.std(prevalence_pos_label):0.2f})" + ) + # Only label first curve with mean AP, to get single legend entry + self.chance_level_[0].set_label(label) + + if n_curves == 1: + # Return single artist if only one curve is plotted + self.chance_level_ = self.chance_level_[0] else: self.chance_level_ = None if despine: _despine(self.ax_) - if "label" in line_kwargs or plot_chance_level: + # Note: if 'label' present in one `line_kwargs`, it should be present in all + if curve_kwargs[0].get("label") is not None or ( + plot_chance_level and chance_level_kw.get("label") is not None + ): self.ax_.legend(loc="lower left") return self @@ -285,6 +417,7 @@ def from_estimator( pos_label=None, name=None, ax=None, + curve_kwargs=None, plot_chance_level=False, chance_level_kw=None, despine=False, @@ -337,6 +470,11 @@ def from_estimator( ax : matplotlib axes, default=None Axes object to plot on. If `None`, a new figure and axes is created. + curve_kwargs : dict, default=None + Keywords arguments to be passed to matplotlib's `plot` function. + + .. versionadded:: 1.9 + plot_chance_level : bool, default=False Whether to plot the chance level. The chance level is the prevalence of the positive label computed from the data passed during @@ -358,6 +496,10 @@ def from_estimator( **kwargs : dict Keyword arguments to be passed to matplotlib's `plot`. + .. deprecated:: 1.9 + kwargs is deprecated and will be removed in 1.11. Pass matplotlib + arguments to `curve_kwargs` as a dictionary instead. + Returns ------- display : :class:`~sklearn.metrics.PrecisionRecallDisplay` @@ -374,9 +516,9 @@ def from_estimator( with this metric, the precision-recall curve is plotted without any interpolation as well (step-wise style). - You can change this style by passing the keyword argument - `drawstyle="default"`. However, the curve will not be strictly - consistent with the reported average precision. + To enable interpolation, pass `curve_kwargs={"drawstyle": "default"}`. + However, the curve will not be strictly consistent with the reported + average precision. Examples -------- @@ -409,10 +551,11 @@ def from_estimator( y, y_score, sample_weight=sample_weight, - name=name, - pos_label=pos_label, drop_intermediate=drop_intermediate, + pos_label=pos_label, + name=name, ax=ax, + curve_kwargs=curve_kwargs, plot_chance_level=plot_chance_level, chance_level_kw=chance_level_kw, despine=despine, @@ -430,6 +573,7 @@ def from_predictions( pos_label=None, name=None, ax=None, + curve_kwargs=None, plot_chance_level=False, chance_level_kw=None, despine=False, @@ -477,6 +621,11 @@ def from_predictions( ax : matplotlib axes, default=None Axes object to plot on. If `None`, a new figure and axes is created. + curve_kwargs : dict, default=None + Keywords arguments to be passed to matplotlib's `plot` function. + + .. versionadded:: 1.9 + plot_chance_level : bool, default=False Whether to plot the chance level. The chance level is the prevalence of the positive label computed from the data passed during @@ -505,6 +654,10 @@ def from_predictions( **kwargs : dict Keyword arguments to be passed to matplotlib's `plot`. + .. deprecated:: 1.9 + kwargs is deprecated and will be removed in 1.11. Pass matplotlib + arguments to `curve_kwargs` as a dictionary instead. + Returns ------- display : :class:`~sklearn.metrics.PrecisionRecallDisplay` @@ -521,9 +674,9 @@ def from_predictions( with this metric, the precision-recall curve is plotted without any interpolation as well (step-wise style). - You can change this style by passing the keyword argument - `drawstyle="default"`. However, the curve will not be strictly - consistent with the reported average precision. + To enable interpolation, pass `curve_kwargs={"drawstyle": "default"}`. + However, the curve will not be strictly consistent with the reported + average precision. Examples -------- @@ -575,8 +728,199 @@ def from_predictions( return viz.plot( ax=ax, name=name, + curve_kwargs=curve_kwargs, plot_chance_level=plot_chance_level, chance_level_kw=chance_level_kw, despine=despine, **kwargs, ) + + @classmethod + def from_cv_results( + cls, + cv_results, + X, + y, + *, + sample_weight=None, + drop_intermediate=True, + response_method="auto", + pos_label=None, + name=None, + ax=None, + curve_kwargs=None, + plot_chance_level=False, + chance_level_kwargs=None, + despine=False, + ): + """Plot multi-fold precision-recall curves given cross-validation results. + + .. versionadded:: 1.9 + + Parameters + ---------- + cv_results : dict + Dictionary as returned by :func:`~sklearn.model_selection.cross_validate` + using `return_estimator=True` and `return_indices=True` (i.e., dictionary + should contain the keys "estimator" and "indices"). + + X : {array-like, sparse matrix} of shape (n_samples, n_features) + Input values. + + y : array-like of shape (n_samples,) + Target values. + + sample_weight : array-like of shape (n_samples,), default=None + Sample weights. + + drop_intermediate : bool, default=True + Whether to drop some suboptimal thresholds which would not appear + on a plotted precision-recall curve. This is useful in order to + create lighter precision-recall curves. + + response_method : {'predict_proba', 'decision_function', 'auto'} \ + default='auto' + Specifies whether to use :term:`predict_proba` or + :term:`decision_function` as the target response. If set to 'auto', + :term:`predict_proba` is tried first and if it does not exist + :term:`decision_function` is tried next. + + pos_label : int, float, bool or str, default=None + The class considered as the positive class when computing the precision + and recall metrics. By default, `estimators.classes_[1]` is considered + as the positive class. + + name : str or list of str, default=None + Name for labeling legend entries. The number of legend entries + is determined by `curve_kwargs`, and is not affected by `name`. + + If a string is provided, it will be used to either label the single legend + entry or if there are multiple legend entries, label each individual curve + with the same name. + + If a list is provided, it will be used to label each curve individually. + Passing a list will raise an error if `curve_kwargs` is not a list to avoid + labeling individual curves that have the same appearance. + + If `None`, no name is shown in the legend. + + ax : matplotlib axes, default=None + Axes object to plot on. If `None`, a new figure and axes is + created. + + curve_kwargs : dict or list of dict, default=None + Dictionary with keywords passed to the matplotlib's `plot` function + to draw the individual precision-recall curves. If a list is provided, the + parameters are applied to the precision-recall curves of each CV fold + sequentially. If a single dictionary is provided, the same + parameters are applied to all precision-recall curves. + + plot_chance_level : bool, default=False + Whether to plot the chance level lines. + + chance_level_kwargs : dict, default=None + Keyword arguments to be passed to matplotlib's `plot` for rendering + the chance level lines. + + despine : bool, default=False + Whether to remove the top and right spines from the plot. + + Returns + ------- + display : :class:`~sklearn.metrics.PrecisionRecallDisplay` + + See Also + -------- + PrecisionRecallDisplay.from_predictions : Plot precision-recall curve + using estimated probabilities or output of decision function. + PrecisionRecallDisplay.from_estimator : Plot precision-recall curve + using an estimator. + precision_recall_curve : Compute precision-recall pairs for different + probability thresholds. + average_precision_score : Compute average precision (AP) from prediction scores. + + Notes + ----- + The average precision (cf. :func:`~sklearn.metrics.average_precision_score`) + in scikit-learn is computed without any interpolation. To be consistent + with this metric, the precision-recall curve is plotted without any + interpolation as well (step-wise style). + + To enable interpolation, pass `curve_kwargs={"drawstyle": "default"}`. + However, the curve will not be strictly consistent with the reported + average precision. + + Examples + -------- + >>> import matplotlib.pyplot as plt + >>> from sklearn.datasets import make_classification + >>> from sklearn.metrics import PrecisionRecallDisplay + >>> from sklearn.model_selection import cross_validate + >>> from sklearn.svm import SVC + >>> X, y = make_classification(random_state=0) + >>> clf = SVC(random_state=0) + >>> cv_results = cross_validate( + ... clf, X, y, cv=3, return_estimator=True, return_indices=True) + >>> PrecisionRecallDisplay.from_cv_results(cv_results, X, y) + <...> + >>> plt.show() + """ + cls._validate_from_cv_results_params( + cv_results, X, y, sample_weight=sample_weight + ) + + precision_folds, recall_folds = [], [] + ap_folds, prevalence_pos_label_folds = [], [] + + for estimator, test_indices in zip( + cv_results["estimator"], cv_results["indices"]["test"] + ): + y_true = _safe_indexing(y, test_indices) + y_pred, pos_label_ = _get_response_values_binary( + estimator, + _safe_indexing(X, test_indices), + response_method=response_method, + pos_label=pos_label, + ) + sample_weight_fold = ( + None + if sample_weight is None + else _safe_indexing(sample_weight, test_indices) + ) + precision, recall, _ = precision_recall_curve( + y_true, + y_pred, + pos_label=pos_label_, + sample_weight=sample_weight_fold, + drop_intermediate=drop_intermediate, + ) + # `average_precision_score` is only metric where default `pos_label=1`, + # thus `pos_label` cannot be None and we use `pos_label_` from + # `_get_response_values_binary` + average_precision = average_precision_score( + y_true, y_pred, pos_label=pos_label_, sample_weight=sample_weight_fold + ) + prevalence_pos_label = ( + np.count_nonzero(y_true == pos_label_) / y_true.shape[0] + ) + + precision_folds.append(precision) + recall_folds.append(recall) + ap_folds.append(average_precision) + prevalence_pos_label_folds.append(prevalence_pos_label) + + viz = cls( + precision=precision_folds, + recall=recall_folds, + average_precision=ap_folds, + name=name, + pos_label=pos_label_, + prevalence_pos_label=prevalence_pos_label_folds, + ) + return viz.plot( + ax=ax, + curve_kwargs=curve_kwargs, + plot_chance_level=plot_chance_level, + chance_level_kw=chance_level_kwargs, + despine=despine, + ) diff --git a/sklearn/metrics/_plot/roc_curve.py b/sklearn/metrics/_plot/roc_curve.py index 3582e61990f75..50f6da1b1be1c 100644 --- a/sklearn/metrics/_plot/roc_curve.py +++ b/sklearn/metrics/_plot/roc_curve.py @@ -2,8 +2,6 @@ # SPDX-License-Identifier: BSD-3-Clause -import numpy as np - from sklearn.metrics._ranking import auc, roc_curve from sklearn.utils import _safe_indexing from sklearn.utils._plotting import ( @@ -247,14 +245,9 @@ def plot( """ fpr, tpr, roc_auc, name = self._validate_plot_params(ax=ax, name=name) n_curves = len(fpr) - if not isinstance(curve_kwargs, list) and n_curves > 1: - if roc_auc: - legend_metric = {"mean": np.mean(roc_auc), "std": np.std(roc_auc)} - else: - legend_metric = {"mean": None, "std": None} - else: - roc_auc = roc_auc if roc_auc is not None else [None] * n_curves - legend_metric = {"metric": roc_auc} + roc_auc, legend_metric = self._get_legend_metric( + curve_kwargs, n_curves, roc_auc + ) curve_kwargs = self._validate_curve_kwargs( n_curves, diff --git a/sklearn/metrics/_plot/tests/test_common_curve_display.py b/sklearn/metrics/_plot/tests/test_common_curve_display.py index a717494e0003f..124c85b8b4205 100644 --- a/sklearn/metrics/_plot/tests/test_common_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_common_curve_display.py @@ -89,7 +89,7 @@ def _check_pos_label_statistics( y_score, pos_label=pos_label, ) - else: + else: # constructor_name = "from_cv_results" display = display_class.from_cv_results( cv_results, X, @@ -116,7 +116,7 @@ def _check_pos_label_statistics( y_score, pos_label=pos_label, ) - else: + else: # constructor_name = "from_cv_results" display = display_class.from_cv_results( cv_results, X, @@ -232,7 +232,9 @@ def fit(self, X, y): "Display", [CalibrationDisplay, DetCurveDisplay, PrecisionRecallDisplay, RocCurveDisplay], ) -@pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) +@pytest.mark.parametrize( + "constructor_name", ["from_estimator", "from_predictions", "from_cv_results"] +) def test_display_curve_name_overwritten_by_plot_multiple_calls( pyplot, data_binary, @@ -244,14 +246,20 @@ def test_display_curve_name_overwritten_by_plot_multiple_calls( clf_name = "my hand-crafted name" clf = LogisticRegression().fit(X, y) y_pred = clf.predict_proba(X)[:, 1] - - # safe guard for the binary if/else construction - assert constructor_name in ("from_estimator", "from_predictions") + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) if constructor_name == "from_estimator": disp = Display.from_estimator(clf, X, y, name=clf_name) - else: + elif constructor_name == "from_predictions": disp = Display.from_predictions(y, y_pred, name=clf_name) + else: # constructor_name = "from_cv_results" + if Display in (RocCurveDisplay, PrecisionRecallDisplay): + disp = Display.from_cv_results(cv_results, X, y, name=clf_name) + else: + pytest.skip(f"`from_cv_results` not implemented in {Display}") + # TODO: Clean-up once `estimator_name` deprecated in all displays if Display in (PrecisionRecallDisplay, RocCurveDisplay): assert disp.name == clf_name @@ -259,11 +267,17 @@ def test_display_curve_name_overwritten_by_plot_multiple_calls( assert disp.estimator_name == clf_name pyplot.close("all") disp.plot() - assert clf_name in disp.line_.get_label() + if constructor_name == "from_cv_results": + assert clf_name in disp.line_[0].get_label() + else: + assert clf_name in disp.line_.get_label() pyplot.close("all") clf_name = "another_name" disp.plot(name=clf_name) - assert clf_name in disp.line_.get_label() + if constructor_name == "from_cv_results": + assert clf_name in disp.line_[0].get_label() + else: + assert clf_name in disp.line_.get_label() @pytest.mark.parametrize( @@ -349,7 +363,7 @@ def test_display_curve_error_pos_label(pyplot, data_binary, Display): ) @pytest.mark.parametrize( "constructor", - ["from_predictions", "from_estimator"], + ["from_predictions", "from_estimator", "from_cv_results"], ) def test_classifier_display_curve_named_constructor_return_type( pyplot, data_binary, Display, constructor @@ -366,14 +380,22 @@ def test_classifier_display_curve_named_constructor_return_type( y_pred = y classifier = LogisticRegression().fit(X, y) + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) class SubclassOfDisplay(Display): pass if constructor == "from_predictions": curve = SubclassOfDisplay.from_predictions(y, y_pred) - else: # constructor == "from_estimator" + elif constructor == "from_estimator": curve = SubclassOfDisplay.from_estimator(classifier, X, y) + else: # `from_cv_results` + if Display in (RocCurveDisplay, PrecisionRecallDisplay): + curve = SubclassOfDisplay.from_cv_results(cv_results, X, y) + else: + pytest.skip(f"`from_cv_results` not implemented in {Display}") assert isinstance(curve, SubclassOfDisplay) @@ -381,6 +403,16 @@ class SubclassOfDisplay(Display): @pytest.mark.parametrize( "Display, display_args", [ + ( + PrecisionRecallDisplay, + { + "precision": np.array([1, 0.5, 0]), + "recall": [np.array([0, 0.5, 1])], + "average_precision": None, + "name": "test_curve", + "prevalence_pos_label": 0.5, + }, + ), ( RocCurveDisplay, { @@ -431,6 +463,19 @@ def test_display_validate_plot_params(pyplot, Display, display_args): }, ) for auc_metric in auc_metrics + ] + + [ + pytest.param( + PrecisionRecallDisplay, + "AP", + "average_precision", + { + "precision": [np.array([1, 0.5, 0])] * 3, + "recall": [np.array([0, 0.5, 1])] * 3, + "average_precision": auc_metric, + }, + ) + for auc_metric in auc_metrics ], ) @pytest.mark.parametrize( @@ -503,9 +548,40 @@ def test_display_plot_legend_label( pyplot.close("all") +@pytest.mark.parametrize("Display", [PrecisionRecallDisplay, RocCurveDisplay]) +@pytest.mark.parametrize( + "constructor_name, expected_clf_name", + [ + ("from_estimator", "LogisticRegression"), + ("from_predictions", "Classifier"), + ], +) +def test_display_default_name( + pyplot, + data_binary, + constructor_name, + expected_clf_name, + Display, +): + # Check the default name display in the figure when `name` is not provided + X, y = data_binary + + lr = LogisticRegression().fit(X, y) + y_score = lr.predict_proba(X)[:, 1] + + if constructor_name == "from_estimator": + disp = Display.from_estimator(lr, X, y) + else: # constructor_name = "from_predictions" + disp = Display.from_predictions(y, y_score) + + assert expected_clf_name in disp.name + assert expected_clf_name in disp.line_.get_label() + + @pytest.mark.parametrize( "Display, auc_metrics, auc_metric_name", [ + (PrecisionRecallDisplay, [0.97, 1.00, 1.00], "AP"), (RocCurveDisplay, [0.96, 1.00, 1.00], "AUC"), ], ) @@ -573,7 +649,7 @@ def test_display_from_cv_results_legend_label( pyplot.close("all") -@pytest.mark.parametrize("Display", [RocCurveDisplay]) +@pytest.mark.parametrize("Display", [PrecisionRecallDisplay, RocCurveDisplay]) def test_display_from_cv_results_param_validation(pyplot, data_binary, Display): """Check parameter validation is correct.""" X, y = data_binary @@ -644,7 +720,7 @@ def test_display_from_cv_results_param_validation(pyplot, data_binary, Display): ) -@pytest.mark.parametrize("Display", [RocCurveDisplay]) +@pytest.mark.parametrize("Display", [PrecisionRecallDisplay, RocCurveDisplay]) def test_display_from_cv_results_pos_label_inferred(pyplot, data_binary, Display): """Check `pos_label` inferred correctly by `from_cv_results(pos_label=None)`.""" X, y = data_binary @@ -657,37 +733,7 @@ def test_display_from_cv_results_pos_label_inferred(pyplot, data_binary, Display assert disp.pos_label == 1 -@pytest.mark.parametrize("Display", [RocCurveDisplay]) -@pytest.mark.parametrize( - "constructor_name, expected_clf_name", - [ - ("from_estimator", "LogisticRegression"), - ("from_predictions", "Classifier"), - ], -) -def test_display_default_name( - pyplot, - data_binary, - constructor_name, - expected_clf_name, - Display, -): - """Check the default name display in the figure when `name` is not provided.""" - X, y = data_binary - - lr = LogisticRegression().fit(X, y) - y_score = lr.predict_proba(X)[:, 1] - - if constructor_name == "from_estimator": - disp = Display.from_estimator(lr, X, y) - else: - disp = Display.from_predictions(y, y_score) - - assert expected_clf_name in disp.name - assert expected_clf_name in disp.line_.get_label() - - -@pytest.mark.parametrize("Display", [RocCurveDisplay]) +@pytest.mark.parametrize("Display", [PrecisionRecallDisplay, RocCurveDisplay]) @pytest.mark.parametrize( "curve_kwargs", [None, {"alpha": 0.2}, [{"alpha": 0.2}, {"alpha": 0.3}, {"alpha": 0.4}]], @@ -695,7 +741,7 @@ def test_display_default_name( def test_display_from_cv_results_curve_kwargs( pyplot, data_binary, curve_kwargs, Display ): - """Check `curve_kwargs` correctly passed.""" + """Check `curve_kwargs` correctly passed from `from_cv_results`.""" X, y = data_binary cv_results = cross_validate( LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True @@ -720,7 +766,7 @@ def test_display_from_cv_results_curve_kwargs( ) -@pytest.mark.parametrize("Display", [RocCurveDisplay]) +@pytest.mark.parametrize("Display", [PrecisionRecallDisplay, RocCurveDisplay]) @pytest.mark.parametrize( "curve_kwargs", [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], @@ -764,3 +810,45 @@ def test_display_estimator_name_deprecation(pyplot, Display, display_kwargs): """Check deprecation of `estimator_name`.""" with pytest.warns(FutureWarning, match="`estimator_name` is deprecated in"): Display(**display_kwargs, estimator_name="test") + + +@pytest.mark.parametrize( + "Display, display_kwargs", + [ + # TODO(1.11): Remove + ( + PrecisionRecallDisplay, + {"precision": np.array([1, 0.5, 0]), "recall": np.array([0, 0.5, 1])}, + ), + # TODO(1.9): Remove + (RocCurveDisplay, {"fpr": np.array([0, 0.5, 1]), "tpr": np.array([0, 0.5, 1])}), + ], +) +@pytest.mark.parametrize( + "constructor_name", ["from_estimator", "from_predictions", "plot"] +) +def test_display_kwargs_deprecation( + pyplot, data_binary, constructor_name, Display, display_kwargs +): + """Check **kwargs deprecated correctly in favour of `curve_kwargs`.""" + X, y = data_binary + lr = LogisticRegression() + lr.fit(X, y) + + # Error when both `curve_kwargs` and `**kwargs` provided + with pytest.raises(ValueError, match="Cannot provide both `curve_kwargs`"): + if constructor_name == "from_estimator": + Display.from_estimator(lr, X, y, curve_kwargs={"alpha": 1}, label="test") + elif constructor_name == "from_predictions": + Display.from_predictions(y, y, curve_kwargs={"alpha": 1}, label="test") + else: # constructor_name = "plot" + Display(**display_kwargs).plot(curve_kwargs={"alpha": 1}, label="test") + + # Warning when `**kwargs`` provided + with pytest.warns(FutureWarning, match=r"`\*\*kwargs` is deprecated and will be"): + if constructor_name == "from_estimator": + Display.from_estimator(lr, X, y, label="test") + elif constructor_name == "from_predictions": + Display.from_predictions(y, y, label="test") + else: # constructor_name = "plot" + Display(**display_kwargs).plot(label="test") diff --git a/sklearn/metrics/_plot/tests/test_precision_recall_display.py b/sklearn/metrics/_plot/tests/test_precision_recall_display.py index 68b187a829061..6db603dbdd8cf 100644 --- a/sklearn/metrics/_plot/tests/test_precision_recall_display.py +++ b/sklearn/metrics/_plot/tests/test_precision_recall_display.py @@ -2,7 +2,6 @@ import numpy as np import pytest -from scipy.integrate import trapezoid from sklearn.compose import make_column_transformer from sklearn.datasets import load_breast_cancer, make_classification @@ -13,25 +12,57 @@ average_precision_score, precision_recall_curve, ) -from sklearn.model_selection import train_test_split +from sklearn.metrics._plot.tests.test_common_curve_display import ( + _check_pos_label_statistics, +) +from sklearn.model_selection import cross_validate from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler -from sklearn.utils import shuffle +from sklearn.utils import _safe_indexing +from sklearn.utils._response import _get_response_values_binary +from sklearn.utils._testing import assert_allclose + + +def _check_figure_axes_and_labels(display, pos_label): + """Check mpl figure and axes are correct.""" + import matplotlib as mpl + + assert isinstance(display.ax_, mpl.axes.Axes) + assert isinstance(display.figure_, mpl.figure.Figure) + + assert display.ax_.get_xlabel() == f"Recall (Positive label: {pos_label})" + assert display.ax_.get_ylabel() == f"Precision (Positive label: {pos_label})" + assert display.ax_.get_adjustable() == "box" + assert display.ax_.get_aspect() in ("equal", 1.0) + assert display.ax_.get_xlim() == display.ax_.get_ylim() == (-0.01, 1.01) @pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) @pytest.mark.parametrize("response_method", ["predict_proba", "decision_function"]) @pytest.mark.parametrize("drop_intermediate", [True, False]) +@pytest.mark.parametrize("with_sample_weight", [True, False]) def test_precision_recall_display_plotting( - pyplot, constructor_name, response_method, drop_intermediate + pyplot, + constructor_name, + response_method, + drop_intermediate, + with_sample_weight, ): """Check the overall plotting rendering.""" + import matplotlib as mpl + X, y = make_classification(n_classes=2, n_samples=50, random_state=0) pos_label = 1 classifier = LogisticRegression().fit(X, y) classifier.fit(X, y) + if with_sample_weight: + rng = np.random.RandomState(42) + sample_weight = rng.randint(1, 4, size=(X.shape[0])) + else: + sample_weight = None + y_score = getattr(classifier, response_method)(X) y_score = y_score if y_score.ndim == 1 else y_score[:, pos_label] @@ -43,37 +74,41 @@ def test_precision_recall_display_plotting( classifier, X, y, + sample_weight=sample_weight, response_method=response_method, drop_intermediate=drop_intermediate, ) else: display = PrecisionRecallDisplay.from_predictions( - y, y_score, pos_label=pos_label, drop_intermediate=drop_intermediate + y, + y_score, + sample_weight=sample_weight, + pos_label=pos_label, + drop_intermediate=drop_intermediate, ) precision, recall, _ = precision_recall_curve( - y, y_score, pos_label=pos_label, drop_intermediate=drop_intermediate + y, + y_score, + pos_label=pos_label, + sample_weight=sample_weight, + drop_intermediate=drop_intermediate, + ) + average_precision = average_precision_score( + y, y_score, pos_label=pos_label, sample_weight=sample_weight ) - average_precision = average_precision_score(y, y_score, pos_label=pos_label) - np.testing.assert_allclose(display.precision, precision) - np.testing.assert_allclose(display.recall, recall) + assert_allclose(display.precision, precision) + assert_allclose(display.recall, recall) assert display.average_precision == pytest.approx(average_precision) - import matplotlib as mpl - + _check_figure_axes_and_labels(display, pos_label) assert isinstance(display.line_, mpl.lines.Line2D) - assert isinstance(display.ax_, mpl.axes.Axes) - assert isinstance(display.figure_, mpl.figure.Figure) - - assert display.ax_.get_xlabel() == "Recall (Positive label: 1)" - assert display.ax_.get_ylabel() == "Precision (Positive label: 1)" - assert display.ax_.get_adjustable() == "box" - assert display.ax_.get_aspect() in ("equal", 1.0) - assert display.ax_.get_xlim() == display.ax_.get_ylim() == (-0.01, 1.01) + # Check default curve kwarg + assert display.line_.get_drawstyle() == "steps-post" # plotting passing some new parameters - display.plot(alpha=0.8, name="MySpecialEstimator") + display.plot(name="MySpecialEstimator", curve_kwargs={"alpha": 0.8}) expected_label = f"MySpecialEstimator (AP = {average_precision:0.2f})" assert display.line_.get_label() == expected_label assert display.line_.get_alpha() == pytest.approx(0.8) @@ -82,14 +117,168 @@ def test_precision_recall_display_plotting( assert display.chance_level_ is None +@pytest.mark.parametrize("response_method", ["predict_proba", "decision_function"]) +@pytest.mark.parametrize("drop_intermediate", [True, False]) +@pytest.mark.parametrize("with_sample_weight", [True, False]) +def test_precision_recall_display_from_cv_results_plotting( + pyplot, response_method, drop_intermediate, with_sample_weight +): + """Check the overall plotting of `from_cv_results`.""" + import matplotlib as mpl + + X, y = make_classification(n_classes=2, n_samples=50, random_state=0) + pos_label = 1 + + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) + + if with_sample_weight: + rng = np.random.RandomState(42) + sample_weight = rng.randint(1, 4, size=(X.shape[0])) + else: + sample_weight = None + + display = PrecisionRecallDisplay.from_cv_results( + cv_results, + X, + y, + sample_weight=sample_weight, + response_method=response_method, + drop_intermediate=drop_intermediate, + pos_label=pos_label, + ) + + for idx, (estimator, test_indices) in enumerate( + zip(cv_results["estimator"], cv_results["indices"]["test"]) + ): + y_true = _safe_indexing(y, test_indices) + y_score = getattr(estimator, response_method)(_safe_indexing(X, test_indices)) + y_score = y_score if y_score.ndim == 1 else y_score[:, 1] + sample_weight_test = ( + _safe_indexing(sample_weight, test_indices) + if sample_weight is not None + else None + ) + precision, recall, _ = precision_recall_curve( + y_true, + y_score, + pos_label=pos_label, + drop_intermediate=drop_intermediate, + sample_weight=sample_weight_test, + ) + average_precision = average_precision_score( + y_true, y_score, pos_label=pos_label, sample_weight=sample_weight_test + ) + + assert_allclose(display.precision[idx], precision) + assert_allclose(display.recall[idx], recall) + assert display.average_precision[idx] == pytest.approx(average_precision) + + assert isinstance(display.line_[idx], mpl.lines.Line2D) + # Check default curve kwarg + assert display.line_[idx].get_drawstyle() == "steps-post" + + _check_figure_axes_and_labels(display, pos_label) + # Check that the chance level line is not plotted by default + assert display.chance_level_ is None + + +@pytest.mark.parametrize( + "params, err_msg", + [ + ( + { + "precision": [np.array([1, 0.5, 0]), np.array([1, 0.5, 0])], + "recall": [np.array([0, 0.5, 1])], + "average_precision": None, + "prevalence_pos_label": None, + "name": None, + }, + "self.precision and self.recall from `PrecisionRecallDisplay`", + ), + ( + { + "precision": [np.array([1, 0.5, 0])], + "recall": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "average_precision": [0.8, 0.9], + "prevalence_pos_label": None, + "name": None, + }, + "self.precision, self.recall and self.average_precision", + ), + ( + { + "precision": [np.array([1, 0.5, 0])], + "recall": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "average_precision": [0.8, 0.9], + "prevalence_pos_label": [0.5, 0.5, 0.5], + "name": None, + }, + ( + "self.precision, self.recall, self.average_precision and " + "self.prevalence_pos_label" + ), + ), + ( + { + "precision": [np.array([1, 0.5, 0]), np.array([1, 0.5, 0])], + "recall": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "average_precision": [0.8], + "prevalence_pos_label": [0.8, 0.6, 0.5], + "name": None, + }, + ( + "Got: self.precision: 2, self.recall: 2, self.average_precision: 1, " + "self.prevalence_pos_label: 3" + ), + ), + ( + { + "precision": [np.array([1, 0.5, 0]), np.array([1, 0.5, 0])], + "recall": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "average_precision": [0.8, 0.9], + "prevalence_pos_label": None, + "name": ["curve1", "curve2", "curve3"], + }, + ( + "self.precision, self.recall, self.average_precision and 'name' " + r"\(or self.name\)" + ), + ), + ( + { + "precision": [np.array([1, 0.5, 0]), np.array([1, 0.5, 0])], + "recall": [np.array([0, 0.5, 1]), np.array([0, 0.5, 1])], + "average_precision": [0.8, 0.9], + "prevalence_pos_label": [0.5, 0.4], + # List of length 1 is always allowed + "name": ["curve1"], + }, + None, + ), + ], +) +def test_precison_recall_plot_parameter_length_validation(pyplot, params, err_msg): + """Check `plot` parameter length validation performed correctly.""" + display = PrecisionRecallDisplay(**params) + if err_msg: + with pytest.raises(ValueError, match=err_msg): + display.plot() + else: + # No error should be raised + display.plot() + + +@pytest.mark.parametrize("plot_chance_level", [True, False]) @pytest.mark.parametrize("chance_level_kw", [None, {"color": "r"}, {"c": "r"}]) @pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) def test_precision_recall_chance_level_line( - pyplot, - chance_level_kw, - constructor_name, + pyplot, plot_chance_level, chance_level_kw, constructor_name ): - """Check the chance level line plotting behavior.""" + """Check chance level plotting behavior, for `from_estimator`/`from_predictions`.""" + import matplotlib as mpl + X, y = make_classification(n_classes=2, n_samples=50, random_state=0) pos_prevalence = Counter(y)[1] / len(y) @@ -101,18 +290,21 @@ def test_precision_recall_chance_level_line( lr, X, y, - plot_chance_level=True, + plot_chance_level=plot_chance_level, chance_level_kw=chance_level_kw, ) else: display = PrecisionRecallDisplay.from_predictions( y, y_score, - plot_chance_level=True, + plot_chance_level=plot_chance_level, chance_level_kw=chance_level_kw, ) - import matplotlib as mpl + if not plot_chance_level: + assert display.chance_level_ is None + # Early return if chance level not plotted + return assert isinstance(display.chance_level_, mpl.lines.Line2D) assert tuple(display.chance_level_.get_xdata()) == (0, 1) @@ -124,12 +316,72 @@ def test_precision_recall_chance_level_line( else: assert display.chance_level_.get_color() == "r" + assert display.chance_level_.get_label() == f"Chance level (AP = {pos_prevalence})" + + +@pytest.mark.parametrize("plot_chance_level", [True, False]) +@pytest.mark.parametrize("chance_level_kw", [None, {"color": "r"}, {"c": "r"}]) +def test_precision_recall_chance_level_line_from_cv_results( + pyplot, plot_chance_level, chance_level_kw +): + """Check chance level plotting behavior for `from_cv_results`.""" + import matplotlib as mpl + + # Note a separate chance line is plotted for each cv split + X, y = make_classification(n_classes=2, n_samples=50, random_state=0) + n_cv = 3 + cv_results = cross_validate( + LogisticRegression(), X, y, cv=n_cv, return_estimator=True, return_indices=True + ) + + display = PrecisionRecallDisplay.from_cv_results( + cv_results, + X, + y, + plot_chance_level=plot_chance_level, + chance_level_kwargs=chance_level_kw, + ) + + if not plot_chance_level: + assert display.chance_level_ is None + # Early return if chance level not plotted + return + + pos_prevalence_folds = [] + for idx in range(n_cv): + assert isinstance(display.chance_level_[idx], mpl.lines.Line2D) + assert tuple(display.chance_level_[idx].get_xdata()) == (0, 1) + test_indices = cv_results["indices"]["test"][idx] + pos_prevalence = Counter(_safe_indexing(y, test_indices))[1] / len(test_indices) + pos_prevalence_folds.append(pos_prevalence) + assert tuple(display.chance_level_[idx].get_ydata()) == ( + pos_prevalence, + pos_prevalence, + ) + + # Checking for chance level line styles + if chance_level_kw is None: + assert display.chance_level_[idx].get_color() == "k" + else: + assert display.chance_level_[idx].get_color() == "r" + + for idx in range(n_cv): + # Only the first chance line should have a label + if idx == 0: + assert display.chance_level_[idx].get_label() == ( + f"Chance level (AP = {np.mean(pos_prevalence_folds):0.2f} +/- " + f"{np.std(pos_prevalence_folds):0.2f})" + ) + else: + assert display.chance_level_[idx].get_label() == f"_child{3 + idx}" + @pytest.mark.parametrize( "constructor_name, default_label", [ ("from_estimator", "LogisticRegression (AP = {:.2f})"), ("from_predictions", "Classifier (AP = {:.2f})"), + ("from_cv_results", "AP = {:.2f} +/- {:.2f}"), ], ) def test_precision_recall_display_name(pyplot, constructor_name, default_label): @@ -137,32 +389,61 @@ def test_precision_recall_display_name(pyplot, constructor_name, default_label): X, y = make_classification(n_classes=2, n_samples=100, random_state=0) pos_label = 1 - classifier = LogisticRegression().fit(X, y) + classifier = LogisticRegression() + n_cv = 3 + cv_results = cross_validate( + classifier, X, y, cv=n_cv, return_estimator=True, return_indices=True + ) classifier.fit(X, y) - y_score = classifier.predict_proba(X)[:, pos_label] - # safe guard for the binary if/else construction - assert constructor_name in ("from_estimator", "from_predictions") - if constructor_name == "from_estimator": display = PrecisionRecallDisplay.from_estimator(classifier, X, y) - else: + elif constructor_name == "from_predictions": display = PrecisionRecallDisplay.from_predictions( y, y_score, pos_label=pos_label ) + else: # constructor_name = "from_cv_results" + display = PrecisionRecallDisplay.from_cv_results(cv_results, X, y) + + if constructor_name == "from_cv_results": + average_precision = [] + for idx in range(n_cv): + test_indices = cv_results["indices"]["test"][idx] + y_score, _ = _get_response_values_binary( + cv_results["estimator"][idx], + _safe_indexing(X, test_indices), + response_method="auto", + ) + average_precision.append( + average_precision_score( + _safe_indexing(y, test_indices), y_score, pos_label=pos_label + ) + ) + # By default, only the first curve is labelled + assert display.line_[0].get_label() == default_label.format( + np.mean(average_precision), np.std(average_precision) + ) - average_precision = average_precision_score(y, y_score, pos_label=pos_label) + # check that the name can be set + display.plot(name="MySpecialEstimator") + # Sets only first labelled curve + assert display.line_[0].get_label() == ( + f"MySpecialEstimator (AP = {np.mean(average_precision):.2f} +/- " + f"{np.std(average_precision):.2f})" + ) + else: + average_precision = average_precision_score(y, y_score, pos_label=pos_label) - # check that the default name is used - assert display.line_.get_label() == default_label.format(average_precision) + # check that the default name is used + assert display.line_.get_label() == default_label.format(average_precision) - # check that the name can be set - display.plot(name="MySpecialEstimator") - assert ( - display.line_.get_label() - == f"MySpecialEstimator (AP = {average_precision:.2f})" - ) + # check that the name can be set + display.plot(name="MySpecialEstimator") + assert ( + display.line_.get_label() + == f"MySpecialEstimator (AP = {average_precision:.2f})" + ) @pytest.mark.parametrize( @@ -189,9 +470,15 @@ def test_precision_recall_display_string_labels(pyplot): X, y = cancer.data, cancer.target_names[cancer.target] lr = make_pipeline(StandardScaler(), LogisticRegression()) + n_cv = 3 + cv_results = cross_validate( + lr, X, y, cv=n_cv, return_estimator=True, return_indices=True + ) lr.fit(X, y) for klass in cancer.target_names: assert klass in lr.classes_ + + # `from_estimator` display = PrecisionRecallDisplay.from_estimator(lr, X, y) y_score = lr.predict_proba(X)[:, 1] @@ -200,6 +487,7 @@ def test_precision_recall_display_string_labels(pyplot): assert display.average_precision == pytest.approx(avg_prec) assert display.name == lr.__class__.__name__ + # `from_predictions` err_msg = r"y_true takes value in {'benign', 'malignant'}" with pytest.raises(ValueError, match=err_msg): PrecisionRecallDisplay.from_predictions(y, y_score) @@ -209,6 +497,26 @@ def test_precision_recall_display_string_labels(pyplot): ) assert display.average_precision == pytest.approx(avg_prec) + # `from_cv_results` + display = PrecisionRecallDisplay.from_cv_results(cv_results, X, y) + average_precision = [] + for idx in range(n_cv): + test_indices = cv_results["indices"]["test"][idx] + y_pred, _ = _get_response_values_binary( + cv_results["estimator"][idx], + _safe_indexing(X, test_indices), + response_method="auto", + ) + # Note `pos_label` cannot be `None` (default=1), unlike other metrics + average_precision.append( + average_precision_score( + _safe_indexing(y, test_indices), + y_pred, + pos_label=cv_results["estimator"][idx].classes_[1], + ) + ) + assert_allclose(display.average_precision, average_precision) + @pytest.mark.parametrize( "average_precision, name, expected_label", @@ -235,104 +543,83 @@ def test_default_labels(pyplot, average_precision, name, expected_label): @pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) @pytest.mark.parametrize("response_method", ["predict_proba", "decision_function"]) def test_plot_precision_recall_pos_label(pyplot, constructor_name, response_method): - # check that we can provide the positive label and display the proper - # statistics - X, y = load_breast_cancer(return_X_y=True) - # create a highly imbalanced version of the breast cancer dataset - idx_positive = np.flatnonzero(y == 1) - idx_negative = np.flatnonzero(y == 0) - idx_selected = np.hstack([idx_negative, idx_positive[:25]]) - X, y = X[idx_selected], y[idx_selected] - X, y = shuffle(X, y, random_state=42) - # only use 2 features to make the problem even harder - X = X[:, :2] - y = np.array(["cancer" if c == 1 else "not cancer" for c in y], dtype=object) - X_train, X_test, y_train, y_test = train_test_split( - X, - y, - stratify=y, - random_state=0, + """Check switching `pos_label` give correct statistics, using imbalanced data.""" + + def _check_average_precision(display, constructor_name, pos_label): + if pos_label == "cancer": + avg_prec_limit = 0.6338 + avg_prec_limit_multi = [0.8189, 0.8802, 0.8795] + else: + avg_prec_limit = 0.9953 + avg_prec_limit_multi = [0.9966, 0.9984, 0.9976] + + def average_precision_uninterpolated(precision, recall): + return -np.sum(np.diff(recall) * np.array(precision)[:-1]) + + if constructor_name == "from_cv_results": + for idx, average_precision in enumerate(display.average_precision): + assert average_precision == pytest.approx( + avg_prec_limit_multi[idx], rel=1e-3 + ) + assert average_precision_uninterpolated( + display.precision[idx], display.recall[idx] + ) == pytest.approx(avg_prec_limit_multi[idx], rel=1e-3) + else: + assert display.average_precision == pytest.approx(avg_prec_limit, rel=1e-3) + assert average_precision_uninterpolated( + display.precision, display.recall + ) == pytest.approx(avg_prec_limit, rel=1e-3) + + _check_pos_label_statistics( + PrecisionRecallDisplay, + response_method, + constructor_name, + _check_average_precision, ) - classifier = LogisticRegression() - classifier.fit(X_train, y_train) - - # sanity check to be sure the positive class is classes_[0] and that we - # are betrayed by the class imbalance - assert classifier.classes_.tolist() == ["cancer", "not cancer"] - - y_score = getattr(classifier, response_method)(X_test) - # we select the corresponding probability columns or reverse the decision - # function otherwise - y_score_cancer = -1 * y_score if y_score.ndim == 1 else y_score[:, 0] - y_score_not_cancer = y_score if y_score.ndim == 1 else y_score[:, 1] - - if constructor_name == "from_estimator": - display = PrecisionRecallDisplay.from_estimator( - classifier, - X_test, - y_test, - pos_label="cancer", - response_method=response_method, - ) - else: - display = PrecisionRecallDisplay.from_predictions( - y_test, - y_score_cancer, - pos_label="cancer", - ) - # we should obtain the statistics of the "cancer" class - avg_prec_limit = 0.65 - assert display.average_precision < avg_prec_limit - assert -trapezoid(display.precision, display.recall) < avg_prec_limit - - # otherwise we should obtain the statistics of the "not cancer" class - if constructor_name == "from_estimator": - display = PrecisionRecallDisplay.from_estimator( - classifier, - X_test, - y_test, - response_method=response_method, - pos_label="not cancer", - ) - else: - display = PrecisionRecallDisplay.from_predictions( - y_test, - y_score_not_cancer, - pos_label="not cancer", - ) - avg_prec_limit = 0.95 - assert display.average_precision > avg_prec_limit - assert -trapezoid(display.precision, display.recall) > avg_prec_limit - -@pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) +@pytest.mark.parametrize( + "constructor_name", ["from_estimator", "from_predictions", "from_cv_results"] +) def test_precision_recall_prevalence_pos_label_reusable(pyplot, constructor_name): # Check that even if one passes plot_chance_level=False the first time # one can still call disp.plot with plot_chance_level=True and get the # chance level line + + import matplotlib as mpl + X, y = make_classification(n_classes=2, n_samples=50, random_state=0) lr = LogisticRegression() + n_cv = 3 + cv_results = cross_validate( + lr, X, y, cv=n_cv, return_estimator=True, return_indices=True + ) y_score = lr.fit(X, y).predict_proba(X)[:, 1] if constructor_name == "from_estimator": display = PrecisionRecallDisplay.from_estimator( lr, X, y, plot_chance_level=False ) - else: + elif constructor_name == "from_predictions": display = PrecisionRecallDisplay.from_predictions( y, y_score, plot_chance_level=False ) + else: + display = PrecisionRecallDisplay.from_cv_results( + cv_results, X, y, plot_chance_level=False + ) assert display.chance_level_ is None - import matplotlib as mpl - # When calling from_estimator or from_predictions, # prevalence_pos_label should have been set, so that directly # calling plot_chance_level=True should plot the chance level line display.plot(plot_chance_level=True) - assert isinstance(display.chance_level_, mpl.lines.Line2D) + if constructor_name == "from_cv_results": + for idx in range(n_cv): + assert isinstance(display.chance_level_[idx], mpl.lines.Line2D) + else: + assert isinstance(display.chance_level_, mpl.lines.Line2D) def test_precision_recall_raise_no_prevalence(pyplot): @@ -356,23 +643,29 @@ def test_precision_recall_raise_no_prevalence(pyplot): @pytest.mark.parametrize("despine", [True, False]) -@pytest.mark.parametrize("constructor_name", ["from_estimator", "from_predictions"]) +@pytest.mark.parametrize( + "constructor_name", ["from_estimator", "from_predictions", "from_cv_results"] +) def test_plot_precision_recall_despine(pyplot, despine, constructor_name): # Check that the despine keyword is working correctly X, y = make_classification(n_classes=2, n_samples=50, random_state=0) clf = LogisticRegression().fit(X, y) clf.fit(X, y) + cv_results = cross_validate( + LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True + ) y_score = clf.decision_function(X) - # safe guard for the binary if/else construction - assert constructor_name in ("from_estimator", "from_predictions") - if constructor_name == "from_estimator": display = PrecisionRecallDisplay.from_estimator(clf, X, y, despine=despine) - else: + elif constructor_name == "from_predictions": display = PrecisionRecallDisplay.from_predictions(y, y_score, despine=despine) + else: + display = PrecisionRecallDisplay.from_cv_results( + cv_results, X, y, despine=despine + ) for s in ["top", "right"]: assert display.ax_.spines[s].get_visible() is not despine diff --git a/sklearn/metrics/_plot/tests/test_roc_curve_display.py b/sklearn/metrics/_plot/tests/test_roc_curve_display.py index 2049ff34e3546..4bb7a89e236ad 100644 --- a/sklearn/metrics/_plot/tests/test_roc_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_roc_curve_display.py @@ -1,5 +1,3 @@ -from collections.abc import Mapping - import numpy as np import pytest from numpy.testing import assert_allclose @@ -200,43 +198,6 @@ def test_roc_curve_plot_parameter_length_validation(pyplot, params, err_msg): display.plot() -# TODO(1.9): Remove in 1.9 -@pytest.mark.parametrize( - "constructor_name", ["from_estimator", "from_predictions", "plot"] -) -def test_roc_curve_display_kwargs_deprecation(pyplot, data_binary, constructor_name): - """Check **kwargs deprecated correctly in favour of `curve_kwargs`.""" - X, y = data_binary - lr = LogisticRegression() - lr.fit(X, y) - fpr = np.array([0, 0.5, 1]) - tpr = np.array([0, 0.5, 1]) - - # Error when both `curve_kwargs` and `**kwargs` provided - with pytest.raises(ValueError, match="Cannot provide both `curve_kwargs`"): - if constructor_name == "from_estimator": - RocCurveDisplay.from_estimator( - lr, X, y, curve_kwargs={"alpha": 1}, label="test" - ) - elif constructor_name == "from_predictions": - RocCurveDisplay.from_predictions( - y, y, curve_kwargs={"alpha": 1}, label="test" - ) - else: - RocCurveDisplay(fpr=fpr, tpr=tpr).plot( - curve_kwargs={"alpha": 1}, label="test" - ) - - # Warning when `**kwargs`` provided - with pytest.warns(FutureWarning, match=r"`\*\*kwargs` is deprecated and will be"): - if constructor_name == "from_estimator": - RocCurveDisplay.from_estimator(lr, X, y, label="test") - elif constructor_name == "from_predictions": - RocCurveDisplay.from_predictions(y, y, label="test") - else: - RocCurveDisplay(fpr=fpr, tpr=tpr).plot(label="test") - - @pytest.mark.parametrize( "curve_kwargs", [ @@ -333,33 +294,6 @@ def test_roc_curve_display_plotting_from_cv_results( assert line.get_label() == aggregate_expected_labels[idx] -@pytest.mark.parametrize( - "curve_kwargs", - [None, {"color": "red"}, [{"c": "red"}, {"c": "green"}, {"c": "yellow"}]], -) -def test_roc_curve_from_cv_results_curve_kwargs(pyplot, data_binary, curve_kwargs): - """Check line kwargs passed correctly in `from_cv_results`.""" - - X, y = data_binary - cv_results = cross_validate( - LogisticRegression(), X, y, cv=3, return_estimator=True, return_indices=True - ) - display = RocCurveDisplay.from_cv_results( - cv_results, X, y, curve_kwargs=curve_kwargs - ) - - for idx, line in enumerate(display.line_): - color = line.get_color() - if curve_kwargs is None: - # Default color - assert color == "blue" - elif isinstance(curve_kwargs, Mapping): - # All curves "red" - assert color == "red" - else: - assert color == curve_kwargs[idx]["c"] - - def _check_chance_level(plot_chance_level, chance_level_kw, display): """Check chance level line and line styles correct.""" import matplotlib as mpl diff --git a/sklearn/utils/_plotting.py b/sklearn/utils/_plotting.py index 2486d5cba72bc..3d13c4aa66869 100644 --- a/sklearn/utils/_plotting.py +++ b/sklearn/utils/_plotting.py @@ -106,6 +106,19 @@ def _validate_from_cv_results_params( ) check_consistent_length(X, y, sample_weight) + @staticmethod + def _get_legend_metric(curve_kwargs, n_curves, metric): + """Generate legend information dictionary and expand `metric` if required.""" + if not isinstance(curve_kwargs, list) and n_curves > 1: + if metric: + legend_metric = {"mean": np.mean(metric), "std": np.std(metric)} + else: + legend_metric = {"mean": None, "std": None} + else: + metric = metric if metric is not None else [None] * n_curves + legend_metric = {"metric": metric} + return metric, legend_metric + @staticmethod def _get_legend_label(curve_legend_metric, curve_name, legend_metric_name): """Helper to get legend label using `name` and `legend_metric`""" @@ -128,6 +141,7 @@ def _validate_curve_kwargs( curve_kwargs, default_curve_kwargs=None, default_multi_curve_kwargs=None, + removed_version="1.9", **kwargs, ): """Get validated line kwargs for each curve. @@ -162,20 +176,24 @@ def _validate_curve_kwargs( Default curve kwargs for multi-curve plots. Individual kwargs are over-ridden by `curve_kwargs`, if kwarg also set in `curve_kwargs`. + removed_version : str, default="1.9" + Version in which `kwargs` will be removed. + **kwargs : dict Deprecated. Keyword arguments to be passed to matplotlib's `plot`. """ - # TODO(1.9): Remove deprecated **kwargs + # TODO: Remove once kwargs deprecated on all displays if curve_kwargs and kwargs: raise ValueError( "Cannot provide both `curve_kwargs` and `kwargs`. `**kwargs` is " - "deprecated in 1.7 and will be removed in 1.9. Pass all matplotlib " - "arguments to `curve_kwargs` as a dictionary." + f"deprecated and will be removed in {removed_version}. Pass all " + "matplotlib arguments to `curve_kwargs` as a dictionary." ) if kwargs: warnings.warn( - "`**kwargs` is deprecated and will be removed in 1.9. Pass all " - "matplotlib arguments to `curve_kwargs` as a dictionary instead.", + f"`**kwargs` is deprecated and will be removed in {removed_version}. " + "Pass all matplotlib arguments to `curve_kwargs` as a dictionary " + "instead.", FutureWarning, ) curve_kwargs = kwargs @@ -196,7 +214,7 @@ def _validate_curve_kwargs( "To avoid labeling individual curves that have the same appearance, " f"`curve_kwargs` should be a list of {n_curves} dictionaries. " "Alternatively, set `name` to `None` or a single string to label " - "a single legend entry with mean ROC AUC score of all curves." + "a single legend entry for all curves." ) # Ensure `name` is of the correct length diff --git a/sklearn/utils/tests/test_plotting.py b/sklearn/utils/tests/test_plotting.py index f7a585824ff84..94357dd761f69 100644 --- a/sklearn/utils/tests/test_plotting.py +++ b/sklearn/utils/tests/test_plotting.py @@ -196,7 +196,7 @@ def test_get_legend_label(curve_legend_metric, curve_name, expected_label): assert label == expected_label -# TODO(1.9) : Remove +# TODO: Remove once kwargs deprecated on all displays @pytest.mark.parametrize("curve_kwargs", [{"alpha": 1.0}, None]) @pytest.mark.parametrize("kwargs", [{}, {"alpha": 1.0}]) def test_validate_curve_kwargs_deprecate_kwargs(curve_kwargs, kwargs): @@ -266,8 +266,7 @@ def test_validate_curve_kwargs_error(): @pytest.mark.parametrize("name", [None, "curve_name", ["curve_name"]]) @pytest.mark.parametrize( - "legend_metric", - [{"mean": 0.8, "std": 0.2}, {"mean": None, "std": None}], + "legend_metric", [{"mean": 0.8, "std": 0.2}, {"mean": None, "std": None}] ) @pytest.mark.parametrize("legend_metric_name", ["AUC", "AP"]) @pytest.mark.parametrize("curve_kwargs", [None, {"color": "red"}]) From 022217383f4f9282ca36587fe52fe9d0101c4853 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= Date: Tue, 24 Feb 2026 11:22:58 +0100 Subject: [PATCH 241/462] API Deprecate positional args for confusion_matrix_at_thresholds (#33357) Co-authored-by: Lucy Liu --- .../upcoming_changes/sklearn.metrics/33357.api.rst | 4 ++++ sklearn/metrics/_ranking.py | 11 +++++++++-- sklearn/metrics/tests/test_ranking.py | 8 ++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/33357.api.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/33357.api.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/33357.api.rst new file mode 100644 index 0000000000000..362f6cd1cd710 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.metrics/33357.api.rst @@ -0,0 +1,4 @@ +- Passing the `pos_label` and `sample_weight` parameters of + :func:`metrics.confusion_matrix_at_thresholds` as positional arguments is deprecated + and will be removed in v1.11. + By :user:`Jérémie du Boisberranger `. diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index 8712c63f0780a..2f04ea67d9254 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -38,7 +38,11 @@ from sklearn.utils._param_validation import Interval, StrOptions, validate_params from sklearn.utils.multiclass import type_of_target from sklearn.utils.sparsefuncs import count_nonzero -from sklearn.utils.validation import _check_pos_label_consistency, _check_sample_weight +from sklearn.utils.validation import ( + _check_pos_label_consistency, + _check_sample_weight, + _deprecate_positional_args, +) @validate_params( @@ -865,6 +869,7 @@ def _multiclass_roc_auc_score( ) +@_deprecate_positional_args(version="1.11") @validate_params( { "y_true": ["array-like"], @@ -874,7 +879,9 @@ def _multiclass_roc_auc_score( }, prefer_skip_nested_validation=True, ) -def confusion_matrix_at_thresholds(y_true, y_score, pos_label=None, sample_weight=None): +def confusion_matrix_at_thresholds( + y_true, y_score, *, pos_label=None, sample_weight=None +): """Calculate :term:`binary` confusion matrix terms per classification threshold. Read more in the :ref:`User Guide `. diff --git a/sklearn/metrics/tests/test_ranking.py b/sklearn/metrics/tests/test_ranking.py index fb607d319482f..dbb77f69f9c0e 100644 --- a/sklearn/metrics/tests/test_ranking.py +++ b/sklearn/metrics/tests/test_ranking.py @@ -2305,3 +2305,11 @@ def test_roc_curve_with_probablity_estimates(global_random_seed): y_score = rng.rand(10) _, _, thresholds = roc_curve(y_true, y_score) assert np.isinf(thresholds[0]) + + +# TODO(1.11): remove this test +def test_confusion_matrix_at_thresholds_positional_args_deprecation(): + y_true = np.array([0, 1, 1, 0]) + y_score = np.array([0.2, 0.1, 0.7, 0.7]) + with pytest.warns(FutureWarning, match="Pass pos_label=None as keyword arg"): + confusion_matrix_at_thresholds(y_true, y_score, None) From 212083d1a056f15fd766ef32f665222305d8289b Mon Sep 17 00:00:00 2001 From: Lucy Liu Date: Tue, 24 Feb 2026 23:17:40 +1100 Subject: [PATCH 242/462] DOC Fix deprecated kwargs in `PrecisionRecallDisplay` in example (#33396) --- examples/model_selection/plot_cost_sensitive_learning.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/model_selection/plot_cost_sensitive_learning.py b/examples/model_selection/plot_cost_sensitive_learning.py index 8b5209e85e8a0..affef34d92044 100644 --- a/examples/model_selection/plot_cost_sensitive_learning.py +++ b/examples/model_selection/plot_cost_sensitive_learning.py @@ -304,10 +304,9 @@ def plot_roc_pr_curves(vanilla_model, tuned_model, *, title): X_test, y_test, pos_label=pos_label, - linestyle=linestyle, - color=color, ax=axs[0], name=name, + curve_kwargs={"linestyle": linestyle, "color": color}, ) axs[0].plot( scoring["recall"](est, X_test, y_test), @@ -322,7 +321,7 @@ def plot_roc_pr_curves(vanilla_model, tuned_model, *, title): X_test, y_test, pos_label=pos_label, - curve_kwargs=dict(linestyle=linestyle, color=color), + curve_kwargs={"linestyle": linestyle, "color": color}, ax=axs[1], name=name, plot_chance_level=idx == 1, From 0b5ae1bffeadfb5595b52b8f749c491b33cf4e36 Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Tue, 24 Feb 2026 14:28:21 +0100 Subject: [PATCH 243/462] FIX make test more robust by increasing dataset size (#33377) --- sklearn/cluster/tests/test_spectral.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/cluster/tests/test_spectral.py b/sklearn/cluster/tests/test_spectral.py index 85c9c1c04d9ab..9888afed16f17 100644 --- a/sklearn/cluster/tests/test_spectral.py +++ b/sklearn/cluster/tests/test_spectral.py @@ -104,7 +104,7 @@ def test_spectral_clustering_sparse(assign_labels, coo_container, global_random_ def test_precomputed_nearest_neighbors_filtering(global_random_seed): # Test precomputed graph filtering when containing too many neighbors X, y = make_blobs( - n_samples=250, + n_samples=300, random_state=global_random_seed, centers=[[1, 1, 1], [-1, -1, -1]], cluster_std=0.01, From 57aa064e97fe18b18f57cdb994b6bab1f5e7332c Mon Sep 17 00:00:00 2001 From: Anne Beyer Date: Wed, 25 Feb 2026 15:42:12 +0100 Subject: [PATCH 244/462] FIX: Set `levels` explicitly to plot all classes in distinct colors in `DecisionBoundaryDisplay` (#33300) Co-authored-by: Olivier Grisel --- .../sklearn.inspection/33300.fix.rst | 5 +++ sklearn/inspection/_plot/decision_boundary.py | 9 +++++ .../tests/test_boundary_decision_display.py | 34 +++++++++++++++++-- 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.inspection/33300.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/33300.fix.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/33300.fix.rst new file mode 100644 index 0000000000000..2a96cd9af085e --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.inspection/33300.fix.rst @@ -0,0 +1,5 @@ +- :class:`inspection.DecisionBoundaryDisplay` now displays all class boundaries when + using ``plot_method="contour"`` with all response_methods, and displays all classes + in distinct colors when using ``plot_method="contourf"`` with + ``response_method="predict"``. + By :user:`Anne Beyer ` and :user:`Levente Csibi `. diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index 224f30bc96ca3..28b310461e6dc 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -287,6 +287,12 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar self.multiclass_colors_ = colors if self.response.ndim == 2: # predict + # Set `levels` to ensure all classes are displayed in different colors + if "levels" not in kwargs: + if plot_method == "contour": + kwargs["levels"] = np.arange(self.n_classes) + elif plot_method == "contourf": + kwargs["levels"] = np.arange(self.n_classes + 1) - 0.5 # `pcolormesh` requires cmap, for the others it makes no difference cmap = mpl.colors.ListedColormap(colors) self.surface_ = plot_func( @@ -295,6 +301,9 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar # predict_proba and decision_function differ for plotting methods elif plot_method == "contour": + # Set `levels` to ensure all classes are displayed in different colors + if "levels" not in kwargs: + kwargs["levels"] = np.arange(self.n_classes) # Plot only integer class values self.surface_ = plot_func( self.xx0, diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index 19c75407c2ddf..85605d5be88ab 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -685,9 +685,37 @@ def test_multiclass_colors_cmap( else: assert_allclose(disp.surface_.colors, colors) - # non-regression test for issue #32866 (currently still fails) - # if hasattr(disp.surface_, "levels"): - # assert len(disp.surface_.levels) >= disp.n_classes + +@pytest.mark.parametrize("y", [np.arange(6), [str(i) for i in np.arange(6)]]) +@pytest.mark.parametrize( + "response_method, plot_method", + [ + ("decision_function", "contour"), + ("predict_proba", "contour"), + ("predict", "contour"), + ("predict", "contourf"), + ], +) +def test_multiclass_levels(pyplot, y, response_method, plot_method): + # non-regression test for issue #32866 + + X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1], [2, 2], [3, 2]]) + + clf = LogisticRegression().fit(X, y) + + disp = DecisionBoundaryDisplay.from_estimator( + clf, + X, + response_method=response_method, + plot_method=plot_method, + ) + + if plot_method == "contour": + expected_levels = np.arange(6) + else: + expected_levels = np.arange(7) - 0.5 + + assert_allclose(disp.surface_.levels, expected_levels) # estimator classes for non-regression test cases for issue #33194 From 0731b161ada9ef8a610c70f20ce0a969fb949e0b Mon Sep 17 00:00:00 2001 From: Mohammad Ahmadullah Khan <115063771+MAUK9086@users.noreply.github.com> Date: Fri, 27 Feb 2026 09:59:46 +0530 Subject: [PATCH 245/462] FIX Correct validation in BisectingKMeans with custom init (#33148) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger --- .../sklearn.cluster/33148.fix.rst | 3 +++ sklearn/cluster/_bisect_k_means.py | 6 ++++-- sklearn/cluster/_kmeans.py | 13 ++++++++----- sklearn/cluster/tests/test_bisect_k_means.py | 15 +++++++++++++++ 4 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.cluster/33148.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.cluster/33148.fix.rst b/doc/whats_new/upcoming_changes/sklearn.cluster/33148.fix.rst new file mode 100644 index 0000000000000..82d5c21738d63 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.cluster/33148.fix.rst @@ -0,0 +1,3 @@ +- Fixed a bug in :class:`cluster.BisectingKMeans` when using a custom callable `init` + with `n_clusters > 2`. + By :user:`Mohammad Ahmadullah Khan `. diff --git a/sklearn/cluster/_bisect_k_means.py b/sklearn/cluster/_bisect_k_means.py index 3443d6d2511c4..9cbc2d31aa240 100644 --- a/sklearn/cluster/_bisect_k_means.py +++ b/sklearn/cluster/_bisect_k_means.py @@ -94,7 +94,7 @@ class BisectingKMeans(_BaseKMeans): centroids to generate. init : {'k-means++', 'random'} or callable, default='random' - Method for initialization: + Method for initialization for each bisection. 'k-means++' : selects initial cluster centers for k-mean clustering in a smart way to speed up convergence. See section @@ -104,7 +104,9 @@ class BisectingKMeans(_BaseKMeans): for the initial centroids. If a callable is passed, it should take arguments X, n_clusters and a - random state and return an initialization. + random state and return an initialization. Note that the bisecting algorithm + always performs a 2-way split, so the callable will always be called with + `n_clusters=2` and should return 2 centroids. n_init : int, default=1 Number of time the inner k-means algorithm will be run with different diff --git a/sklearn/cluster/_kmeans.py b/sklearn/cluster/_kmeans.py index aa7f86d3d3cb5..8a907c6e4f8bc 100644 --- a/sklearn/cluster/_kmeans.py +++ b/sklearn/cluster/_kmeans.py @@ -933,12 +933,15 @@ def _check_mkl_vcomp(self, X, n_samples): if has_vcomp and has_mkl: self._warn_mkl_vcomp(n_active_threads) - def _validate_center_shape(self, X, centers): - """Check if centers is compatible with X and n_clusters.""" - if centers.shape[0] != self.n_clusters: + def _validate_center_shape(self, X, centers, n_centroids=None): + """Check if the shape of the centers is correct.""" + if n_centroids is None: + n_centroids = self.n_clusters + + if centers.shape[0] != n_centroids: raise ValueError( f"The shape of the initial centers {centers.shape} does not " - f"match the number of clusters {self.n_clusters}." + f"match the number of clusters {n_centroids}." ) if centers.shape[1] != X.shape[1]: raise ValueError( @@ -1037,7 +1040,7 @@ def _init_centroids( elif callable(init): centers = init(X, n_clusters, random_state=random_state) centers = check_array(centers, dtype=X.dtype, copy=False, order="C") - self._validate_center_shape(X, centers) + self._validate_center_shape(X, centers, n_centroids=n_clusters) if sp.issparse(centers): centers = centers.toarray() diff --git a/sklearn/cluster/tests/test_bisect_k_means.py b/sklearn/cluster/tests/test_bisect_k_means.py index 799ddbc086ce0..98be77d5438c8 100644 --- a/sklearn/cluster/tests/test_bisect_k_means.py +++ b/sklearn/cluster/tests/test_bisect_k_means.py @@ -156,3 +156,18 @@ def test_one_feature(): # https://github.com/scikit-learn/scikit-learn/issues/27236 X = np.random.normal(size=(128, 1)) BisectingKMeans(bisecting_strategy="biggest_inertia", random_state=0).fit(X) + + +def test_bisecting_kmeans_custom_init_validation(): + """Test that BisectingKMeans validates center shape correctly with callable init. + + Regression test for issue #33146 + """ + rng = np.random.RandomState(42) + X = rng.rand(100, 2) + + def my_init(X, n_clusters, random_state): + return X[:n_clusters] + + bisect = BisectingKMeans(n_clusters=3, init=my_init, n_init=1, random_state=rng) + bisect.fit(X) From 7b40732c1927e607cf4b9f51af2b25792acc6f91 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 2 Mar 2026 05:19:56 -0500 Subject: [PATCH 246/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33431) Co-authored-by: Lock file bot --- build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock index 12996217704ed..3069757ddc1ef 100644 --- a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -4,7 +4,7 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 @@ -31,7 +31,7 @@ https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 -# pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c +# pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa # pip charset-normalizer @ https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 # pip coverage @ https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de From 579ba3f69eda6ac54913f31123a77db13ff8d90c Mon Sep 17 00:00:00 2001 From: scikit-learn-bot Date: Mon, 2 Mar 2026 05:20:21 -0500 Subject: [PATCH 247/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33433) Co-authored-by: Lock file bot --- build_tools/azure/pylatest_free_threaded_linux-64_conda.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock index 0bbffd42aef26..9b78e026012c6 100644 --- a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock @@ -4,7 +4,7 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#3251796e09870c978e0f69fa05e38fb6 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 @@ -55,5 +55,5 @@ https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1 https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.3-h92d6c8b_1.conda#817a41a5e7c547bda68fd981fb72b1ec https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py314h529d2a9_1.conda#2548681b651d007d01368d98b3f8536e +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314h529d2a9_0.conda#c09dd94be0e88aca25c60fb53d5c8e45 https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.2-pyhd8ed1ab_0.conda#288250b7e539cddf52f39616deae278d From c492f2f35ff83e87022d9f8fe9b9b84ab1ac6d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= Date: Mon, 2 Mar 2026 14:43:28 +0100 Subject: [PATCH 248/462] CI Clean-up after Azure -> GHA move (#33403) --- .gitattributes | 1 - .github/workflows/unit-tests.yml | 88 +++++++++----- README.rst | 7 +- build_tools/azure/get_commit_message.py | 72 ------------ build_tools/azure/get_selected_tests.py | 42 ------- build_tools/azure/install_setup_conda.sh | 36 ------ build_tools/azure/posix.yml | 109 ------------------ build_tools/azure/upload_codecov.sh | 59 ---------- .../combine_coverage_reports.sh | 0 .../{azure => github}/debian_32bit_lock.txt | 0 .../debian_32bit_requirements.txt | 0 build_tools/{azure => github}/install.sh | 0 ...latest_conda_forge_mkl_linux-64_conda.lock | 0 ...t_conda_forge_mkl_linux-64_environment.yml | 0 ..._conda_forge_mkl_no_openmp_environment.yml | 0 ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 0 .../pylatest_conda_forge_osx-arm64_conda.lock | 0 ...test_conda_forge_osx-arm64_environment.yml | 0 .../pylatest_free_threaded_environment.yml | 0 ...pylatest_free_threaded_linux-64_conda.lock | 0 ...latest_pip_openblas_pandas_environment.yml | 0 ...st_pip_openblas_pandas_linux-64_conda.lock | 0 .../pylatest_pip_scipy_dev_environment.yml | 0 ...pylatest_pip_scipy_dev_linux-64_conda.lock | 0 ...pymin_conda_forge_openblas_environment.yml | 0 ..._openblas_min_dependencies_environment.yml | 0 ...nblas_min_dependencies_linux-64_conda.lock | 0 ...forge_openblas_ubuntu_2204_environment.yml | 0 ...e_openblas_ubuntu_2204_linux-64_conda.lock | 0 ...min_conda_forge_openblas_win-64_conda.lock | 0 build_tools/{azure => github}/test_docs.sh | 2 +- .../test_pytest_soft_dependency.sh | 0 build_tools/{azure => github}/test_script.sh | 25 ---- .../{azure => github}/ubuntu_atlas_lock.txt | 0 .../ubuntu_atlas_requirements.txt | 0 .../update_environments_and_lock_files.py | 22 ++-- doc/about.rst | 6 +- doc/developers/contributing.rst | 8 +- pyproject.toml | 2 +- sklearn/utils/tests/test_estimator_checks.py | 2 +- 40 files changed, 84 insertions(+), 397 deletions(-) delete mode 100644 build_tools/azure/get_commit_message.py delete mode 100644 build_tools/azure/get_selected_tests.py delete mode 100755 build_tools/azure/install_setup_conda.sh delete mode 100644 build_tools/azure/posix.yml delete mode 100755 build_tools/azure/upload_codecov.sh rename build_tools/{azure => github}/combine_coverage_reports.sh (100%) rename build_tools/{azure => github}/debian_32bit_lock.txt (100%) rename build_tools/{azure => github}/debian_32bit_requirements.txt (100%) rename build_tools/{azure => github}/install.sh (100%) rename build_tools/{azure => github}/pylatest_conda_forge_mkl_linux-64_conda.lock (100%) rename build_tools/{azure => github}/pylatest_conda_forge_mkl_linux-64_environment.yml (100%) rename build_tools/{azure => github}/pylatest_conda_forge_mkl_no_openmp_environment.yml (100%) rename build_tools/{azure => github}/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock (100%) rename build_tools/{azure => github}/pylatest_conda_forge_osx-arm64_conda.lock (100%) rename build_tools/{azure => github}/pylatest_conda_forge_osx-arm64_environment.yml (100%) rename build_tools/{azure => github}/pylatest_free_threaded_environment.yml (100%) rename build_tools/{azure => github}/pylatest_free_threaded_linux-64_conda.lock (100%) rename build_tools/{azure => github}/pylatest_pip_openblas_pandas_environment.yml (100%) rename build_tools/{azure => github}/pylatest_pip_openblas_pandas_linux-64_conda.lock (100%) rename build_tools/{azure => github}/pylatest_pip_scipy_dev_environment.yml (100%) rename build_tools/{azure => github}/pylatest_pip_scipy_dev_linux-64_conda.lock (100%) rename build_tools/{azure => github}/pymin_conda_forge_openblas_environment.yml (100%) rename build_tools/{azure => github}/pymin_conda_forge_openblas_min_dependencies_environment.yml (100%) rename build_tools/{azure => github}/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock (100%) rename build_tools/{azure => github}/pymin_conda_forge_openblas_ubuntu_2204_environment.yml (100%) rename build_tools/{azure => github}/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock (100%) rename build_tools/{azure => github}/pymin_conda_forge_openblas_win-64_conda.lock (100%) rename build_tools/{azure => github}/test_docs.sh (90%) rename build_tools/{azure => github}/test_pytest_soft_dependency.sh (100%) rename build_tools/{azure => github}/test_script.sh (61%) rename build_tools/{azure => github}/ubuntu_atlas_lock.txt (100%) rename build_tools/{azure => github}/ubuntu_atlas_requirements.txt (100%) diff --git a/.gitattributes b/.gitattributes index f45e0f29ccfa2..952138b08adba 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,5 @@ .* export-ignore asv_benchmarks export-ignore -azure-pipelines.yml export-ignore benchmarks export-ignore build_tools export-ignore maint_tools export-ignore diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index c49dbfc92aad4..e4f57f04457da 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -72,7 +72,7 @@ jobs: } >> "${GITHUB_OUTPUT}" retrieve-selected-tests: - # Parse the commit message to check if `build_tools/azure/test_script.sh` should run + # Parse the commit message to check if `build_tools/github/test_script.sh` should run # only specific tests. # # If so, selected tests will be run with SKLEARN_TESTS_GLOBAL_RANDOM_SEED="all". @@ -130,7 +130,7 @@ jobs: - name: Linux x86-64 pylatest_conda_forge_mkl os: ubuntu-22.04 DISTRIB: conda - LOCK_FILE: build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock + LOCK_FILE: build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock COVERAGE: true SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 42 # default global random seed SCIPY_ARRAY_API: 1 @@ -142,7 +142,7 @@ jobs: - name: Linux x86-64 pymin_conda_forge_openblas_ubuntu_2204 os: ubuntu-22.04 DISTRIB: conda - LOCK_FILE: build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock + LOCK_FILE: build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock SKLEARN_WARNINGS_AS_ERRORS: 1 COVERAGE: false SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 0 # non-default seed @@ -151,7 +151,7 @@ jobs: - name: Linux x86-64 pymin_conda_forge_openblas_min_dependencies os: ubuntu-22.04 DISTRIB: conda - LOCK_FILE: build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock + LOCK_FILE: build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock # Enable debug Cython directives to capture IndexError exceptions in # combination with the -Werror::pytest.PytestUnraisableExceptionWarning # flag for pytest. @@ -165,7 +165,7 @@ jobs: - name: Linux pylatest_pip_openblas_pandas os: ubuntu-24.04 DISTRIB: conda - LOCK_FILE: build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock + LOCK_FILE: build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 3 # non-default seed SCIPY_ARRAY_API: 1 CHECK_PYTEST_SOFT_DEPENDENCY: true @@ -182,14 +182,14 @@ jobs: - name: Linux x86-64 ubuntu_atlas os: ubuntu-24.04 DISTRIB: ubuntu - LOCK_FILE: build_tools/azure/ubuntu_atlas_lock.txt + LOCK_FILE: build_tools/github/ubuntu_atlas_lock.txt COVERAGE: false SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 1 # non-default seed - name: macOS pylatest_conda_forge_arm os: macos-15 DISTRIB: conda - LOCK_FILE: build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock + LOCK_FILE: build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 5 # non-default seed SCIPY_ARRAY_API: 1 PYTORCH_ENABLE_MPS_FALLBACK: 1 @@ -198,7 +198,7 @@ jobs: - name: macOS x86-64 pylatest_conda_forge_mkl_no_openmp os: macos-15-intel DISTRIB: conda - LOCK_FILE: build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock + LOCK_FILE: build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock SKLEARN_TEST_NO_OPENMP: true SKLEARN_SKIP_OPENMP_TEST: true SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 6 # non-default seed @@ -206,7 +206,7 @@ jobs: - name: Windows x64 pymin_conda_forge_openblas os: windows-latest DISTRIB: conda - LOCK_FILE: build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock + LOCK_FILE: build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock SKLEARN_WARNINGS_AS_ERRORS: 1 # The Windows runner is typically much slower than other CI runners # due to the lack of compiler cache. Running the tests with coverage @@ -252,30 +252,47 @@ jobs: activate-environment: "" - name: Build scikit-learn - run: bash -l build_tools/azure/install.sh + run: bash -l build_tools/github/install.sh - - name: Set random seed for nightly/manual runs + # Enable global random seed randomization to discover seed-sensitive tests + # only on nightly builds. + # https://scikit-learn.org/stable/computing/parallelism.html#sklearn-tests-global-random-seed + - name: Set random global random seed for nightly/manual runs if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' - run: echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 20))" >> $GITHUB_ENV shell: bash + run: | + SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 20)) + echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$SKLEARN_TESTS_GLOBAL_RANDOM_SEED" >> $GITHUB_ENV + echo "To reproduce this test run, set the following environment variable:" + echo " SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$SKLEARN_TESTS_GLOBAL_RANDOM_SEED" + echo "See: https://scikit-learn.org/dev/computing/parallelism.html#sklearn-tests-global-random-seed" + + # Enable global dtype fixture for all nightly builds to discover + # numerical-sensitive tests. + # https://scikit-learn.org/stable/computing/parallelism.html#sklearn-run-float32-tests + - name: Run float32 tests for nightly/manual runs + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + shell: bash + run: | + echo SKLEARN_RUN_FLOAT32_TESTS=1 >> $GITHUB_ENV - name: Run tests env: COMMIT_MESSAGE: ${{ needs.retrieve-commit-message.outputs.message }} SELECTED_TESTS: ${{ needs.retrieve-selected-tests.outputs.tests }} COVERAGE: ${{ env.COVERAGE == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}} - run: bash -l build_tools/azure/test_script.sh + run: bash -l build_tools/github/test_script.sh - name: Run doctests in .py and .rst files - run: bash -l build_tools/azure/test_docs.sh + run: bash -l build_tools/github/test_docs.sh if: ${{ needs.retrieve-selected-tests.outputs.tests == ''}} - name: Run pytest soft dependency test - run: bash -l build_tools/azure/test_pytest_soft_dependency.sh + run: bash -l build_tools/github/test_pytest_soft_dependency.sh if: ${{ env.CHECK_PYTEST_SOFT_DEPENDENCY == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}} - name: Combine coverage reports from parallel test runners - run: bash -l build_tools/azure/combine_coverage_reports.sh + run: bash -l build_tools/github/combine_coverage_reports.sh if: ${{ env.COVERAGE == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}} - name: Upload coverage report to Codecov @@ -310,7 +327,7 @@ jobs: if: contains(needs.retrieve-commit-message.outputs.message, '[free-threaded]') || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' env: DISTRIB: conda-free-threaded - LOCK_FILE: build_tools/azure/pylatest_free_threaded_linux-64_conda.lock + LOCK_FILE: build_tools/github/pylatest_free_threaded_linux-64_conda.lock COVERAGE: false # Disable pytest-xdist to use multiple cores for stress-testing with pytest-run-parallel PYTEST_XDIST_VERSION: none @@ -326,7 +343,7 @@ jobs: if: contains(needs.retrieve-commit-message.outputs.message, '[scipy-dev]') || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' env: DISTRIB: conda-pip-scipy-dev - LOCK_FILE: build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock + LOCK_FILE: build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock SKLEARN_WARNINGS_AS_ERRORS: 1 CHECK_PYTEST_SOFT_DEPENDENCY: true # To be able to access the job name in the steps, it must be set as an env variable. @@ -340,7 +357,7 @@ jobs: needs: [lint, retrieve-commit-message, retrieve-selected-tests] env: DISTRIB: debian-32 - LOCK_FILE: build_tools/azure/debian_32bit_lock.txt + LOCK_FILE: build_tools/github/debian_32bit_lock.txt SKLEARN_TESTS_GLOBAL_RANDOM_SEED: 4 # non-default seed DOCKER_CONTAINER: i386/debian:trixie # To be able to access the job name in the steps, it must be set as an env variable. @@ -364,9 +381,27 @@ jobs: auto-activate-base: true activate-environment: "" - - name: Set random seed for nightly/manual runs + # Enable global random seed randomization to discover seed-sensitive tests + # only on nightly builds. + # https://scikit-learn.org/stable/computing/parallelism.html#sklearn-tests-global-random-seed + - name: Set random global random seed for nightly/manual runs if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' - run: echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 20))" >> $GITHUB_ENV + shell: bash + run: | + SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$((RANDOM % 20)) + echo "SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$SKLEARN_TESTS_GLOBAL_RANDOM_SEED" >> $GITHUB_ENV + echo "To reproduce this test run, set the following environment variable:" + echo " SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$SKLEARN_TESTS_GLOBAL_RANDOM_SEED" + echo "See: https://scikit-learn.org/dev/computing/parallelism.html#sklearn-tests-global-random-seed" + + # Enable global dtype fixture for all nightly builds to discover + # numerical-sensitive tests. + # https://scikit-learn.org/stable/computing/parallelism.html#sklearn-run-float32-tests + - name: Run float32 tests for nightly/manual runs + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + shell: bash + run: | + echo SKLEARN_RUN_FLOAT32_TESTS=1 >> $GITHUB_ENV - name: Start container # Environment variable are passed when starting the container rather @@ -397,25 +432,26 @@ jobs: -e COMMIT_MESSAGE -e JOB_NAME -e SKLEARN_TESTS_GLOBAL_RANDOM_SEED + -e SKLEARN_RUN_FLOAT32_TESTS $DOCKER_CONTAINER sleep 1000000 - name: Build scikit-learn - run: docker exec skcontainer bash -l build_tools/azure/install.sh + run: docker exec skcontainer bash -l build_tools/github/install.sh - name: Run tests - run: docker exec skcontainer bash -l build_tools/azure/test_script.sh + run: docker exec skcontainer bash -l build_tools/github/test_script.sh - name: Run doctests in .py and .rst files - run: docker exec skcontainer bash -l build_tools/azure/test_docs.sh + run: docker exec skcontainer bash -l build_tools/github/test_docs.sh if: ${{ needs.retrieve-selected-tests.outputs.tests == ''}} - name: Run pytest soft dependency test - run: docker exec skcontainer build_tools/azure/test_pytest_soft_dependency.sh + run: docker exec skcontainer build_tools/github/test_pytest_soft_dependency.sh if: ${{ env.CHECK_PYTEST_SOFT_DEPENDENCY == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}} - name: Combine coverage reports from parallel test runners - run: docker exec skcontainer bash -l build_tools/azure/combine_coverage_reports.sh + run: docker exec skcontainer bash -l build_tools/github/combine_coverage_reports.sh if: ${{ env.COVERAGE == 'true' && needs.retrieve-selected-tests.outputs.tests == ''}} - name: Upload coverage report to Codecov diff --git a/README.rst b/README.rst index cd93589a64448..dda307f8248a6 100644 --- a/README.rst +++ b/README.rst @@ -1,9 +1,10 @@ .. -*- mode: rst -*- -|Azure| |Codecov| |CircleCI| |Nightly wheels| |Ruff| |PythonVersion| |PyPI| |DOI| |Benchmark| +|GitHubActions| |Codecov| |CircleCI| |Nightly wheels| |Ruff| |PythonVersion| |PyPI| |DOI| |Benchmark| -.. |Azure| image:: https://dev.azure.com/scikit-learn/scikit-learn/_apis/build/status/scikit-learn.scikit-learn?branchName=main - :target: https://dev.azure.com/scikit-learn/scikit-learn/_build/latest?definitionId=1&branchName=main + +.. |GitHubActions| image:: https://github.com/scikit-learn/scikit-learn/actions/workflows/unit-tests.yml/badge.svg + :target: https://github.com/scikit-learn/scikit-learn/actions/workflows/unit-tests.yml?query=branch%3Amain .. |CircleCI| image:: https://circleci.com/gh/scikit-learn/scikit-learn/tree/main.svg?style=shield :target: https://circleci.com/gh/scikit-learn/scikit-learn diff --git a/build_tools/azure/get_commit_message.py b/build_tools/azure/get_commit_message.py deleted file mode 100644 index f110697c2b24f..0000000000000 --- a/build_tools/azure/get_commit_message.py +++ /dev/null @@ -1,72 +0,0 @@ -import argparse -import os -import subprocess - - -def get_commit_message(): - """Retrieve the commit message.""" - - if "COMMIT_MESSAGE" in os.environ or "BUILD_SOURCEVERSIONMESSAGE" not in os.environ: - raise RuntimeError( - "This legacy script should only be used on Azure. " - "On GitHub actions, use the 'COMMIT_MESSAGE' environment variable" - ) - - build_source_version_message = os.environ["BUILD_SOURCEVERSIONMESSAGE"] - - if os.environ["BUILD_REASON"] == "PullRequest": - # By default pull requests use refs/pull/PULL_ID/merge as the source branch - # which has a "Merge ID into ID" as a commit message. The latest commit - # message is the second to last commit - commit_id = build_source_version_message.split()[1] - git_cmd = ["git", "log", commit_id, "-1", "--pretty=%B"] - commit_message = subprocess.run( - git_cmd, capture_output=True, text=True - ).stdout.strip() - else: - commit_message = build_source_version_message - - # Sanitize the commit message to avoid introducing a vulnerability: a PR - # submitter could include the "##vso" special marker in their commit - # message to attempt to obfuscate the injection of arbitrary commands in - # the Azure pipeline. - # - # This can be a problem if the PR reviewers do not pay close enough - # attention to the full commit message prior to clicking the merge button - # and as a result make the inject code run in a protected branch with - # elevated access to CI secrets. On a protected branch, Azure - # already sanitizes `BUILD_SOURCEVERSIONMESSAGE`, but the message - # will still be sanitized here out of precaution. - commit_message = commit_message.replace("##vso", "..vso") - - return commit_message - - -def parsed_args(): - parser = argparse.ArgumentParser( - description=( - "Show commit message that triggered the build in Azure DevOps pipeline" - ) - ) - parser.add_argument( - "--only-show-message", - action="store_true", - default=False, - help=( - "Only print commit message. Useful for direct use in scripts rather than" - " setting output variable of the Azure job" - ), - ) - return parser.parse_args() - - -if __name__ == "__main__": - args = parsed_args() - commit_message = get_commit_message() - - if args.only_show_message: - print(commit_message) - else: - # set the environment variable to be propagated to other steps - print(f"##vso[task.setvariable variable=message;isOutput=true]{commit_message}") - print(f"commit message: {commit_message}") # helps debugging diff --git a/build_tools/azure/get_selected_tests.py b/build_tools/azure/get_selected_tests.py deleted file mode 100644 index 177d42604a5b2..0000000000000 --- a/build_tools/azure/get_selected_tests.py +++ /dev/null @@ -1,42 +0,0 @@ -import os - -from get_commit_message import get_commit_message - - -def get_selected_tests(): - """Parse the commit message to check if pytest should run only specific tests. - - If so, selected tests will be run with SKLEARN_TESTS_GLOBAL_RANDOM_SEED="all". - - The commit message must take the form: - [all random seeds] - <test_name_1> - <test_name_2> - ... - """ - if "SELECTED_TESTS" in os.environ: - raise RuntimeError( - "This legacy script should only be used on Azure. " - "On GitHub actions, use the 'SELECTED_TESTS' environment variable" - ) - - commit_message = get_commit_message() - - if "[all random seeds]" in commit_message: - selected_tests = commit_message.split("[all random seeds]")[1].strip() - selected_tests = selected_tests.replace("\n", " or ") - else: - selected_tests = "" - - return selected_tests - - -if __name__ == "__main__": - # set the environment variable to be propagated to other steps - selected_tests = get_selected_tests() - - if selected_tests: - print(f"##vso[task.setvariable variable=SELECTED_TESTS]'{selected_tests}'") - print(f"selected tests: {selected_tests}") # helps debugging - else: - print("no selected tests") diff --git a/build_tools/azure/install_setup_conda.sh b/build_tools/azure/install_setup_conda.sh deleted file mode 100755 index e57d7dbe155be..0000000000000 --- a/build_tools/azure/install_setup_conda.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -set -e -set -x - -PLATFORM=$(uname) -if [[ "$PLATFORM" =~ MINGW|MSYS ]]; then - PLATFORM=Windows -fi -if [[ "$PLATFORM" == "Windows" ]]; then - EXTENSION="exe" -else - EXTENSION="sh" -fi -INSTALLER="miniforge.$EXTENSION" -MINIFORGE_URL="https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$PLATFORM-$(uname -m).$EXTENSION" -curl -L ${MINIFORGE_URL} -o "$INSTALLER" - -MINIFORGE_DIR="$HOME/miniforge3" -if [[ "$PLATFORM" == "Windows" ]]; then - WIN_MINIFORGE_DIR=$(cygpath -w "$MINIFORGE_DIR") - cmd "/C $INSTALLER /InstallationType=JustMe /RegisterPython=0 /S /D=$WIN_MINIFORGE_DIR" -else - bash "$INSTALLER" -b -u -p $MINIFORGE_DIR -fi - -# Add conda to the PATH so that it can be used in further Azure CI steps. -# Need set +x for ##vso Azure magic otherwise it may add a quote in the PATH. -# For more details, see https://github.com/microsoft/azure-pipelines-tasks/issues/10331 -set +x -if [[ "$PLATFORM" == "Windows" ]]; then - echo "##vso[task.prependpath]$MINIFORGE_DIR/Scripts" -else - echo "##vso[task.prependpath]$MINIFORGE_DIR/bin" -fi -set -x diff --git a/build_tools/azure/posix.yml b/build_tools/azure/posix.yml deleted file mode 100644 index e0f504ba540db..0000000000000 --- a/build_tools/azure/posix.yml +++ /dev/null @@ -1,109 +0,0 @@ -parameters: - name: '' - vmImage: '' - matrix: [] - dependsOn: [] - condition: '' - -jobs: -- job: ${{ parameters.name }} - dependsOn: ${{ parameters.dependsOn }} - condition: ${{ parameters.condition }} - timeoutInMinutes: 120 - pool: - vmImage: ${{ parameters.vmImage }} - variables: - TEST_DIR: '$(Agent.WorkFolder)/tmp_folder' - VIRTUALENV: 'testvenv' - JUNITXML: 'test-data.xml' - SKLEARN_SKIP_NETWORK_TESTS: '1' - CCACHE_DIR: $(Pipeline.Workspace)/ccache - CCACHE_COMPRESS: '1' - PYTEST_XDIST_VERSION: 'latest' - COVERAGE: 'true' - CREATE_ISSUE_ON_TRACKER: 'true' - strategy: - matrix: - ${{ insert }}: ${{ parameters.matrix }} - - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.9' - addToPath: false - name: pyTools - displayName: Select python version to run CI python scripts - - bash: $(pyTools.pythonLocation)/bin/python build_tools/azure/get_selected_tests.py - displayName: Check selected tests for all random seeds - condition: eq(variables['Build.Reason'], 'PullRequest') - - bash: build_tools/azure/install_setup_conda.sh - displayName: Install conda if necessary and set it up - condition: startsWith(variables['DISTRIB'], 'conda') - - task: Cache@2 - inputs: - key: '"ccache-v1" | "$(Agent.JobName)" | "$(Build.BuildNumber)"' - restoreKeys: | - "ccache-v1" | "$(Agent.JobName)" - path: $(CCACHE_DIR) - displayName: ccache - continueOnError: true - - script: | - build_tools/azure/install.sh - displayName: 'Install' - - script: | - build_tools/azure/test_script.sh - displayName: 'Test Library' - - script: | - build_tools/azure/test_docs.sh - displayName: 'Test Docs' - condition: and(succeeded(), eq(variables['SELECTED_TESTS'], '')) - - script: | - build_tools/azure/test_pytest_soft_dependency.sh - displayName: 'Test Soft Dependency' - condition: and(succeeded(), - eq(variables['CHECK_PYTEST_SOFT_DEPENDENCY'], 'true'), - eq(variables['SELECTED_TESTS'], '')) - - script: | - build_tools/azure/combine_coverage_reports.sh - condition: and(succeeded(), eq(variables['COVERAGE'], 'true'), - eq(variables['SELECTED_TESTS'], '')) - displayName: 'Combine coverage' - - task: PublishTestResults@2 - inputs: - testResultsFiles: '$(TEST_DIR)/$(JUNITXML)' - testRunTitle: ${{ format('{0}-$(Agent.JobName)', parameters.name) }} - displayName: 'Publish Test Results' - condition: succeededOrFailed() - - bash: | - set -ex - if [[ $(BOT_GITHUB_TOKEN) == "" ]]; then - echo "GitHub Token is not set. Issue tracker will not be updated." - exit - fi - - LINK_TO_RUN="https://dev.azure.com/$BUILD_REPOSITORY_NAME/_build/results?buildId=$BUILD_BUILDID&view=logs&j=$SYSTEM_JOBID" - CI_NAME="$SYSTEM_JOBIDENTIFIER" - ISSUE_REPO="$BUILD_REPOSITORY_NAME" - - $(pyTools.pythonLocation)/bin/pip install defusedxml PyGithub - $(pyTools.pythonLocation)/bin/python maint_tools/update_tracking_issue.py \ - $(BOT_GITHUB_TOKEN) \ - $CI_NAME \ - $ISSUE_REPO \ - $LINK_TO_RUN \ - --junit-file $JUNIT_FILE \ - --auto-close false - displayName: 'Update issue tracker' - env: - JUNIT_FILE: $(TEST_DIR)/$(JUNITXML) - condition: and(succeededOrFailed(), eq(variables['CREATE_ISSUE_ON_TRACKER'], 'true'), - eq(variables['Build.Reason'], 'Schedule')) - - script: | - build_tools/azure/upload_codecov.sh - condition: and(succeeded(), eq(variables['COVERAGE'], 'true'), - eq(variables['SELECTED_TESTS'], '')) - displayName: 'Upload To Codecov' - retryCountOnTaskFailure: 5 - env: - CODECOV_TOKEN: $(CODECOV_TOKEN) - JUNIT_FILE: $(TEST_DIR)/$(JUNITXML) diff --git a/build_tools/azure/upload_codecov.sh b/build_tools/azure/upload_codecov.sh deleted file mode 100755 index 4c3db8fe8bbd6..0000000000000 --- a/build_tools/azure/upload_codecov.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash - -set -e - -# Do not upload to codecov on forks -if [[ "$BUILD_REPOSITORY_NAME" != "scikit-learn/scikit-learn" ]]; then - exit 0 -fi - -# When we update the codecov uploader version, we need to update the checksums. -# The checksum for each codecov binary is available at -# https://cli.codecov.io e.g. for linux -# https://cli.codecov.io/v10.2.1/linux/codecov.SHA256SUM. - -# Instead of hardcoding a specific version and signature in this script, it -# would be possible to use the "latest" symlink URL but then we need to -# download both the codecov.SHA256SUM files each time and check the signatures -# with the codecov gpg key as well, see: -# https://docs.codecov.com/docs/codecov-uploader#integrity-checking-the-uploader -# However this approach would yield a larger number of downloads from -# codecov.io and keybase.io, therefore increasing the risk of running into -# network failures. -CODECOV_CLI_VERSION=10.2.1 -CODECOV_BASE_URL="https://cli.codecov.io/v$CODECOV_CLI_VERSION" - -# Check that the git repo is located at the expected location: -if [[ ! -d "$BUILD_REPOSITORY_LOCALPATH/.git" ]]; then - echo "Could not find the git checkout at $BUILD_REPOSITORY_LOCALPATH" - exit 1 -fi - -# Check that the combined coverage file exists at the expected location: -export COVERAGE_XML="$BUILD_REPOSITORY_LOCALPATH/coverage.xml" -if [[ ! -f "$COVERAGE_XML" ]]; then - echo "Could not find the combined coverage file at $COVERAGE_XML" - exit 1 -fi - -if [[ $OSTYPE == *"linux"* ]]; then - curl -Os "$CODECOV_BASE_URL/linux/codecov" - SHA256SUM="39dd112393680356daf701c07f375303aef5de62f06fc80b466b5c3571336014 codecov" - echo "$SHA256SUM" | shasum -a256 -c - chmod +x codecov - ./codecov upload-coverage -t ${CODECOV_TOKEN} -f coverage.xml -Z - ./codecov do-upload --disable-search --report-type test_results --file $JUNIT_FILE -elif [[ $OSTYPE == *"darwin"* ]]; then - curl -Os "$CODECOV_BASE_URL/macos/codecov" - SHA256SUM="01183f6367c7baff4947cce389eaa511b7a6d938e37ae579b08a86b51f769fd9 codecov" - echo "$SHA256SUM" | shasum -a256 -c - chmod +x codecov - ./codecov upload-coverage -t ${CODECOV_TOKEN} -f coverage.xml -Z - ./codecov do-upload --disable-search --report-type test_results --file $JUNIT_FILE -else - curl -Os "$CODECOV_BASE_URL/windows/codecov.exe" - SHA256SUM="e54e9520428701a510ef451001db56b56fb17f9b0484a266f184b73dd27b77e7 codecov.exe" - echo "$SHA256SUM" | sha256sum -c - ./codecov.exe upload-coverage -t ${CODECOV_TOKEN} -f coverage.xml -Z - ./codecov.exe do-upload --disable-search --report-type test_results --file $JUNIT_FILE -fi diff --git a/build_tools/azure/combine_coverage_reports.sh b/build_tools/github/combine_coverage_reports.sh similarity index 100% rename from build_tools/azure/combine_coverage_reports.sh rename to build_tools/github/combine_coverage_reports.sh diff --git a/build_tools/azure/debian_32bit_lock.txt b/build_tools/github/debian_32bit_lock.txt similarity index 100% rename from build_tools/azure/debian_32bit_lock.txt rename to build_tools/github/debian_32bit_lock.txt diff --git a/build_tools/azure/debian_32bit_requirements.txt b/build_tools/github/debian_32bit_requirements.txt similarity index 100% rename from build_tools/azure/debian_32bit_requirements.txt rename to build_tools/github/debian_32bit_requirements.txt diff --git a/build_tools/azure/install.sh b/build_tools/github/install.sh similarity index 100% rename from build_tools/azure/install.sh rename to build_tools/github/install.sh diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock similarity index 100% rename from build_tools/azure/pylatest_conda_forge_mkl_linux-64_conda.lock rename to build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock diff --git a/build_tools/azure/pylatest_conda_forge_mkl_linux-64_environment.yml b/build_tools/github/pylatest_conda_forge_mkl_linux-64_environment.yml similarity index 100% rename from build_tools/azure/pylatest_conda_forge_mkl_linux-64_environment.yml rename to build_tools/github/pylatest_conda_forge_mkl_linux-64_environment.yml diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_environment.yml b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_environment.yml similarity index 100% rename from build_tools/azure/pylatest_conda_forge_mkl_no_openmp_environment.yml rename to build_tools/github/pylatest_conda_forge_mkl_no_openmp_environment.yml diff --git a/build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock similarity index 100% rename from build_tools/azure/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock rename to build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock similarity index 100% rename from build_tools/azure/pylatest_conda_forge_osx-arm64_conda.lock rename to build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock diff --git a/build_tools/azure/pylatest_conda_forge_osx-arm64_environment.yml b/build_tools/github/pylatest_conda_forge_osx-arm64_environment.yml similarity index 100% rename from build_tools/azure/pylatest_conda_forge_osx-arm64_environment.yml rename to build_tools/github/pylatest_conda_forge_osx-arm64_environment.yml diff --git a/build_tools/azure/pylatest_free_threaded_environment.yml b/build_tools/github/pylatest_free_threaded_environment.yml similarity index 100% rename from build_tools/azure/pylatest_free_threaded_environment.yml rename to build_tools/github/pylatest_free_threaded_environment.yml diff --git a/build_tools/azure/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock similarity index 100% rename from build_tools/azure/pylatest_free_threaded_linux-64_conda.lock rename to build_tools/github/pylatest_free_threaded_linux-64_conda.lock diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_environment.yml b/build_tools/github/pylatest_pip_openblas_pandas_environment.yml similarity index 100% rename from build_tools/azure/pylatest_pip_openblas_pandas_environment.yml rename to build_tools/github/pylatest_pip_openblas_pandas_environment.yml diff --git a/build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock similarity index 100% rename from build_tools/azure/pylatest_pip_openblas_pandas_linux-64_conda.lock rename to build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock diff --git a/build_tools/azure/pylatest_pip_scipy_dev_environment.yml b/build_tools/github/pylatest_pip_scipy_dev_environment.yml similarity index 100% rename from build_tools/azure/pylatest_pip_scipy_dev_environment.yml rename to build_tools/github/pylatest_pip_scipy_dev_environment.yml diff --git a/build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock similarity index 100% rename from build_tools/azure/pylatest_pip_scipy_dev_linux-64_conda.lock rename to build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock diff --git a/build_tools/azure/pymin_conda_forge_openblas_environment.yml b/build_tools/github/pymin_conda_forge_openblas_environment.yml similarity index 100% rename from build_tools/azure/pymin_conda_forge_openblas_environment.yml rename to build_tools/github/pymin_conda_forge_openblas_environment.yml diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_environment.yml b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_environment.yml similarity index 100% rename from build_tools/azure/pymin_conda_forge_openblas_min_dependencies_environment.yml rename to build_tools/github/pymin_conda_forge_openblas_min_dependencies_environment.yml diff --git a/build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock similarity index 100% rename from build_tools/azure/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock rename to build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_environment.yml b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_environment.yml similarity index 100% rename from build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_environment.yml rename to build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_environment.yml diff --git a/build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock similarity index 100% rename from build_tools/azure/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock rename to build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock diff --git a/build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock similarity index 100% rename from build_tools/azure/pymin_conda_forge_openblas_win-64_conda.lock rename to build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock diff --git a/build_tools/azure/test_docs.sh b/build_tools/github/test_docs.sh similarity index 90% rename from build_tools/azure/test_docs.sh rename to build_tools/github/test_docs.sh index f41072bf23a8b..800acdcc8f1d4 100755 --- a/build_tools/azure/test_docs.sh +++ b/build_tools/github/test_docs.sh @@ -8,7 +8,7 @@ activate_environment scipy_doctest_installed=$(python -c 'import scipy_doctest' && echo "True" || echo "False") if [[ "$scipy_doctest_installed" == "True" ]]; then doc_rst_files=$(find $PWD/doc -name '*.rst' | sort) - # Changing dir, as we do in build_tools/azure/test_script.sh, avoids an + # Changing dir, as we do in build_tools/github/test_script.sh, avoids an # error when importing sklearn. Not sure why this happens ... I am going to # wild guess that it has something to do with the bespoke way we set up # conda with putting conda in the PATH and source activate, rather than diff --git a/build_tools/azure/test_pytest_soft_dependency.sh b/build_tools/github/test_pytest_soft_dependency.sh similarity index 100% rename from build_tools/azure/test_pytest_soft_dependency.sh rename to build_tools/github/test_pytest_soft_dependency.sh diff --git a/build_tools/azure/test_script.sh b/build_tools/github/test_script.sh similarity index 61% rename from build_tools/azure/test_script.sh rename to build_tools/github/test_script.sh index 3f47c1455932f..f4300d4d0bf04 100755 --- a/build_tools/azure/test_script.sh +++ b/build_tools/github/test_script.sh @@ -7,31 +7,6 @@ source build_tools/shared.sh activate_environment -if [[ "$BUILD_REASON" == "Schedule" ]]; then - # Enable global random seed randomization to discover seed-sensitive tests - # only on nightly builds. - # https://scikit-learn.org/stable/computing/parallelism.html#environment-variables - export SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$(($RANDOM % 20)) - echo "To reproduce this test run, set the following environment variable:" - echo " SKLEARN_TESTS_GLOBAL_RANDOM_SEED=$SKLEARN_TESTS_GLOBAL_RANDOM_SEED", - echo "See: https://scikit-learn.org/dev/computing/parallelism.html#sklearn-tests-global-random-seed" - - # Enable global dtype fixture for all nightly builds to discover - # numerical-sensitive tests. - # https://scikit-learn.org/stable/computing/parallelism.html#environment-variables - export SKLEARN_RUN_FLOAT32_TESTS=1 -fi - -# In GitHub Action (especially in `.github/workflows/unit-tests.yml` which -# calls this script), the environment variable `COMMIT_MESSAGE` is already set -# to the latest commit message. -if [[ -z "${COMMIT_MESSAGE+x}" ]]; then - # If 'COMMIT_MESSAGE' is unset we are in Azure, and we retrieve the commit - # message via the get_commit_message.py script which uses Azure-specific - # variables, for example 'BUILD_SOURCEVERSIONMESSAGE'. - COMMIT_MESSAGE=$(python build_tools/azure/get_commit_message.py --only-show-message) -fi - if [[ "$COMMIT_MESSAGE" =~ \[float32\] ]]; then echo "float32 tests will be run due to commit message" export SKLEARN_RUN_FLOAT32_TESTS=1 diff --git a/build_tools/azure/ubuntu_atlas_lock.txt b/build_tools/github/ubuntu_atlas_lock.txt similarity index 100% rename from build_tools/azure/ubuntu_atlas_lock.txt rename to build_tools/github/ubuntu_atlas_lock.txt diff --git a/build_tools/azure/ubuntu_atlas_requirements.txt b/build_tools/github/ubuntu_atlas_requirements.txt similarity index 100% rename from build_tools/azure/ubuntu_atlas_requirements.txt rename to build_tools/github/ubuntu_atlas_requirements.txt diff --git a/build_tools/update_environments_and_lock_files.py b/build_tools/update_environments_and_lock_files.py index 731b8bb91a08c..1bd11432d4e8b 100644 --- a/build_tools/update_environments_and_lock_files.py +++ b/build_tools/update_environments_and_lock_files.py @@ -119,7 +119,7 @@ def remove_from(alist, to_remove): "name": "pylatest_conda_forge_mkl_linux-64", "type": "conda", "tag": "main-ci", - "folder": "build_tools/azure", + "folder": "build_tools/github", "platform": "linux-64", "channels": ["conda-forge"], "conda_dependencies": common_dependencies @@ -141,7 +141,7 @@ def remove_from(alist, to_remove): "name": "pylatest_conda_forge_osx-arm64", "type": "conda", "tag": "main-ci", - "folder": "build_tools/azure", + "folder": "build_tools/github", "platform": "osx-arm64", "channels": ["conda-forge"], "conda_dependencies": common_dependencies @@ -158,7 +158,7 @@ def remove_from(alist, to_remove): "name": "pylatest_conda_forge_mkl_no_openmp", "type": "conda", "tag": "main-ci", - "folder": "build_tools/azure", + "folder": "build_tools/github", "platform": "osx-64", "channels": ["conda-forge"], "conda_dependencies": common_dependencies + ["ccache"], @@ -170,7 +170,7 @@ def remove_from(alist, to_remove): "name": "pymin_conda_forge_openblas_min_dependencies", "type": "conda", "tag": "main-ci", - "folder": "build_tools/azure", + "folder": "build_tools/github", "platform": "linux-64", "channels": ["conda-forge"], "conda_dependencies": remove_from(common_dependencies, ["pandas"]) @@ -198,7 +198,7 @@ def remove_from(alist, to_remove): "name": "pymin_conda_forge_openblas_ubuntu_2204", "type": "conda", "tag": "main-ci", - "folder": "build_tools/azure", + "folder": "build_tools/github", "platform": "linux-64", "channels": ["conda-forge"], "conda_dependencies": ( @@ -215,7 +215,7 @@ def remove_from(alist, to_remove): "name": "pylatest_pip_openblas_pandas", "type": "conda", "tag": "main-ci", - "folder": "build_tools/azure", + "folder": "build_tools/github", "platform": "linux-64", "channels": ["conda-forge"], "conda_dependencies": ["python", "ccache"], @@ -239,7 +239,7 @@ def remove_from(alist, to_remove): "name": "pylatest_pip_scipy_dev", "type": "conda", "tag": "scipy-dev", - "folder": "build_tools/azure", + "folder": "build_tools/github", "platform": "linux-64", "channels": ["conda-forge"], "conda_dependencies": ["python", "ccache"], @@ -273,7 +273,7 @@ def remove_from(alist, to_remove): "name": "pylatest_free_threaded", "type": "conda", "tag": "free-threaded", - "folder": "build_tools/azure", + "folder": "build_tools/github", "platform": "linux-64", "channels": ["conda-forge"], "conda_dependencies": [ @@ -294,7 +294,7 @@ def remove_from(alist, to_remove): "name": "pymin_conda_forge_openblas", "type": "conda", "tag": "main-ci", - "folder": "build_tools/azure", + "folder": "build_tools/github", "platform": "win-64", "channels": ["conda-forge"], "conda_dependencies": remove_from(common_dependencies, ["pandas", "pyamg"]) @@ -426,7 +426,7 @@ def remove_from(alist, to_remove): "name": "debian_32bit", "type": "pip", "tag": "main-ci", - "folder": "build_tools/azure", + "folder": "build_tools/github", "pip_dependencies": [ "cython", "joblib", @@ -445,7 +445,7 @@ def remove_from(alist, to_remove): "name": "ubuntu_atlas", "type": "pip", "tag": "main-ci", - "folder": "build_tools/azure", + "folder": "build_tools/github", "pip_dependencies": [ "cython", "joblib", diff --git a/doc/about.rst b/doc/about.rst index e3b015c5f9fee..89ae80084eadf 100644 --- a/doc/about.rst +++ b/doc/about.rst @@ -503,11 +503,7 @@ scikit-learn project. </tr> <tr> <td><a href="https://www.github.com">GitHub</a></td> - <td>Teams account</td> - </tr> - <tr> - <td><a href="https://azure.microsoft.com/en-us/">Microsoft Azure</a></td> - <td>CPU time on their Continuous Integration servers</td> + <td>CPU time on their Continuous Integration servers + Teams account</td> </tr> </tbody> </table> diff --git a/doc/developers/contributing.rst b/doc/developers/contributing.rst index 56ed850fbc3e7..ac4fe5578ab9d 100644 --- a/doc/developers/contributing.rst +++ b/doc/developers/contributing.rst @@ -541,11 +541,10 @@ profiling and Cython optimizations. Continuous Integration (CI) --------------------------- -* Azure pipelines are used for testing scikit-learn on Linux, Mac and Windows, - with different dependencies and settings. +* Github Actions are used for various tasks, including testing scikit-learn on + Linux, Mac and Windows, with different dependencies and settings, building + wheels and source distributions. * CircleCI is used to build the docs for viewing. -* Github Actions are used for various tasks, including building wheels and - source distributions. .. _commit_markers: @@ -560,7 +559,6 @@ Commit Message Marker Action Taken by CI ====================== =================== [ci skip] CI is skipped completely [cd build] CD is run (wheels and source distribution are built) -[lint skip] Azure pipeline skips linting [scipy-dev] Build & test with our dependencies (numpy, scipy, etc.) development builds [free-threaded] Build & test with CPython 3.14 free-threaded [pyodide] Build & test with Pyodide diff --git a/pyproject.toml b/pyproject.toml index 11eb36a7986ef..d09e030b58226 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -267,7 +267,7 @@ exclude= ''' [tool.check-sdist] # These settings should match .gitattributes sdist-only = [] -git-only = [".*", "asv_benchmarks", "azure-pipelines.yml", "benchmarks", "build_tools", "maint_tools"] +git-only = [".*", "asv_benchmarks", "benchmarks", "build_tools", "maint_tools"] default-ignore = false [tool.spin] diff --git a/sklearn/utils/tests/test_estimator_checks.py b/sklearn/utils/tests/test_estimator_checks.py index 556cf42462ab1..a3c40d8ae4457 100644 --- a/sklearn/utils/tests/test_estimator_checks.py +++ b/sklearn/utils/tests/test_estimator_checks.py @@ -1,5 +1,5 @@ # We can not use pytest here, because we run -# build_tools/azure/test_pytest_soft_dependency.sh on these +# build_tools/github/test_pytest_soft_dependency.sh on these # tests to make sure estimator_checks works without pytest. import importlib From fa3a6cc978700cabe52ec39a48864c3b79fc001b Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Mon, 2 Mar 2026 17:31:54 +0100 Subject: [PATCH 249/462] TST improve test time in `test_calibrated_classifier_cv_works_with_large_confidence_scores` (#33414) --- sklearn/tests/test_calibration.py | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/sklearn/tests/test_calibration.py b/sklearn/tests/test_calibration.py index d082b26b6e946..62d4608b21770 100644 --- a/sklearn/tests/test_calibration.py +++ b/sklearn/tests/test_calibration.py @@ -1086,12 +1086,12 @@ def fit(self, X, y, sample_weight=None, fit_param=None): ) +@pytest.mark.filterwarnings("ignore::sklearn.exceptions.ConvergenceWarning") def test_calibrated_classifier_cv_works_with_large_confidence_scores( global_random_seed, ): - """Test that :class:`CalibratedClassifierCV` works with large confidence - scores when using the `sigmoid` method, particularly with the - :class:`SGDClassifier`. + """Test that CalibratedClassifierCV works with large confidence scores when using + the sigmoid method, particularly with the SGDClassifier. Non-regression test for issue #26766. """ @@ -1104,12 +1104,13 @@ def test_calibrated_classifier_cv_works_with_large_confidence_scores( # Check that the decision function of SGDClassifier produces predicted # values that are quite large, for the data under consideration. - cv = check_cv(cv=None, y=y, classifier=True) + clf = SGDClassifier(loss="squared_hinge", tol=1e-2, random_state=global_random_seed) + cv = check_cv(cv=3, y=y, classifier=True) indices = cv.split(X, y) for train, test in indices: X_train, y_train = X[train], y[train] X_test = X[test] - sgd_clf = SGDClassifier(loss="squared_hinge", random_state=global_random_seed) + sgd_clf = clone(clf) sgd_clf.fit(X_train, y_train) predictions = sgd_clf.decision_function(X_test) assert (predictions > 1e4).any() @@ -1117,22 +1118,15 @@ def test_calibrated_classifier_cv_works_with_large_confidence_scores( # Compare the CalibratedClassifierCV using the sigmoid method with the # CalibratedClassifierCV using the isotonic method. The isotonic method # is used for comparison because it is numerically stable. - clf_sigmoid = CalibratedClassifierCV( - SGDClassifier(loss="squared_hinge", random_state=global_random_seed), - method="sigmoid", - ) + clf_sigmoid = CalibratedClassifierCV(clone(clf), method="sigmoid") score_sigmoid = cross_val_score(clf_sigmoid, X, y, scoring="roc_auc") - # The isotonic method is used for comparison because it is numerically - # stable. - clf_isotonic = CalibratedClassifierCV( - SGDClassifier(loss="squared_hinge", random_state=global_random_seed), - method="isotonic", - ) + # The isotonic method is used for comparison because it is numerically stable. + clf_isotonic = CalibratedClassifierCV(clone(clf), method="isotonic") score_isotonic = cross_val_score(clf_isotonic, X, y, scoring="roc_auc") - # The AUC score should be the same because it is invariant under - # strictly monotonic conditions + # The AUC score should be the same because it is invariant under strictly monotonic + # conditions assert_allclose(score_sigmoid, score_isotonic) From 8147f24b79d702be89e9199f33011a128dc8e2ef Mon Sep 17 00:00:00 2001 From: Shruti Nath <51656807+snath-xoc@users.noreply.github.com> Date: Tue, 3 Mar 2026 11:43:56 +0300 Subject: [PATCH 250/462] Add stricter gradient check for log marginal likelihood in Gaussian Processes (#31543) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> Co-authored-by: Christian Lorentzen <lorentzen.ch@gmail.com> --- sklearn/gaussian_process/tests/test_gpc.py | 37 ++++++++++++++++------ sklearn/gaussian_process/tests/test_gpr.py | 29 +++++++++++++---- 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/sklearn/gaussian_process/tests/test_gpc.py b/sklearn/gaussian_process/tests/test_gpc.py index 365b8f5a11441..3f01c32042590 100644 --- a/sklearn/gaussian_process/tests/test_gpc.py +++ b/sklearn/gaussian_process/tests/test_gpc.py @@ -9,6 +9,7 @@ import pytest from scipy.optimize import approx_fprime +from sklearn.base import clone from sklearn.exceptions import ConvergenceWarning from sklearn.gaussian_process import GaussianProcessClassifier from sklearn.gaussian_process.kernels import ( @@ -20,7 +21,11 @@ ConstantKernel as C, ) from sklearn.gaussian_process.tests._mini_sequence_kernel import MiniSeqKernel -from sklearn.utils._testing import assert_almost_equal, assert_array_equal +from sklearn.utils._testing import ( + assert_allclose, + assert_almost_equal, + assert_array_equal, +) def f(x): @@ -105,17 +110,31 @@ def test_converged_to_local_maximum(kernel): ) -@pytest.mark.parametrize("kernel", kernels) -def test_lml_gradient(kernel): - # Compare analytic and numeric gradient of log marginal likelihood. - gpc = GaussianProcessClassifier(kernel=kernel).fit(X, y) +@pytest.mark.xfail( + raises=AssertionError, + reason="https://github.com/scikit-learn/scikit-learn/issues/31366", +) +@pytest.mark.parametrize("kernel", non_fixed_kernels) +@pytest.mark.parametrize("length_scale", np.logspace(-3, 3, 13)) +def test_lml_gradient(kernel, length_scale): + # Clone the kernel object prior to mutating it to avoid any side effects between + # GP tests: + kernel = clone(kernel) + length_scale_param_name = next( + name for name in kernel.get_params() if name.endswith("length_scale") + ) + kernel.set_params(**{length_scale_param_name: length_scale}) - lml, lml_gradient = gpc.log_marginal_likelihood(kernel.theta, True) + # Compare analytic and numeric gradient of log marginal likelihood. + gpr = GaussianProcessClassifier(kernel=kernel).fit(X, y) + _, lml_gradient = gpr.log_marginal_likelihood(kernel.theta, eval_gradient=True) + epsilon = 1e-9 lml_gradient_approx = approx_fprime( - kernel.theta, lambda theta: gpc.log_marginal_likelihood(theta, False), 1e-10 + kernel.theta.copy(), + lambda theta: gpr.log_marginal_likelihood(theta, False), + epsilon=epsilon, ) - - assert_almost_equal(lml_gradient, lml_gradient_approx, 3) + assert_allclose(lml_gradient, lml_gradient_approx, rtol=1e-4, atol=epsilon * 100) def test_random_starts(global_random_seed): diff --git a/sklearn/gaussian_process/tests/test_gpr.py b/sklearn/gaussian_process/tests/test_gpr.py index 3c841c479a8bd..a5a97af101c14 100644 --- a/sklearn/gaussian_process/tests/test_gpr.py +++ b/sklearn/gaussian_process/tests/test_gpr.py @@ -11,6 +11,7 @@ import pytest from scipy.optimize import approx_fprime +from sklearn.base import clone from sklearn.exceptions import ConvergenceWarning from sklearn.gaussian_process import GaussianProcessRegressor from sklearn.gaussian_process.kernels import ( @@ -140,17 +141,31 @@ def test_solution_inside_bounds(kernel): assert_array_less(gpr.kernel_.theta, bounds[:, 1] + tiny) -@pytest.mark.parametrize("kernel", kernels) -def test_lml_gradient(kernel): +@pytest.mark.xfail( + raises=AssertionError, + reason="https://github.com/scikit-learn/scikit-learn/issues/31366", +) +@pytest.mark.parametrize("kernel", non_fixed_kernels) +@pytest.mark.parametrize("length_scale", np.logspace(-3, 3, 13)) +def test_lml_gradient(kernel, length_scale): + # Clone the kernel object prior to mutating it to avoid any side effects between + # GP tests: + kernel = clone(kernel) + length_scale_param_name = next( + name for name in kernel.get_params() if name.endswith("length_scale") + ) + kernel.set_params(**{length_scale_param_name: length_scale}) + # Compare analytic and numeric gradient of log marginal likelihood. gpr = GaussianProcessRegressor(kernel=kernel).fit(X, y) - - lml, lml_gradient = gpr.log_marginal_likelihood(kernel.theta, True) + _, lml_gradient = gpr.log_marginal_likelihood(kernel.theta, eval_gradient=True) + epsilon = 1e-9 lml_gradient_approx = approx_fprime( - kernel.theta, lambda theta: gpr.log_marginal_likelihood(theta, False), 1e-10 + kernel.theta.copy(), + lambda theta: gpr.log_marginal_likelihood(theta, False), + epsilon=epsilon, ) - - assert_almost_equal(lml_gradient, lml_gradient_approx, 3) + assert_allclose(lml_gradient, lml_gradient_approx, rtol=1e-4, atol=epsilon * 100) @pytest.mark.parametrize("kernel", kernels) From 5f0f25fe7c637394c736363c60c1a03f4e468842 Mon Sep 17 00:00:00 2001 From: Shruti Nath <51656807+snath-xoc@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:14:27 +0300 Subject: [PATCH 251/462] FIX Added sample weight handling to BinMapper under HGBT (#29641) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> Co-authored-by: antoinebaker <antoinebaker@users.noreply.github.com> Co-authored-by: Christian Lorentzen <lorentzen.ch@gmail.com> --- .../sklearn.ensemble/29641.fix.rst | 11 +++ .../_hist_gradient_boosting/binning.py | 86 +++++++++++++++---- .../gradient_boosting.py | 16 ++-- .../tests/test_binning.py | 80 +++++++++++++++++ .../tests/test_gradient_boosting.py | 38 ++++---- .../tests/test_predictor.py | 2 +- 6 files changed, 189 insertions(+), 44 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.ensemble/29641.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.ensemble/29641.fix.rst b/doc/whats_new/upcoming_changes/sklearn.ensemble/29641.fix.rst new file mode 100644 index 0000000000000..987fcf033a3fe --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.ensemble/29641.fix.rst @@ -0,0 +1,11 @@ +- Fixed the way :class:`ensemble.HistGradientBoostingClassifier` and + `ensemble.HistGradientBoostingRegressor` compute their bin edges to properly and + consistently handle :term:`sample_weight`. When `sample_weights=None` is + passed to `fit` and the number of distinct feature values is less than the + specified `max_bins`, the edges are still set to midpoints between consecutive + feature values. Otherwise, the bin edges are set to weight-aware quantiles + computed using the averaged inverted CDF method. If `n_samples` is larger than + the `subsample` parameter, the weights are instead used to subsample the data + (with replacement) and the bin edges are set using unweighted quantiles of the + subsampled data. By + :user:`Shruti Nath <snath-xoc>` and :user:`Olivier Grisel <ogrisel>` diff --git a/sklearn/ensemble/_hist_gradient_boosting/binning.py b/sklearn/ensemble/_hist_gradient_boosting/binning.py index b0745b58ae8dd..3b3a4108359ee 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/binning.py +++ b/sklearn/ensemble/_hist_gradient_boosting/binning.py @@ -10,6 +10,7 @@ # SPDX-License-Identifier: BSD-3-Clause import numpy as np +from numpy.lib.stride_tricks import sliding_window_view from sklearn.base import BaseEstimator, TransformerMixin from sklearn.ensemble._hist_gradient_boosting._binning import _map_to_bins @@ -23,10 +24,11 @@ from sklearn.utils import check_array, check_random_state from sklearn.utils._openmp_helpers import _openmp_effective_n_threads from sklearn.utils.parallel import Parallel, delayed +from sklearn.utils.stats import _weighted_percentile from sklearn.utils.validation import check_is_fitted -def _find_binning_thresholds(col_data, max_bins): +def _find_binning_thresholds(col_data, max_bins, sample_weight=None): """Extract quantiles from a continuous feature. Missing values are ignored for finding the thresholds. @@ -50,31 +52,63 @@ def _find_binning_thresholds(col_data, max_bins): """ # ignore missing values when computing bin thresholds missing_mask = np.isnan(col_data) - if missing_mask.any(): + any_missing = missing_mask.any() + if any_missing: col_data = col_data[~missing_mask] + + # If sample_weight is not None and 0-weighted values exist, we need to + # remove those before calculating the distinct points. + if sample_weight is not None: + if any_missing: + sample_weight = sample_weight[~missing_mask] + nnz_sw = sample_weight != 0 + col_data = col_data[nnz_sw] + sample_weight = sample_weight[nnz_sw] + # The data will be sorted anyway in np.unique and again in percentile, so we do it # here. Sorting also returns a contiguous array. - col_data = np.sort(col_data) + sort_idx = np.argsort(col_data) + col_data = col_data[sort_idx] + if sample_weight is not None: + sample_weight = sample_weight[sort_idx] + distinct_values = np.unique(col_data).astype(X_DTYPE) + + if len(distinct_values) == 1: + return np.asarray([]) + if len(distinct_values) <= max_bins: - midpoints = distinct_values[:-1] + distinct_values[1:] - midpoints *= 0.5 + # Calculate midpoints if distinct values <= max_bins + bin_thresholds = sliding_window_view(distinct_values, 2).mean(axis=1) + elif sample_weight is None: + # We compute bin edges using the output of np.percentile with + # the "averaged_inverted_cdf" interpolation method that is consistent + # with the code for the sample_weight != None case. + percentiles = np.linspace(0, 100, num=max_bins + 1) + percentiles = percentiles[1:-1] + bin_thresholds = np.percentile( + col_data, percentiles, method="averaged_inverted_cdf" + ) + assert bin_thresholds.shape[0] == max_bins - 1 else: - # We could compute approximate midpoint percentiles using the output of - # np.unique(col_data, return_counts) instead but this is more - # work and the performance benefit will be limited because we - # work on a fixed-size subsample of the full data. percentiles = np.linspace(0, 100, num=max_bins + 1) percentiles = percentiles[1:-1] - midpoints = np.percentile(col_data, percentiles, method="midpoint").astype( - X_DTYPE + bin_thresholds = np.array( + [ + _weighted_percentile(col_data, sample_weight, percentile, average=True) + for percentile in percentiles + ] ) - assert midpoints.shape[0] == max_bins - 1 + assert bin_thresholds.shape[0] == max_bins - 1 + # Remove duplicated thresholds if they exist. + unique_bin_values = np.unique(bin_thresholds) + if unique_bin_values.shape[0] != bin_thresholds.shape[0]: + bin_thresholds = unique_bin_values # We avoid having +inf thresholds: +inf thresholds are only allowed in # a "split on nan" situation. - np.clip(midpoints, a_min=None, a_max=ALMOST_INF, out=midpoints) - return midpoints + np.clip(bin_thresholds, a_min=None, a_max=ALMOST_INF, out=bin_thresholds) + return bin_thresholds class _BinMapper(TransformerMixin, BaseEstimator): @@ -175,7 +209,7 @@ def __init__( self.random_state = random_state self.n_threads = n_threads - def fit(self, X, y=None): + def fit(self, X, y=None, sample_weight=None): """Fit data X by computing the binning thresholds. The last bin is reserved for missing values, whether missing values @@ -202,12 +236,25 @@ def fit(self, X, y=None): X = check_array(X, dtype=[X_DTYPE], ensure_all_finite=False) max_bins = self.n_bins - 1 - rng = check_random_state(self.random_state) if self.subsample is not None and X.shape[0] > self.subsample: - subset = rng.choice(X.shape[0], self.subsample, replace=False) + subsampling_probabilities = None + if sample_weight is not None: + subsampling_probabilities = sample_weight / np.sum(sample_weight) + # Sampling with replacement to implement frequency semantics + # for sample weights. Note that we need `replace=True` even when + # `sample_weight is None` to make sure that passing no weights is + # statistically equivalent to passing unit weights. + subset = rng.choice( + X.shape[0], self.subsample, p=subsampling_probabilities, replace=True + ) X = X.take(subset, axis=0) + # Add a switch to replace sample weights with None + # since sample weights were already used in subsampling + # and should not then be propagated to _find_binning_thresholds + sample_weight = None + if self.is_categorical is None: self.is_categorical_ = np.zeros(X.shape[1], dtype=np.uint8) else: @@ -238,11 +285,12 @@ def fit(self, X, y=None): n_bins_non_missing = [None] * n_features non_cat_thresholds = Parallel(n_jobs=self.n_threads, backend="threading")( - delayed(_find_binning_thresholds)(X[:, f_idx], max_bins) + delayed(_find_binning_thresholds)( + X[:, f_idx], max_bins, sample_weight=sample_weight + ) for f_idx in range(n_features) if not self.is_categorical_[f_idx] ) - non_cat_idx = 0 for f_idx in range(n_features): if self.is_categorical_[f_idx]: diff --git a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py index 4a4fa319f4ab7..a2977cdc6b64c 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py +++ b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py @@ -719,9 +719,13 @@ def fit( random_state=self._random_seed, n_threads=n_threads, ) - X_binned_train = self._bin_data(X_train, is_training_data=True) + X_binned_train = self._bin_data( + X_train, sample_weight_train, is_training_data=True + ) if X_val is not None: - X_binned_val = self._bin_data(X_val, is_training_data=False) + X_binned_val = self._bin_data( + X_val, sample_weight_val, is_training_data=False + ) else: X_binned_val = None @@ -1218,7 +1222,7 @@ def _should_stop(self, scores): recent_improvements = [score > reference_score for score in recent_scores] return not any(recent_improvements) - def _bin_data(self, X, is_training_data): + def _bin_data(self, X, sample_weight, is_training_data): """Bin data X. If is_training_data, then fit the _bin_mapper attribute. @@ -1234,7 +1238,9 @@ def _bin_data(self, X, is_training_data): ) tic = time() if is_training_data: - X_binned = self._bin_mapper.fit_transform(X) # F-aligned array + X_binned = self._bin_mapper.fit_transform( + X, sample_weight=sample_weight + ) # F-aligned array else: X_binned = self._bin_mapper.transform(X) # F-aligned array # We convert the array to C-contiguous since predicting is faster @@ -1736,7 +1742,7 @@ class HistGradientBoostingRegressor(RegressorMixin, BaseHistGradientBoosting): >>> X, y = load_diabetes(return_X_y=True) >>> est = HistGradientBoostingRegressor().fit(X, y) >>> est.score(X, y) - 0.92... + 0.93... """ _parameter_constraints: dict = { diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_binning.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_binning.py index 6f9fcd0057141..6193594fa74b7 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_binning.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_binning.py @@ -1,6 +1,7 @@ import numpy as np import pytest from numpy.testing import assert_allclose, assert_array_equal +from scipy.stats import kstest from sklearn.ensemble._hist_gradient_boosting.binning import ( _BinMapper, @@ -113,6 +114,22 @@ def test_map_to_bins(max_bins): assert binned[max_idx, feature_idx] == max_bins - 1 +def test_unique_bins_repeated_weighted(): + # Test sample weight equivalence for the degenerate case + # when only one unique bin value exists and should be trimmed + # due to repeated values. Since the first discrete value of 1 + # is repeated/weighted 1000 times we expect the quantile bin + # threshold values found to be repeated values of 1, which are + # trimmed to return a single unique bin threshold of [1.] + col_data = np.asarray([1, 2, 3, 4, 5, 6]).reshape(-1, 1) + sample_weight = np.asarray([1000, 1, 1, 1, 1, 1]) + col_data_repeated = np.asarray(([1] * 1000) + [2, 3, 4, 5, 6]).reshape(-1, 1) + + binmapper = _BinMapper(n_bins=4).fit(col_data, sample_weight=sample_weight) + binmapper_repeated = _BinMapper(n_bins=4).fit(col_data_repeated) + assert_array_equal(binmapper.bin_thresholds_, binmapper_repeated.bin_thresholds_) + + @pytest.mark.parametrize("max_bins", [5, 10, 42]) def test_bin_mapper_random_data(max_bins): n_samples, n_features = DATA.shape @@ -198,6 +215,69 @@ def test_bin_mapper_repeated_values_invariance(n_distinct): assert_array_equal(binned_1, binned_2) +@pytest.mark.parametrize("n_bins", [50, 250]) +def test_binmapper_weighted_vs_repeated_equivalence(global_random_seed, n_bins): + rng = np.random.RandomState(global_random_seed) + + n_samples = 200 + X = rng.randn(n_samples, 3) + sw = rng.randint(0, 5, size=n_samples) + X_repeated = np.repeat(X, sw, axis=0) + + est_weighted = _BinMapper(n_bins=n_bins).fit(X, sample_weight=sw) + est_repeated = _BinMapper(n_bins=n_bins).fit(X_repeated, sample_weight=None) + assert_allclose(est_weighted.bin_thresholds_, est_repeated.bin_thresholds_) + + X_trans_weighted = est_weighted.transform(X) + X_trans_repeated = est_repeated.transform(X) + assert_array_equal(X_trans_weighted, X_trans_repeated) + + +# Note: we use a small number of RNG seeds to check that the tests is not seed +# dependent while keeping the statistical test valid. If we had used the +# global_random_seed fixture, it would have been expected to get some wrong +# rejections of the null hypothesis because of the large number of +# tests run by the fixture. +@pytest.mark.parametrize("seed", [0, 1, 42]) +@pytest.mark.parametrize("n_bins", [3, 5]) +def test_subsampled_weighted_vs_repeated_equivalence(seed, n_bins): + rng = np.random.RandomState(seed) + + n_samples = 500 + X = rng.randn(n_samples, 3) + + sw = rng.randint(0, 5, size=n_samples) + X_repeated = np.repeat(X, sw, axis=0) + + # Collect estimated bins thresholds on the weighted/repeated datasets for + # `n_resampling_iterations` subsampling. `n_resampling_iterations` is large + # enough to ensure a well-powered statistical test. + n_resampling_iterations = 500 + bins_weighted = [] + bins_repeated = [] + for _ in range(n_resampling_iterations): + params = dict(n_bins=n_bins, subsample=300, random_state=rng) + est_weighted = _BinMapper(**params).fit(X, sample_weight=sw) + est_repeated = _BinMapper(**params).fit(X_repeated, sample_weight=None) + bins_weighted.append(np.hstack(est_weighted.bin_thresholds_)) + bins_repeated.append(np.hstack(est_repeated.bin_thresholds_)) + + bins_weighted = np.stack(bins_weighted).T + bins_repeated = np.stack(bins_repeated).T + # bins_weighted and bins_weighted of shape (n_thresholds, n_subsample) + # kstest_pval of shape (n_thresholds,) + kstest_pval = np.asarray( + [ + kstest(bin_weighted, bin_repeated).pvalue + for bin_weighted, bin_repeated in zip(bins_weighted, bins_repeated) + ] + ) + # We should not be able to reject the null hypothesis that the two samples + # come from the same distribution for all bins at level 5% with Bonferroni + # correction. + assert np.min(kstest_pval) > 0.05 / len(kstest_pval) + + @pytest.mark.parametrize( "max_bins, scale, offset", [ diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py index e5992e27840b8..cb8cc1971a0d2 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py @@ -708,6 +708,7 @@ def test_zero_sample_weights_classification(): X = [[1, 0], [1, 0], [1, 0], [0, 1], [1, 1]] y = [0, 0, 1, 0, 2] + # ignore the first 2 training samples by setting their weight to 0 sample_weight = [0, 0, 1, 1, 1] gb = HistGradientBoostingClassifier(loss="log_loss", min_samples_leaf=1) @@ -718,16 +719,19 @@ def test_zero_sample_weights_classification(): @pytest.mark.parametrize( "problem", ("regression", "binary_classification", "multiclass_classification") ) -@pytest.mark.parametrize("duplication", ("half", "all")) -def test_sample_weight_effect(problem, duplication): +def test_sample_weight_effect(problem, global_random_seed): # High level test to make sure that duplicating a sample is equivalent to # giving it weight of 2. - # fails for n_samples > 255 because binning does not take sample weights - # into account. Keeping n_samples <= 255 makes - # sure only unique values are used so SW have no effect on binning. - n_samples = 255 + # This test assumes that subsampling in `_BinMapper` is disabled + # (when `n_samples < 2e5`) and therefore the binning results should be + # deterministic. + # Otherwise, this test would require being rewritten as a statistical test. + # We also set `n_samples` large enough to ensure that columns have more than + # 255 distinct values and that we test the impact of weight-aware binning. + n_samples = 300 n_features = 2 + rng = np.random.RandomState(global_random_seed) if problem == "regression": X, y = make_regression( n_samples=n_samples, @@ -755,21 +759,17 @@ def test_sample_weight_effect(problem, duplication): # duplicated samples. est = Klass(min_samples_leaf=1) - # Create dataset with duplicate and corresponding sample weights - if duplication == "half": - lim = n_samples // 2 - else: - lim = n_samples - X_dup = np.r_[X, X[:lim]] - y_dup = np.r_[y, y[:lim]] - sample_weight = np.ones(shape=(n_samples)) - sample_weight[:lim] = 2 + # Create dataset with repetitions and corresponding sample weights + sample_weight = rng.randint(0, 3, size=X.shape[0]) + X_repeated = np.repeat(X, sample_weight, axis=0) + assert X_repeated.shape[0] < 2e5 + y_repeated = np.repeat(y, sample_weight, axis=0) - est_sw = clone(est).fit(X, y, sample_weight=sample_weight) - est_dup = clone(est).fit(X_dup, y_dup) + est_weighted = clone(est).fit(X, y, sample_weight=sample_weight) + est_repeated = clone(est).fit(X_repeated, y_repeated) # checking raw_predict is stricter than just predict for classification - assert np.allclose(est_sw._raw_predict(X_dup), est_dup._raw_predict(X_dup)) + assert_allclose(est_weighted._raw_predict(X), est_repeated._raw_predict(X)) @pytest.mark.parametrize("Loss", (HalfSquaredError, AbsoluteError)) @@ -1303,7 +1303,7 @@ def test_check_interaction_cst(interaction_cst, n_features, result): def test_interaction_cst_numerically(): """Check that interaction constraints have no forbidden interactions.""" rng = np.random.RandomState(42) - n_samples = 1000 + n_samples = 2000 X = rng.uniform(size=(n_samples, 2)) # Construct y with a strong interaction term # y = x0 + x1 + 5 * x0 * x1 diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_predictor.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_predictor.py index 3c3c9ae81bac2..ae9770ca14a83 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_predictor.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_predictor.py @@ -28,7 +28,7 @@ @pytest.mark.parametrize("n_bins", [200, 256]) def test_regression_dataset(n_bins): X, y = make_regression( - n_samples=500, n_features=10, n_informative=5, random_state=42 + n_samples=1000, n_features=10, n_informative=5, random_state=42 ) X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42) From 24bfc297267e542be4cb677d8c8cba3caa4b50cb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:35:45 +0100 Subject: [PATCH 252/462] Bump the actions group with 2 updates (#33429) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/bot-lint-comment.yml | 2 +- .github/workflows/cuda-ci.yml | 4 ++-- .github/workflows/emscripten.yml | 4 ++-- .github/workflows/lint.yml | 2 +- .github/workflows/wheels.yml | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/bot-lint-comment.yml b/.github/workflows/bot-lint-comment.yml index 2254fcdc9c5a3..cc694e8ad5969 100644 --- a/.github/workflows/bot-lint-comment.yml +++ b/.github/workflows/bot-lint-comment.yml @@ -23,7 +23,7 @@ jobs: run: mkdir -p "$ARTIFACTS_DIR" - name: Download artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: lint-log path: ${{ runner.temp }}/artifacts diff --git a/.github/workflows/cuda-ci.yml b/.github/workflows/cuda-ci.yml index 76d0041763909..d79d646b0bd92 100644 --- a/.github/workflows/cuda-ci.yml +++ b/.github/workflows/cuda-ci.yml @@ -25,7 +25,7 @@ jobs: CIBW_BUILD_VERBOSITY: 1 CIBW_ARCHS: x86_64 - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: cibw-wheels path: ./wheelhouse/*.whl @@ -40,7 +40,7 @@ jobs: timeout-minutes: 20 name: Run Array API unit tests steps: - - uses: actions/download-artifact@v7 + - uses: actions/download-artifact@v8 with: pattern: cibw-wheels path: ~/dist diff --git a/.github/workflows/emscripten.yml b/.github/workflows/emscripten.yml index dc1a7a08f2a0a..9d5f250e45707 100644 --- a/.github/workflows/emscripten.yml +++ b/.github/workflows/emscripten.yml @@ -77,7 +77,7 @@ jobs: CIBW_TEST_COMMAND: "python -m pytest -sra --pyargs sklearn --durations 20 --showlocals" - name: Upload wheel artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: pyodide_wheel path: ./wheelhouse/*.whl @@ -94,7 +94,7 @@ jobs: if: github.repository == 'scikit-learn/scikit-learn' && github.event_name != 'pull_request' steps: - name: Download wheel artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: path: wheelhouse/ merge-multiple: true diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2c29a4d0923d4..593faf026b2e0 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -48,7 +48,7 @@ jobs: - name: Upload Artifact if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: lint-log path: | diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index a1cf2d76a9b2d..cdd3ae1957982 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -240,7 +240,7 @@ jobs: run: bash build_tools/wheels/build_wheels.sh - name: Store artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: cibw-wheels-cp${{ matrix.python }}-${{ matrix.platform_id }} path: wheelhouse/*.whl @@ -279,7 +279,7 @@ jobs: SKLEARN_SKIP_NETWORK_TESTS: 1 - name: Store artifacts - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: cibw-sdist path: dist/*.tar.gz @@ -298,7 +298,7 @@ jobs: uses: actions/checkout@v6 - name: Download artifacts - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: pattern: cibw-* path: dist From 2d59ab9c928d5741b7f72f83201bd0b9edc8511d Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Tue, 3 Mar 2026 14:03:54 +0100 Subject: [PATCH 253/462] MNT fix and refactor color handling in DecisionBoundaryDisplay - Part 1 (#33419) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> --- .../sklearn.inspection/33419.fix.rst | 4 + sklearn/inspection/_plot/decision_boundary.py | 138 ++++++++++-------- .../tests/test_boundary_decision_display.py | 74 ++++++++-- sklearn/utils/_optional_dependencies.py | 6 +- 4 files changed, 145 insertions(+), 77 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.inspection/33419.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/33419.fix.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/33419.fix.rst new file mode 100644 index 0000000000000..e0da40b4044b5 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.inspection/33419.fix.rst @@ -0,0 +1,4 @@ +- In :class:`inspection.DecisionBoundaryDisplay`, a `ValueError` is now raised if the + colormap passed to `multiclass_colors` contains fewer colors than there are classes in + multiclass problems. + By :user:`Anne Beyer <AnneBeyer>`. diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index 28b310461e6dc..e5c3f11eee17c 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -54,6 +54,75 @@ def _check_boundary_response_method(estimator, response_method): return prediction_method +def _select_colors(mpl, multiclass_colors, n_classes): + """Select colors for multiclass decision boundary display. + + Parameters + ---------- + mpl : module + Imported `matplotlib` module. + + multiclass_colors : list of color-like, str, or None + Color specification for multiclass plots. + + - If `None`, defaults to `"tab10"` when `n_classes <= 10`, otherwise + `"gist_rainbow"`. + - If `str`, interpreted as a Matplotlib colormap name. + - If `list`, each entry must be a valid Matplotlib color-like value. + + n_classes : int + Number of colors to select. + + Returns + ------- + colors : list or ndarray of shape (n_classes, 4) + RGBA colors, one per class. + + """ + + if multiclass_colors is None: + multiclass_colors = "tab10" if n_classes <= 10 else "gist_rainbow" + + if isinstance(multiclass_colors, str): + if multiclass_colors not in mpl.pyplot.colormaps(): + raise ValueError( + "When 'multiclass_colors' is a string, it must be a valid " + f"Matplotlib colormap. Got: {multiclass_colors}" + ) + cmap = mpl.pyplot.get_cmap(multiclass_colors) + if cmap.N < n_classes: + raise ValueError( + f"Colormap '{multiclass_colors}' only has {cmap.N} colors, but " + f"{n_classes} classes are to be displayed. Please specify a " + "different colormap or provide a list of colors via " + "'multiclass_colors'." + ) + if cmap.N < 256: + # Special case for the qualitative colormaps that encode a + # discrete set of colors that are easily distinguishable, contrary to other + # colormaps that are continuous (for which `cmap.N` >= 256). + return mpl.colors.to_rgba_array(cmap.colors[:n_classes]) + else: + return cmap(np.linspace(0, 1, n_classes)) + + elif isinstance(multiclass_colors, list): + if len(multiclass_colors) != n_classes: + raise ValueError( + "When 'multiclass_colors' is a list, it must be of the same " + f"length as the classes or labels to plot ({n_classes}), got: " + f"{len(multiclass_colors)}." + ) + elif any(not mpl.colors.is_color_like(col) for col in multiclass_colors): + raise ValueError( + "When 'multiclass_colors' is a list, it can only contain valid" + f" Matplotlib color names. Got: {multiclass_colors}" + ) + return [mpl.colors.to_rgba(color) for color in multiclass_colors] + + else: + raise TypeError("'multiclass_colors' must be a list or a str.") + + class DecisionBoundaryDisplay: """Decisions boundary visualization. @@ -234,7 +303,6 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar """ check_matplotlib_support("DecisionBoundaryDisplay.plot") import matplotlib as mpl - import matplotlib.pyplot as plt if plot_method not in ("contourf", "contour", "pcolormesh"): raise ValueError( @@ -243,7 +311,7 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar ) if ax is None: - _, ax = plt.subplots() + _, ax = mpl.pyplot.subplots() plot_func = getattr(ax, plot_method) if self.n_classes == 2: @@ -257,34 +325,9 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar ) del kwargs[kwarg] - if self.multiclass_colors is None or isinstance( - self.multiclass_colors, str - ): - if self.multiclass_colors is None: - cmap = "tab10" if self.n_classes <= 10 else "gist_rainbow" - else: - cmap = self.multiclass_colors - - # Special case for the tab10 and tab20 colormaps that encode a - # discrete set of colors that are easily distinguishable - # contrary to other colormaps that are continuous. - if cmap == "tab10" and self.n_classes <= 10: - colors = plt.get_cmap("tab10", 10).colors[: self.n_classes] - elif cmap == "tab20" and self.n_classes <= 20: - colors = plt.get_cmap("tab20", 20).colors[: self.n_classes] - else: - cmap = plt.get_cmap(cmap, self.n_classes) - if not hasattr(cmap, "colors"): - # Get `LinearSegmentedColormap` for non-qualitative cmaps - colors = cmap(np.linspace(0, 1, self.n_classes)) - else: - colors = cmap.colors - elif isinstance(self.multiclass_colors, list): - colors = [mpl.colors.to_rgba(color) for color in self.multiclass_colors] - else: - raise ValueError("'multiclass_colors' must be a list or a str.") - - self.multiclass_colors_ = colors + self.multiclass_colors_ = _select_colors( + mpl, self.multiclass_colors, self.n_classes + ) if self.response.ndim == 2: # predict # Set `levels` to ensure all classes are displayed in different colors @@ -294,7 +337,7 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar elif plot_method == "contourf": kwargs["levels"] = np.arange(self.n_classes + 1) - 0.5 # `pcolormesh` requires cmap, for the others it makes no difference - cmap = mpl.colors.ListedColormap(colors) + cmap = mpl.colors.ListedColormap(self.multiclass_colors_) self.surface_ = plot_func( self.xx0, self.xx1, self.response, cmap=cmap, **kwargs ) @@ -309,7 +352,7 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar self.xx0, self.xx1, self.response.argmax(axis=2), - colors=colors, + colors=self.multiclass_colors_, **kwargs, ) else: @@ -318,7 +361,7 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar f"colormap_{class_idx}", [(1.0, 1.0, 1.0, 1.0), (r, g, b, 1.0)], ) - for class_idx, (r, g, b, _) in enumerate(colors) + for class_idx, (r, g, b, _) in enumerate(self.multiclass_colors_) ] self.surface_ = [] for class_idx, cmap in enumerate(multiclass_cmaps): @@ -483,9 +526,7 @@ def from_estimator( <...> >>> plt.show() """ - check_matplotlib_support(f"{cls.__name__}.from_estimator") check_is_fitted(estimator) - import matplotlib as mpl if not grid_resolution > 1: raise ValueError( @@ -512,33 +553,6 @@ def from_estimator( f"n_features must be equal to 2. Got {num_features} instead." ) - if ( - response_method in ("predict_proba", "decision_function", "auto") - and multiclass_colors is not None - and hasattr(estimator, "classes_") - and (n_classes := len(estimator.classes_)) > 2 - ): - if isinstance(multiclass_colors, list): - if len(multiclass_colors) != n_classes: - raise ValueError( - "When 'multiclass_colors' is a list, it must be of the same " - f"length as 'estimator.classes_' ({n_classes}), got: " - f"{len(multiclass_colors)}." - ) - elif any( - not mpl.colors.is_color_like(col) for col in multiclass_colors - ): - raise ValueError( - "When 'multiclass_colors' is a list, it can only contain valid" - f" Matplotlib color names. Got: {multiclass_colors}" - ) - if isinstance(multiclass_colors, str): - if multiclass_colors not in mpl.pyplot.colormaps(): - raise ValueError( - "When 'multiclass_colors' is a string, it must be a valid " - f"Matplotlib colormap. Got: {multiclass_colors}" - ) - x0, x1 = _safe_indexing(X, 0, axis=1), _safe_indexing(X, 1, axis=1) x0_min, x0_max = x0.min() - eps, x0.max() + eps diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index 85605d5be88ab..7319af89d6ccb 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -166,25 +166,42 @@ def test_input_validation_errors(pyplot, kwargs, error_msg, fitted_clf): @pytest.mark.parametrize( - "kwargs, error_msg", + "kwargs, error_type, error_msg", [ ( {"multiclass_colors": {"dict": "not_list"}}, + TypeError, "'multiclass_colors' must be a list or a str.", ), - ({"multiclass_colors": "not_cmap"}, "it must be a valid Matplotlib colormap"), - ({"multiclass_colors": ["red", "green"]}, "it must be of the same length"), + ( + {"multiclass_colors": "not_cmap"}, + ValueError, + "it must be a valid Matplotlib colormap", + ), + ( + {"multiclass_colors": ["red", "green"]}, + ValueError, + "it must be of the same length", + ), + ( + {"multiclass_colors": ["red", "green", "blue", "yellow"]}, + ValueError, + "it must be of the same length", + ), ( {"multiclass_colors": ["red", "green", "not color"]}, + ValueError, "it can only contain valid Matplotlib color names", ), ], ) -def test_input_validation_errors_multiclass_colors(pyplot, kwargs, error_msg): +def test_input_validation_errors_multiclass_colors( + pyplot, kwargs, error_type, error_msg +): """Check input validation for `multiclass_colors` in `from_estimator`.""" X, y = load_iris_2d_scaled() clf = LogisticRegression().fit(X, y) - with pytest.raises(ValueError, match=error_msg): + with pytest.raises(error_type, match=error_msg): DecisionBoundaryDisplay.from_estimator(clf, X, **kwargs) @@ -617,6 +634,7 @@ def test_multiclass_plot_max_class(pyplot, response_method): (None, 11), ("plasma", 3), ("Blues", 3), + ("tab20", 20), (["red", "green", "blue"], 3), ], ) @@ -652,14 +670,15 @@ def test_multiclass_colors_cmap( if multiclass_colors is None: if len(clf.classes_) <= 10: - colors = mpl.pyplot.get_cmap("tab10", 10).colors[: len(clf.classes_)] + multiclass_colors = "tab10" else: - cmap = mpl.pyplot.get_cmap("gist_rainbow", len(clf.classes_)) - colors = cmap(np.linspace(0, 1, len(clf.classes_))) - elif multiclass_colors == "plasma": - colors = mpl.pyplot.get_cmap(multiclass_colors, len(clf.classes_)).colors - elif multiclass_colors == "Blues": - cmap = mpl.pyplot.get_cmap(multiclass_colors, len(clf.classes_)) + multiclass_colors = "gist_rainbow" + + if multiclass_colors in ["tab10", "tab20"]: + cmap = mpl.pyplot.get_cmap(multiclass_colors) + colors = mpl.colors.to_rgba_array(cmap.colors[: len(clf.classes_)]) + elif multiclass_colors in ["Blues", "gist_rainbow", "plasma"]: + cmap = mpl.pyplot.get_cmap(multiclass_colors) colors = cmap(np.linspace(0, 1, len(clf.classes_))) else: colors = [mpl.colors.to_rgba(color) for color in multiclass_colors] @@ -686,6 +705,37 @@ def test_multiclass_colors_cmap( assert_allclose(disp.surface_.colors, colors) +def test_multiclass_not_enough_colors_error(pyplot): + """ + Check that an error is raised if a qualitative colormap doesn't have enough colors. + + Non-regression test for PR 33419. + + Note: List length mismatch is already checked in + `test_input_validation_errors_multiclass_colors`. + """ + X = np.array( + [ + [-1, -1], + [-2, -1], + [1, 1], + [2, 1], + [2, 2], + [3, 2], + [3, 3], + [4, 3], + [4, 4], + [5, 4], + [5, 5], + ] + ) + y = np.arange(11) + clf = LogisticRegression().fit(X, y) + msg = "Colormap 'tab10' only has 10 colors, but 11 classes are to be displayed." + with pytest.raises(ValueError, match=msg): + DecisionBoundaryDisplay.from_estimator(clf, X, multiclass_colors="tab10") + + @pytest.mark.parametrize("y", [np.arange(6), [str(i) for i in np.arange(6)]]) @pytest.mark.parametrize( "response_method, plot_method", diff --git a/sklearn/utils/_optional_dependencies.py b/sklearn/utils/_optional_dependencies.py index 5f0041285090a..10b56b1bea837 100644 --- a/sklearn/utils/_optional_dependencies.py +++ b/sklearn/utils/_optional_dependencies.py @@ -17,8 +17,8 @@ def check_matplotlib_support(caller_name): import matplotlib # noqa: F401 except ImportError as e: raise ImportError( - "{} requires matplotlib. You can install matplotlib with " - "`pip install matplotlib`".format(caller_name) + f"{caller_name} requires matplotlib. You can install matplotlib with " + "`pip install matplotlib`" ) from e @@ -43,4 +43,4 @@ def check_pandas_support(caller_name): return pandas except ImportError as e: - raise ImportError("{} requires pandas.".format(caller_name)) from e + raise ImportError(f"{caller_name} requires pandas.") from e From 70244ed4f3f15e34a24f02482293b3f063dfee1b Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Tue, 3 Mar 2026 18:48:50 +0100 Subject: [PATCH 254/462] FIX always pass `fill_value` to `xp.full` as per array API spec (#33437) Co-authored-by: Lucy Liu <jliu176@gmail.com> --- doc/whats_new/upcoming_changes/array-api/33437.fix.rst | 5 +++++ .../upcoming_changes/sklearn.linear_model/33437.fix.rst | 5 +++++ sklearn/linear_model/_ridge.py | 5 ++++- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/33437.fix.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33437.fix.rst diff --git a/doc/whats_new/upcoming_changes/array-api/33437.fix.rst b/doc/whats_new/upcoming_changes/array-api/33437.fix.rst new file mode 100644 index 0000000000000..23d9f888f9dae --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/33437.fix.rst @@ -0,0 +1,5 @@ +- :func:`linear_model.ridge_regression` now correctly passes a Python scalar as + ``fill_value`` to ``xp.full`` when broadcasting alpha for multi-target + regression, ensuring compliance with the array API specification. This fixes + compatibility issues with some array API backends. + By :user:`Olivier Grisel <ogrisel>`. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33437.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33437.fix.rst new file mode 100644 index 0000000000000..23d9f888f9dae --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33437.fix.rst @@ -0,0 +1,5 @@ +- :func:`linear_model.ridge_regression` now correctly passes a Python scalar as + ``fill_value`` to ``xp.full`` when broadcasting alpha for multi-target + regression, ensuring compliance with the array API specification. This fixes + compatibility issues with some array API backends. + By :user:`Olivier Grisel <ogrisel>`. diff --git a/sklearn/linear_model/_ridge.py b/sklearn/linear_model/_ridge.py index bc8c892f66564..ee58aa85e2943 100644 --- a/sklearn/linear_model/_ridge.py +++ b/sklearn/linear_model/_ridge.py @@ -721,7 +721,10 @@ def _ridge_regression( if alpha.shape[0] == 1 and n_targets > 1: alpha = xp.full( - shape=(n_targets,), fill_value=alpha[0], dtype=alpha.dtype, device=device_ + shape=(n_targets,), + fill_value=float(alpha[0]), + dtype=alpha.dtype, + device=device_, ) n_iter = None From 0b8b02426355e08f67f4d579156ccb35e85d65e0 Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Wed, 4 Mar 2026 00:55:33 +0100 Subject: [PATCH 255/462] FIX remove changelog entry merged in by mistake (#33447) --- .../upcoming_changes/sklearn.linear_model/33437.fix.rst | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33437.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33437.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33437.fix.rst deleted file mode 100644 index 23d9f888f9dae..0000000000000 --- a/doc/whats_new/upcoming_changes/sklearn.linear_model/33437.fix.rst +++ /dev/null @@ -1,5 +0,0 @@ -- :func:`linear_model.ridge_regression` now correctly passes a Python scalar as - ``fill_value`` to ``xp.full`` when broadcasting alpha for multi-target - regression, ensuring compliance with the array API specification. This fixes - compatibility issues with some array API backends. - By :user:`Olivier Grisel <ogrisel>`. From ba3ea9bf623333551447e70b5f78904ea69232ff Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Thu, 5 Mar 2026 11:33:07 +0100 Subject: [PATCH 256/462] ENH make `_loss.link.py` array API compatible (#33345) Co-authored-by: Omar Salman <omar.salman2007@gmail.com> --- sklearn/_loss/link.py | 104 +++++++++++--------------- sklearn/_loss/tests/test_link.py | 81 +++++++++++++------- sklearn/utils/_array_api.py | 31 ++++++-- sklearn/utils/tests/test_array_api.py | 28 +++++++ 4 files changed, 150 insertions(+), 94 deletions(-) diff --git a/sklearn/_loss/link.py b/sklearn/_loss/link.py index 03677c8da6139..6a42e5508fad1 100644 --- a/sklearn/_loss/link.py +++ b/sklearn/_loss/link.py @@ -7,11 +7,11 @@ from abc import ABC, abstractmethod from dataclasses import dataclass +from math import ulp -import numpy as np -from scipy.special import expit, logit from scipy.stats import gmean +from sklearn.utils._array_api import _expit, _logit, get_namespace from sklearn.utils.extmath import softmax @@ -41,49 +41,50 @@ def includes(self, x): ------- result : bool """ + xp, _ = get_namespace(x) if self.low_inclusive: - low = np.greater_equal(x, self.low) + low = xp.greater_equal(x, self.low) else: - low = np.greater(x, self.low) + low = xp.greater(x, self.low) - if not np.all(low): + if not xp.all(low): return False if self.high_inclusive: - high = np.less_equal(x, self.high) + high = xp.less_equal(x, self.high) else: - high = np.less(x, self.high) + high = xp.less(x, self.high) # Note: np.all returns numpy.bool_ - return bool(np.all(high)) + return bool(xp.all(high)) -def _inclusive_low_high(interval, dtype=np.float64): +def _inclusive_low_high(interval): """Generate values low and high to be within the interval range. This is used in tests only. Returns ------- - low, high : tuple + low, high : tuple of floats The returned values low and high lie within the interval. """ - eps = 10 * np.finfo(dtype).eps - if interval.low == -np.inf: + eps = 10 * ulp(1) + if interval.low == -float("inf"): low = -1e10 elif interval.low < 0: low = interval.low * (1 - eps) + eps else: low = interval.low * (1 + eps) + eps - if interval.high == np.inf: + if interval.high == float("inf"): high = 1e10 elif interval.high < 0: high = interval.high * (1 + eps) - eps else: high = interval.high * (1 - eps) - eps - return low, high + return float(low), float(high) class BaseLink(ABC): @@ -105,11 +106,11 @@ class BaseLink(ABC): # Usually, raw_prediction may be any real number and y_pred is an open # interval. - # interval_raw_prediction = Interval(-np.inf, np.inf, False, False) - interval_y_pred = Interval(-np.inf, np.inf, False, False) + # interval_raw_prediction = Interval(-float("inf"), float("inf"), False, False) + interval_y_pred = Interval(-float("inf"), float("inf"), False, False) @abstractmethod - def link(self, y_pred, out=None): + def link(self, y_pred): """Compute the link function g(y_pred). The link function maps (predicted) target values to raw predictions, @@ -119,19 +120,15 @@ def link(self, y_pred, out=None): ---------- y_pred : array Predicted target values. - out : array - A location into which the result is stored. If provided, it must - have a shape that the inputs broadcast to. If not provided or None, - a freshly-allocated array is returned. Returns ------- - out : array + array Output array, element-wise link function. """ @abstractmethod - def inverse(self, raw_prediction, out=None): + def inverse(self, raw_prediction): """Compute the inverse link function h(raw_prediction). The inverse link function maps raw predictions to predicted target @@ -141,14 +138,10 @@ def inverse(self, raw_prediction, out=None): ---------- raw_prediction : array Raw prediction values (in link space). - out : array - A location into which the result is stored. If provided, it must - have a shape that the inputs broadcast to. If not provided or None, - a freshly-allocated array is returned. Returns ------- - out : array + array Output array, element-wise inverse link function. """ @@ -156,12 +149,8 @@ def inverse(self, raw_prediction, out=None): class IdentityLink(BaseLink): """The identity link function g(x)=x.""" - def link(self, y_pred, out=None): - if out is not None: - np.copyto(out, y_pred) - return out - else: - return y_pred + def link(self, y_pred): + return y_pred # TODO: Should we copy? inverse = link @@ -169,13 +158,15 @@ def link(self, y_pred, out=None): class LogLink(BaseLink): """The log link function g(x)=log(x).""" - interval_y_pred = Interval(0, np.inf, False, False) + interval_y_pred = Interval(0, float("inf"), False, False) - def link(self, y_pred, out=None): - return np.log(y_pred, out=out) + def link(self, y_pred): + xp, _ = get_namespace(y_pred) + return xp.log(y_pred) - def inverse(self, raw_prediction, out=None): - return np.exp(raw_prediction, out=out) + def inverse(self, raw_prediction): + xp, _ = get_namespace(raw_prediction) + return xp.exp(raw_prediction) class LogitLink(BaseLink): @@ -183,11 +174,11 @@ class LogitLink(BaseLink): interval_y_pred = Interval(0, 1, False, False) - def link(self, y_pred, out=None): - return logit(y_pred, out=out) + def link(self, y_pred): + return _logit(y_pred) - def inverse(self, raw_prediction, out=None): - return expit(raw_prediction, out=out) + def inverse(self, raw_prediction): + return _expit(raw_prediction) class HalfLogitLink(BaseLink): @@ -198,13 +189,11 @@ class HalfLogitLink(BaseLink): interval_y_pred = Interval(0, 1, False, False) - def link(self, y_pred, out=None): - out = logit(y_pred, out=out) - out *= 0.5 - return out + def link(self, y_pred): + return 0.5 * _logit(y_pred) - def inverse(self, raw_prediction, out=None): - return expit(2 * raw_prediction, out) + def inverse(self, raw_prediction): + return _expit(2 * raw_prediction) class MultinomialLogit(BaseLink): @@ -257,20 +246,17 @@ class MultinomialLogit(BaseLink): interval_y_pred = Interval(0, 1, False, False) def symmetrize_raw_prediction(self, raw_prediction): - return raw_prediction - np.mean(raw_prediction, axis=1)[:, np.newaxis] + xp, _ = get_namespace(raw_prediction) + return raw_prediction - xp.mean(raw_prediction, axis=1)[:, None] - def link(self, y_pred, out=None): + def link(self, y_pred): + xp, _ = get_namespace(y_pred) # geometric mean as reference category gm = gmean(y_pred, axis=1) - return np.log(y_pred / gm[:, np.newaxis], out=out) + return xp.log(y_pred / gm[:, None]) - def inverse(self, raw_prediction, out=None): - if out is None: - return softmax(raw_prediction, copy=True) - else: - np.copyto(out, raw_prediction) - softmax(out, copy=False) - return out + def inverse(self, raw_prediction): + return softmax(raw_prediction) _LINKS = { diff --git a/sklearn/_loss/tests/test_link.py b/sklearn/_loss/tests/test_link.py index e5a665f8d48ac..f85b223c6f1fb 100644 --- a/sklearn/_loss/tests/test_link.py +++ b/sklearn/_loss/tests/test_link.py @@ -1,7 +1,8 @@ import numpy as np import pytest -from numpy.testing import assert_allclose, assert_array_equal +from numpy.testing import assert_allclose +from sklearn import config_context from sklearn._loss.link import ( _LINKS, HalfLogitLink, @@ -9,6 +10,12 @@ MultinomialLogit, _inclusive_low_high, ) +from sklearn.utils._array_api import ( + _convert_to_numpy, + _get_namespace_device_dtype_ids, + yield_namespace_device_dtype_combinations, +) +from sklearn.utils._testing import _array_api_for_tests LINK_FUNCTIONS = list(_LINKS.values()) @@ -28,10 +35,10 @@ def test_interval_raises(): Interval(0, 1, False, True), Interval(0, 1, True, False), Interval(0, 1, True, True), - Interval(-np.inf, np.inf, False, False), - Interval(-np.inf, np.inf, False, True), - Interval(-np.inf, np.inf, True, False), - Interval(-np.inf, np.inf, True, True), + Interval(-float("inf"), float("inf"), False, False), + Interval(-float("inf"), float("inf"), False, True), + Interval(-float("inf"), float("inf"), True, False), + Interval(-float("inf"), float("inf"), True, True), Interval(-10, -1, False, False), Interval(-10, -1, False, True), Interval(-10, -1, True, False), @@ -39,10 +46,10 @@ def test_interval_raises(): ], ) def test_is_in_range(interval): - # make sure low and high are always within the interval, used for linspace + """Test that low and high are always within the interval used for linspace.""" low, high = _inclusive_low_high(interval) - x = np.linspace(low, high, num=10) + assert interval.includes(x) # x contains lower bound @@ -59,7 +66,7 @@ def test_is_in_range(interval): @pytest.mark.parametrize("link", LINK_FUNCTIONS) def test_link_inverse_identity(link, global_random_seed): - # Test that link of inverse gives identity. + """Test that link of inverse gives identity.""" rng = np.random.RandomState(global_random_seed) link = link() n_samples, n_classes = 100, None @@ -81,31 +88,51 @@ def test_link_inverse_identity(link, global_random_seed): assert_allclose(link.inverse(link.link(y_pred)), y_pred) +@pytest.mark.parametrize( + "namespace, device, dtype_name", + yield_namespace_device_dtype_combinations(), + ids=_get_namespace_device_dtype_ids, +) @pytest.mark.parametrize("link", LINK_FUNCTIONS) -def test_link_out_argument(link): - # Test that out argument gets assigned the result. - rng = np.random.RandomState(42) +def test_link_inverse_array_api( + namespace, device, dtype_name, link, global_random_seed +): + """Test that link and inverse link give same result for array API inputs.""" + rng = np.random.RandomState(global_random_seed) link = link() n_samples, n_classes = 100, None + # The values for `raw_prediction` are limited from -20 to 20 because in the + # class `LogitLink` the term `expit(x)` comes very close to 1 for large + # positive x and therefore loses precision. if link.is_multiclass: n_classes = 10 - raw_prediction = rng.normal(loc=0, scale=10, size=(n_samples, n_classes)) + raw_prediction = rng.uniform(low=-20, high=20, size=(n_samples, n_classes)) if isinstance(link, MultinomialLogit): raw_prediction = link.symmetrize_raw_prediction(raw_prediction) - else: - # So far, the valid interval of raw_prediction is (-inf, inf) and - # we do not need to distinguish. + elif isinstance(link, HalfLogitLink): raw_prediction = rng.uniform(low=-10, high=10, size=(n_samples)) + else: + raw_prediction = rng.uniform(low=-20, high=20, size=(n_samples)) - y_pred = link.inverse(raw_prediction, out=None) - out = np.empty_like(raw_prediction) - y_pred_2 = link.inverse(raw_prediction, out=out) - assert_allclose(y_pred, out) - assert_array_equal(out, y_pred_2) - assert np.shares_memory(out, y_pred_2) - - out = np.empty_like(y_pred) - raw_prediction_2 = link.link(y_pred, out=out) - assert_allclose(raw_prediction, out) - assert_array_equal(out, raw_prediction_2) - assert np.shares_memory(out, raw_prediction_2) + xp = _array_api_for_tests(namespace, device) + if dtype_name != "float64": + raw_prediction *= 0.5 # avoid overflow + rtol = 1e-3 if n_classes else 1e-4 + else: + rtol = 1e-8 + + with config_context(array_api_dispatch=True): + raw_prediction_xp = xp.asarray(raw_prediction.astype(dtype_name), device=device) + assert_allclose( + _convert_to_numpy(link.inverse(raw_prediction_xp), xp=xp), + link.inverse(raw_prediction), + rtol=rtol, + ) + + y_pred = link.inverse(raw_prediction) + y_pred_xp = xp.asarray(y_pred.astype(dtype_name), device=device) + assert_allclose( + _convert_to_numpy(link.link(y_pred_xp), xp=xp), + link.link(y_pred), + rtol=rtol, + ) diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 020a758589713..0bd1869695952 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -591,18 +591,33 @@ def move_to(*arrays, xp, device): ) -def _expit(X, out=None, xp=None): +def _expit(x, out=None, xp=None): # The out argument for exp and hence expit is only supported for numpy, # but not in the Array API specification. - xp, _ = get_namespace(X, xp=xp) + xp, _ = get_namespace(x, xp=xp) if _is_numpy_namespace(xp): - if out is not None: - special.expit(X, out=out) - else: - out = special.expit(X) - return out + return special.expit(x, out=out) + + return 1.0 / (1.0 + xp.exp(-x)) - return 1.0 / (1.0 + xp.exp(-X)) + +def _logit(x, out=None, xp=None): + # The out argument for log and hence logit is only supported for numpy, + # but not in the Array API specification. + xp, _ = get_namespace(x, xp=xp) + if _is_numpy_namespace(xp): + return special.logit(x, out=out) + + # See https://github.com/scipy/xsf/blob/e0c4d22d6ae768b39efc69586f1e8d5560a32fc5/include/xsf/log_exp.h#L30 + def logit_v2(x): + s = 2 * (x - 0.5) + return xp.log1p(s) - xp.log1p(-s) + + return xp.where( + xp.logical_or(x < 0.3, x > 0.65), + xp.log(x / (1 - x)), + logit_v2(x), + ) def _validate_diagonal_args(array, value, xp): diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index b300bd5aeebc6..e1abb40fc7a51 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -6,6 +6,7 @@ import scipy import scipy.sparse as sp from numpy.testing import assert_allclose +from scipy.special import expit, logit from sklearn._config import config_context from sklearn._loss import HalfMultinomialLoss @@ -18,11 +19,13 @@ _convert_to_numpy, _count_nonzero, _estimator_with_converted_arrays, + _expit, _fill_diagonal, _get_namespace_device_dtype_ids, _half_multinomial_loss, _is_numpy_namespace, _isin, + _logit, _logsumexp, _matching_numpy_dtype, _max_precision_float_dtype, @@ -824,6 +827,31 @@ def test_median(namespace, device, dtype_name, axis): assert_allclose(result_np, _convert_to_numpy(result_xp, xp=xp)) +@pytest.mark.parametrize( + "namespace, device, dtype_name", yield_namespace_device_dtype_combinations() +) +def test_expit_logit(namespace, device, dtype_name): + rtol = 1e-6 if "float32" in str(dtype_name) else 1e-12 + xp = _array_api_for_tests(namespace, device) + + with config_context(array_api_dispatch=True): + x_np = numpy.linspace(-20, 20, 1000).astype(dtype_name) + x_xp = xp.asarray(x_np, device=device) + assert_allclose( + _convert_to_numpy(_expit(x_xp), xp=xp), + expit(x_np), + rtol=rtol, + ) + + x_np = numpy.linspace(0, 1, 1000).astype(dtype_name) + x_xp = xp.asarray(x_np, device=device) + assert_allclose( + _convert_to_numpy(_logit(x_xp), xp=xp), + logit(x_np), + rtol=rtol, + ) + + @pytest.mark.parametrize( "array_namespace, device_, dtype_name", yield_namespace_device_dtype_combinations() ) From 33b51a63cc06c64ac31a872269f19957b1238d6e Mon Sep 17 00:00:00 2001 From: Arthur Lacote <arthur.lcte@gmail.com> Date: Thu, 5 Mar 2026 13:41:31 +0100 Subject: [PATCH 257/462] FEA Add support for missing values in tree estimators with `criterion="absolute_error"` by greatly simplifying the logic (#32119) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> Co-authored-by: Christian Lorentzen <lorentzen.ch@gmail.com> --- doc/modules/tree.rst | 4 - .../sklearn.tree/32119.feature.rst | 4 + .../sklearn.tree/32119.fix.rst | 6 + sklearn/ensemble/tests/test_forest.py | 90 +++-- sklearn/tree/_classes.py | 34 +- sklearn/tree/_criterion.pxd | 7 - sklearn/tree/_criterion.pyx | 211 ++-------- sklearn/tree/_partitioner.pxd | 46 +-- sklearn/tree/_partitioner.pyx | 365 ++++++++++-------- sklearn/tree/_splitter.pxd | 2 +- sklearn/tree/_splitter.pyx | 121 ++---- sklearn/tree/tests/test_split.py | 5 - sklearn/tree/tests/test_swap.py | 43 +++ sklearn/tree/tests/test_tree.py | 72 ++-- 14 files changed, 435 insertions(+), 575 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/32119.feature.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/32119.fix.rst create mode 100644 sklearn/tree/tests/test_swap.py diff --git a/doc/modules/tree.rst b/doc/modules/tree.rst index 4f0d26a9dfbfb..d0335cd2f6b89 100644 --- a/doc/modules/tree.rst +++ b/doc/modules/tree.rst @@ -647,10 +647,6 @@ support for missing values for `splitter='random'`, where the splits are determined randomly. For more details on how the splitter differs on non-missing values, see the :ref:`Forest section <forest>`. -The criterion supported when there are missing values are -`'gini'`, `'entropy'`, or `'log_loss'`, for classification or -`'squared_error'` or `'poisson'` for regression. - First we will describe how :class:`DecisionTreeClassifier`, :class:`DecisionTreeRegressor` handle missing-values in the data. diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/32119.feature.rst b/doc/whats_new/upcoming_changes/sklearn.tree/32119.feature.rst new file mode 100644 index 0000000000000..73a7251fce13b --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.tree/32119.feature.rst @@ -0,0 +1,4 @@ +- In :class:`tree.DecisionTreeRegressor` and :class:`ensemble.RandomForestRegressor`, + `criterion="absolute_error"` — and, consequently, all criterion options — + now support missing values for dense training data `X`. + By :user:`Arthur Lacote <cakedev0>` diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/32119.fix.rst b/doc/whats_new/upcoming_changes/sklearn.tree/32119.fix.rst new file mode 100644 index 0000000000000..d512560566fb1 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.tree/32119.fix.rst @@ -0,0 +1,6 @@ +- Fix calculation of node impurity in :class:`tree.DecisionTreeRegressor`, + :class:`ensemble.RandomForestRegressor`, :class:`ExtraTreeRegressor` and + :class:`ExtraTreesRegressor` when missing values are present for the Poisson + criterion. The Poisson criterion was returning invalid impurities (including + negative values) when missing values were present. + By :user:`Arthur Lacote <cakedev0>` diff --git a/sklearn/ensemble/tests/test_forest.py b/sklearn/ensemble/tests/test_forest.py index 7d6283300a256..7a0b27b66b327 100644 --- a/sklearn/ensemble/tests/test_forest.py +++ b/sklearn/ensemble/tests/test_forest.py @@ -21,7 +21,7 @@ import sklearn from sklearn import clone, datasets -from sklearn.datasets import make_classification, make_hastie_10_2 +from sklearn.datasets import make_classification, make_hastie_10_2, make_regression from sklearn.decomposition import TruncatedSVD from sklearn.dummy import DummyRegressor from sklearn.ensemble import ( @@ -115,6 +115,9 @@ FOREST_CLASSIFIERS_REGRESSORS: Dict[str, Any] = FOREST_CLASSIFIERS.copy() FOREST_CLASSIFIERS_REGRESSORS.update(FOREST_REGRESSORS) +CLF_CRITERIONS = ("gini", "log_loss") +REG_CRITERIONS = ("squared_error", "absolute_error", "friedman_mse", "poisson") + @pytest.mark.parametrize("name", FOREST_CLASSIFIERS) def test_classification_toy(name): @@ -1829,22 +1832,26 @@ def test_estimators_samples(ForestClass, bootstrap, seed): assert_allclose(orig_tree_values, new_tree_values) +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize( - "make_data, Forest", + "Forest, criterion", [ - (datasets.make_regression, RandomForestRegressor), - (datasets.make_classification, RandomForestClassifier), - (datasets.make_regression, ExtraTreesRegressor), - (datasets.make_classification, ExtraTreesClassifier), + *product(FOREST_REGRESSORS.values(), REG_CRITERIONS), + *product(FOREST_CLASSIFIERS.values(), CLF_CRITERIONS), ], ) -def test_missing_values_is_resilient(make_data, Forest): +def test_missing_values_is_resilient(Forest, criterion): """Check that forest can deal with missing values and has decent performance.""" - - rng = np.random.RandomState(0) - n_samples, n_features = 1000, 10 + rng = np.random.RandomState(np.random.randint(0, 100000)) + n_samples, n_features = 500, 5 + make_data = make_regression if criterion in REG_CRITERIONS else make_classification X, y = make_data(n_samples=n_samples, n_features=n_features, random_state=rng) + # Make y non-negative for Poisson criterion + if criterion == "poisson": + y -= np.min(y) + # Create dataset with missing values X_missing = X.copy() X_missing[rng.choice([False, True], size=X.shape, p=[0.95, 0.05])] = np.nan @@ -1855,13 +1862,13 @@ def test_missing_values_is_resilient(make_data, Forest): ) # Train forest with missing values - forest_with_missing = Forest(random_state=rng, n_estimators=50) + forest_with_missing = Forest(random_state=rng, criterion=criterion, n_estimators=50) forest_with_missing.fit(X_missing_train, y_train) score_with_missing = forest_with_missing.score(X_missing_test, y_test) # Train forest without missing values X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0) - forest = Forest(random_state=rng, n_estimators=50) + forest = Forest(random_state=rng, criterion=criterion, n_estimators=50) forest.fit(X_train, y_train) score_without_missing = forest.score(X_test, y_test) @@ -1869,36 +1876,36 @@ def test_missing_values_is_resilient(make_data, Forest): assert score_with_missing >= 0.80 * score_without_missing +# TODO(1.11): remove the deprecated friedman_mse criterion parametrization +@pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize( - "Forest", + "Forest, criterion", [ - RandomForestClassifier, - RandomForestRegressor, - ExtraTreesRegressor, - ExtraTreesClassifier, + *product(FOREST_REGRESSORS.values(), REG_CRITERIONS), + *product(FOREST_CLASSIFIERS.values(), CLF_CRITERIONS), ], ) -def test_missing_value_is_predictive(Forest): +def test_missing_value_is_predictive(Forest, criterion, global_random_seed): """Check that the forest learns when missing values are only present for a predictive feature.""" - rng = np.random.RandomState(0) - n_samples = 300 - expected_score = 0.75 + rng = np.random.RandomState(global_random_seed) + n_samples = 1000 + expected_score_gap = 0.3 + # Require a minimum 0.3 gap between `forest_predictive` and + # `forest_non_predictive`: meaningful for R2/accuracy, but robust in tests. - X_non_predictive = rng.standard_normal(size=(n_samples, 10)) - y = rng.randint(0, high=2, size=n_samples) + X_non_predictive = rng.randn(n_samples, 2) + y = rng.rand(n_samples) < 0.5 # Create a predictive feature using `y` and with some noise - X_random_mask = rng.choice([False, True], size=n_samples, p=[0.95, 0.05]) - y_mask = y.astype(bool) - y_mask[X_random_mask] = ~y_mask[X_random_mask] - - predictive_feature = rng.standard_normal(size=n_samples) - predictive_feature[y_mask] = np.nan + predictive_feature = rng.randn(n_samples) + noise_mask = rng.rand(n_samples) < 0.05 + # nan/non-nan indicates y is 1/0, except if noise_mask is true: + predictive_feature[y ^ noise_mask] = np.nan assert np.isnan(predictive_feature).any() X_predictive = X_non_predictive.copy() - X_predictive[:, 5] = predictive_feature + X_predictive[:, 1] = predictive_feature ( X_predictive_train, @@ -1908,28 +1915,17 @@ def test_missing_value_is_predictive(Forest): y_train, y_test, ) = train_test_split(X_predictive, X_non_predictive, y, random_state=0) - forest_predictive = Forest(random_state=0).fit(X_predictive_train, y_train) - forest_non_predictive = Forest(random_state=0).fit(X_non_predictive_train, y_train) + forest_predictive = Forest(random_state=0, criterion=criterion) + forest_predictive.fit(X_predictive_train, y_train) + forest_non_predictive = Forest(random_state=0, criterion=criterion) + forest_non_predictive.fit(X_non_predictive_train, y_train) predictive_test_score = forest_predictive.score(X_predictive_test, y_test) - - assert predictive_test_score >= expected_score - assert predictive_test_score >= forest_non_predictive.score( + non_predictive_test_score = forest_non_predictive.score( X_non_predictive_test, y_test ) - -@pytest.mark.parametrize("Forest", FOREST_REGRESSORS.values()) -def test_non_supported_criterion_raises_error_with_missing_values(Forest): - """Raise error for unsupported criterion when there are missing values.""" - X = np.array([[0, 1, 2], [np.nan, 0, 2.0]]) - y = [0.5, 1.0] - - forest = Forest(criterion="absolute_error") - - msg = ".*does not accept missing values" - with pytest.raises(ValueError, match=msg): - forest.fit(X, y) + assert predictive_test_score >= non_predictive_test_score + expected_score_gap # TODO(1.11): remove test with the deprecation of friedman_mse criterion diff --git a/sklearn/tree/_classes.py b/sklearn/tree/_classes.py index dc83aa7d3daea..7410fd91c89e8 100644 --- a/sklearn/tree/_classes.py +++ b/sklearn/tree/_classes.py @@ -1098,15 +1098,10 @@ def predict_log_proba(self, X): def __sklearn_tags__(self): tags = super().__sklearn_tags__() - # XXX: nan is only supported for dense arrays, but we set this for + # XXX: nan values are only accepted in dense arrays, but we set this for # common test to pass, specifically: check_estimators_nan_inf - allow_nan = self.splitter in ("best", "random") and self.criterion in { - "gini", - "log_loss", - "entropy", - } + tags.input_tags.allow_nan = True tags.classifier_tags.multi_label = True - tags.input_tags.allow_nan = allow_nan return tags @@ -1452,13 +1447,9 @@ def _compute_partial_dependence_recursion(self, grid, target_features): def __sklearn_tags__(self): tags = super().__sklearn_tags__() - # XXX: nan is only supported for dense arrays, but we set this for - # common test to pass, specifically: check_estimators_nan_inf - allow_nan = self.splitter in ("best", "random") and self.criterion in { - "squared_error", - "poisson", - } - tags.input_tags.allow_nan = allow_nan + # XXX: nan values are only accepted in dense arrays, but we set this for + # for common test to pass, specifically: check_estimators_nan_inf + tags.input_tags.allow_nan = True return tags @@ -1739,13 +1730,9 @@ def __init__( def __sklearn_tags__(self): tags = super().__sklearn_tags__() - # XXX: nan is only supported for dense arrays, but we set this for the + # XXX: nan values are only accepted in dense arrays, but we set this for # common test to pass, specifically: check_estimators_nan_inf - allow_nan = self.splitter == "random" and self.criterion in { - "gini", - "log_loss", - "entropy", - } + allow_nan = self.splitter == "random" tags.classifier_tags.multi_label = True tags.input_tags.allow_nan = allow_nan return tags @@ -1999,11 +1986,8 @@ def __init__( def __sklearn_tags__(self): tags = super().__sklearn_tags__() - # XXX: nan is only supported for dense arrays, but we set this for the + # XXX: nan values are only accepted in dense arrays, but we set this for # common test to pass, specifically: check_estimators_nan_inf - allow_nan = self.splitter == "random" and self.criterion in { - "squared_error", - "poisson", - } + allow_nan = self.splitter == "random" tags.input_tags.allow_nan = allow_nan return tags diff --git a/sklearn/tree/_criterion.pxd b/sklearn/tree/_criterion.pxd index fa8583b85f4a2..f67516c11381f 100644 --- a/sklearn/tree/_criterion.pxd +++ b/sklearn/tree/_criterion.pxd @@ -18,8 +18,6 @@ cdef class Criterion: cdef intp_t start # samples[start:pos] are the samples in the left node cdef intp_t pos # samples[pos:end] are the samples in the right node cdef intp_t end - cdef intp_t n_missing # Number of missing values for the feature being evaluated - cdef bint missing_go_to_left # Whether missing values go to the left node cdef intp_t n_outputs # Number of outputs cdef intp_t n_samples # Number of samples @@ -28,7 +26,6 @@ cdef class Criterion: cdef float64_t weighted_n_node_samples # Weighted number of samples in the node cdef float64_t weighted_n_left # Weighted number of samples in the left node cdef float64_t weighted_n_right # Weighted number of samples in the right node - cdef float64_t weighted_n_missing # Weighted number of samples that are missing # The criterion object is maintained such that left and right collected # statistics correspond to samples[start:pos] and samples[pos:end]. @@ -43,8 +40,6 @@ cdef class Criterion: intp_t start, intp_t end ) except -1 nogil - cdef void init_sum_missing(self) - cdef void init_missing(self, intp_t n_missing) noexcept nogil cdef int reset(self) except -1 nogil cdef int reverse_reset(self) except -1 nogil cdef int update(self, intp_t new_pos) except -1 nogil @@ -96,7 +91,6 @@ cdef class ClassificationCriterion(Criterion): cdef float64_t[:, ::1] sum_total # The sum of the weighted count of each label. cdef float64_t[:, ::1] sum_left # Same as above, but for the left side of the split cdef float64_t[:, ::1] sum_right # Same as above, but for the right side of the split - cdef float64_t[:, ::1] sum_missing # Same as above, but for missing values in X cdef class RegressionCriterion(Criterion): """Abstract regression criterion.""" @@ -106,4 +100,3 @@ cdef class RegressionCriterion(Criterion): cdef float64_t[::1] sum_total # The sum of w*y. cdef float64_t[::1] sum_left # Same as above, but for the left side of the split cdef float64_t[::1] sum_right # Same as above, but for the right side of the split - cdef float64_t[::1] sum_missing # Same as above, but for missing values in X diff --git a/sklearn/tree/_criterion.pyx b/sklearn/tree/_criterion.pyx index 19c0d9b03c743..d3258169cd4ca 100644 --- a/sklearn/tree/_criterion.pyx +++ b/sklearn/tree/_criterion.pyx @@ -64,19 +64,6 @@ cdef class Criterion: """ pass - cdef void init_missing(self, intp_t n_missing) noexcept nogil: - """Initialize sum_missing if there are missing values. - - This method assumes that caller placed the missing samples in - self.sample_indices[-n_missing:] - - Parameters - ---------- - n_missing: intp_t - Number of missing values for specific feature. - """ - pass - cdef int reset(self) except -1 nogil: """Reset the criterion at pos=start. @@ -241,8 +228,6 @@ cdef class Criterion: ) return check_lower_bound & check_upper_bound & check_monotonic_cst - cdef void init_sum_missing(self): - """Init sum_missing to hold sums for missing values.""" cdef inline void _move_sums_classification( ClassificationCriterion criterion, @@ -250,40 +235,19 @@ cdef inline void _move_sums_classification( float64_t[:, ::1] sum_2, float64_t* weighted_n_1, float64_t* weighted_n_2, - bint put_missing_in_1, ) noexcept nogil: - """Distribute sum_total and sum_missing into sum_1 and sum_2. - - If there are missing values and: - - put_missing_in_1 is True, then missing values to go sum_1. Specifically: - sum_1 = sum_missing - sum_2 = sum_total - sum_missing - - - put_missing_in_1 is False, then missing values go to sum_2. Specifically: - sum_1 = 0 - sum_2 = sum_total + """Distribute sum_total into sum_1 and sum_2. """ - cdef intp_t k, c, n_bytes - if criterion.n_missing != 0 and put_missing_in_1: - for k in range(criterion.n_outputs): - n_bytes = criterion.n_classes[k] * sizeof(float64_t) - memcpy(&sum_1[k, 0], &criterion.sum_missing[k, 0], n_bytes) - - for k in range(criterion.n_outputs): - for c in range(criterion.n_classes[k]): - sum_2[k, c] = criterion.sum_total[k, c] - criterion.sum_missing[k, c] - - weighted_n_1[0] = criterion.weighted_n_missing - weighted_n_2[0] = criterion.weighted_n_node_samples - criterion.weighted_n_missing - else: - # Assigning sum_2 = sum_total for all outputs. - for k in range(criterion.n_outputs): - n_bytes = criterion.n_classes[k] * sizeof(float64_t) - memset(&sum_1[k, 0], 0, n_bytes) - memcpy(&sum_2[k, 0], &criterion.sum_total[k, 0], n_bytes) + cdef intp_t k, n_bytes - weighted_n_1[0] = 0.0 - weighted_n_2[0] = criterion.weighted_n_node_samples + # Assigning sum_2 = sum_total for all outputs. + for k in range(criterion.n_outputs): + n_bytes = criterion.n_classes[k] * sizeof(float64_t) + memset(&sum_1[k, 0], 0, n_bytes) + memcpy(&sum_2[k, 0], &criterion.sum_total[k, 0], n_bytes) + + weighted_n_1[0] = 0.0 + weighted_n_2[0] = criterion.weighted_n_node_samples cdef class ClassificationCriterion(Criterion): @@ -303,7 +267,6 @@ cdef class ClassificationCriterion(Criterion): self.start = 0 self.pos = 0 self.end = 0 - self.missing_go_to_left = 0 self.n_outputs = n_outputs self.n_samples = 0 @@ -311,7 +274,6 @@ cdef class ClassificationCriterion(Criterion): self.weighted_n_node_samples = 0.0 self.weighted_n_left = 0.0 self.weighted_n_right = 0.0 - self.weighted_n_missing = 0.0 self.n_classes = np.empty(n_outputs, dtype=np.intp) @@ -407,39 +369,6 @@ cdef class ClassificationCriterion(Criterion): self.reset() return 0 - cdef void init_sum_missing(self): - """Init sum_missing to hold sums for missing values.""" - self.sum_missing = np.zeros((self.n_outputs, self.max_n_classes), dtype=np.float64) - - cdef void init_missing(self, intp_t n_missing) noexcept nogil: - """Initialize sum_missing if there are missing values. - - This method assumes that caller placed the missing samples in - self.sample_indices[-n_missing:] - """ - cdef intp_t i, p, k, c - cdef float64_t w = 1.0 - - self.n_missing = n_missing - if n_missing == 0: - return - - memset(&self.sum_missing[0, 0], 0, self.max_n_classes * self.n_outputs * sizeof(float64_t)) - - self.weighted_n_missing = 0.0 - - # The missing samples are assumed to be in self.sample_indices[-n_missing:] - for p in range(self.end - n_missing, self.end): - i = self.sample_indices[p] - if self.sample_weight is not None: - w = self.sample_weight[i] - - for k in range(self.n_outputs): - c = <intp_t> self.y[i, k] - self.sum_missing[k, c] += w - - self.weighted_n_missing += w - cdef int reset(self) except -1 nogil: """Reset the criterion at pos=start. @@ -453,7 +382,6 @@ cdef class ClassificationCriterion(Criterion): self.sum_right, &self.weighted_n_left, &self.weighted_n_right, - self.missing_go_to_left, ) return 0 @@ -470,7 +398,6 @@ cdef class ClassificationCriterion(Criterion): self.sum_left, &self.weighted_n_right, &self.weighted_n_left, - not self.missing_go_to_left ) return 0 @@ -487,10 +414,7 @@ cdef class ClassificationCriterion(Criterion): child to the left child. """ cdef intp_t pos = self.pos - # The missing samples are assumed to be in - # self.sample_indices[-self.n_missing:] that is - # self.sample_indices[end_non_missing:self.end]. - cdef intp_t end_non_missing = self.end - self.n_missing + cdef intp_t i cdef intp_t p cdef intp_t k @@ -500,11 +424,11 @@ cdef class ClassificationCriterion(Criterion): # Update statistics up to new_pos # # Given that - # sum_left[x] + sum_right[x] = sum_total[x] + # sum_left[x] + sum_right[x] = sum_total[x] # and that sum_total is known, we are going to update # sum_left from the direction that require the least amount # of computations, i.e. from pos to new_pos or from end to new_po. - if (new_pos - pos) <= (end_non_missing - new_pos): + if (new_pos - pos) <= (self.end - new_pos): for p in range(pos, new_pos): i = self.sample_indices[p] @@ -519,7 +443,7 @@ cdef class ClassificationCriterion(Criterion): else: self.reverse_reset() - for p in range(end_non_missing - 1, new_pos - 1, -1): + for p in range(self.end - 1, new_pos - 1, -1): i = self.sample_indices[p] if self.sample_weight is not None: @@ -769,36 +693,15 @@ cdef inline void _move_sums_regression( float64_t[::1] sum_2, float64_t* weighted_n_1, float64_t* weighted_n_2, - bint put_missing_in_1, ) noexcept nogil: - """Distribute sum_total and sum_missing into sum_1 and sum_2. - - If there are missing values and: - - put_missing_in_1 is True, then missing values to go sum_1. Specifically: - sum_1 = sum_missing - sum_2 = sum_total - sum_missing + """Distribute sum_total into sum_1 and sum_2.""" + cdef intp_t n_bytes = criterion.n_outputs * sizeof(float64_t) - - put_missing_in_1 is False, then missing values go to sum_2. Specifically: - sum_1 = 0 - sum_2 = sum_total - """ - cdef: - intp_t i - intp_t n_bytes = criterion.n_outputs * sizeof(float64_t) - bint has_missing = criterion.n_missing != 0 - - if has_missing and put_missing_in_1: - memcpy(&sum_1[0], &criterion.sum_missing[0], n_bytes) - for i in range(criterion.n_outputs): - sum_2[i] = criterion.sum_total[i] - criterion.sum_missing[i] - weighted_n_1[0] = criterion.weighted_n_missing - weighted_n_2[0] = criterion.weighted_n_node_samples - criterion.weighted_n_missing - else: - memset(&sum_1[0], 0, n_bytes) - # Assigning sum_2 = sum_total for all outputs. - memcpy(&sum_2[0], &criterion.sum_total[0], n_bytes) - weighted_n_1[0] = 0.0 - weighted_n_2[0] = criterion.weighted_n_node_samples + memset(&sum_1[0], 0, n_bytes) + # Assigning sum_2 = sum_total for all outputs. + memcpy(&sum_2[0], &criterion.sum_total[0], n_bytes) + weighted_n_1[0] = 0.0 + weighted_n_2[0] = criterion.weighted_n_node_samples cdef class RegressionCriterion(Criterion): @@ -835,7 +738,6 @@ cdef class RegressionCriterion(Criterion): self.weighted_n_node_samples = 0.0 self.weighted_n_left = 0.0 self.weighted_n_right = 0.0 - self.weighted_n_missing = 0.0 self.sq_sum_total = 0.0 @@ -897,42 +799,6 @@ cdef class RegressionCriterion(Criterion): self.reset() return 0 - cdef void init_sum_missing(self): - """Init sum_missing to hold sums for missing values.""" - self.sum_missing = np.zeros(self.n_outputs, dtype=np.float64) - - cdef void init_missing(self, intp_t n_missing) noexcept nogil: - """Initialize sum_missing if there are missing values. - - This method assumes that caller placed the missing samples in - self.sample_indices[-n_missing:] - """ - cdef intp_t i, p, k - cdef float64_t y_ik - cdef float64_t w_y_ik - cdef float64_t w = 1.0 - - self.n_missing = n_missing - if n_missing == 0: - return - - memset(&self.sum_missing[0], 0, self.n_outputs * sizeof(float64_t)) - - self.weighted_n_missing = 0.0 - - # The missing samples are assumed to be in self.sample_indices[-n_missing:] - for p in range(self.end - n_missing, self.end): - i = self.sample_indices[p] - if self.sample_weight is not None: - w = self.sample_weight[i] - - for k in range(self.n_outputs): - y_ik = self.y[i, k] - w_y_ik = w * y_ik - self.sum_missing[k] += w_y_ik - - self.weighted_n_missing += w - cdef int reset(self) except -1 nogil: """Reset the criterion at pos=start.""" self.pos = self.start @@ -942,7 +808,6 @@ cdef class RegressionCriterion(Criterion): self.sum_right, &self.weighted_n_left, &self.weighted_n_right, - self.missing_go_to_left ) return 0 @@ -955,7 +820,6 @@ cdef class RegressionCriterion(Criterion): self.sum_left, &self.weighted_n_right, &self.weighted_n_left, - not self.missing_go_to_left ) return 0 @@ -963,10 +827,6 @@ cdef class RegressionCriterion(Criterion): """Updated statistics by moving sample_indices[pos:new_pos] to the left.""" cdef intp_t pos = self.pos - # The missing samples are assumed to be in - # self.sample_indices[-self.n_missing:] that is - # self.sample_indices[end_non_missing:self.end]. - cdef intp_t end_non_missing = self.end - self.n_missing cdef intp_t i cdef intp_t p cdef intp_t k @@ -979,7 +839,7 @@ cdef class RegressionCriterion(Criterion): # and that sum_total is known, we are going to update # sum_left from the direction that require the least amount # of computations, i.e. from pos to new_pos or from end to new_pos. - if (new_pos - pos) <= (end_non_missing - new_pos): + if (new_pos - pos) <= (self.end - new_pos): for p in range(pos, new_pos): i = self.sample_indices[p] @@ -993,7 +853,7 @@ cdef class RegressionCriterion(Criterion): else: self.reverse_reset() - for p in range(end_non_missing - 1, new_pos - 1, -1): + for p in range(self.end - 1, new_pos - 1, -1): i = self.sample_indices[p] if self.sample_weight is not None: @@ -1134,8 +994,6 @@ cdef class MSE(RegressionCriterion): cdef intp_t k cdef float64_t w = 1.0 - cdef intp_t end_non_missing - for p in range(start, pos): i = sample_indices[p] @@ -1146,22 +1004,6 @@ cdef class MSE(RegressionCriterion): y_ik = self.y[i, k] sq_sum_left += w * y_ik * y_ik - if self.missing_go_to_left: - # add up the impact of these missing values on the left child - # statistics. - # Note: this only impacts the square sum as the sum - # is modified elsewhere. - end_non_missing = self.end - self.n_missing - - for p in range(end_non_missing, self.end): - i = sample_indices[p] - if sample_weight is not None: - w = sample_weight[i] - - for k in range(self.n_outputs): - y_ik = self.y[i, k] - sq_sum_left += w * y_ik * y_ik - sq_sum_right = self.sq_sum_total - sq_sum_left impurity_left[0] = sq_sum_left / self.weighted_n_left @@ -1501,13 +1343,6 @@ cdef class MAE(Criterion): self.reset() return 0 - cdef void init_missing(self, intp_t n_missing) noexcept nogil: - """Raise error if n_missing != 0.""" - if n_missing == 0: - return - with gil: - raise ValueError("missing values is not supported for MAE.") - cdef int reset(self) except -1 nogil: """Reset the criterion at pos=start. diff --git a/sklearn/tree/_partitioner.pxd b/sklearn/tree/_partitioner.pxd index 6590b8ed585f1..8dca0f78823e2 100644 --- a/sklearn/tree/_partitioner.pxd +++ b/sklearn/tree/_partitioner.pxd @@ -49,7 +49,8 @@ cdef const float32_t FEATURE_THRESHOLD = 1e-7 # cdef void next_p( # self, # intp_t* p_prev, -# intp_t* p +# intp_t* p, +# bint missing_go_to_left # ) noexcept nogil # cdef intp_t partition_samples( # self, @@ -57,10 +58,7 @@ cdef const float32_t FEATURE_THRESHOLD = 1e-7 # ) noexcept nogil # cdef void partition_samples_final( # self, -# intp_t best_pos, -# float64_t best_threshold, -# intp_t best_feature, -# intp_t n_missing, +# const SplitRecord* best_split, # ) noexcept nogil @@ -76,10 +74,12 @@ cdef class DensePartitioner: cdef intp_t end cdef intp_t n_missing cdef const uint8_t[::1] missing_values_in_feature_mask + cdef char[::1] swap_buffer cdef void sort_samples_and_feature_values( self, intp_t current_feature ) noexcept nogil + cdef void shift_missing_to_the_left(self) noexcept nogil cdef void init_node_split( self, intp_t start, @@ -94,18 +94,17 @@ cdef class DensePartitioner: cdef void next_p( self, intp_t* p_prev, - intp_t* p + intp_t* p, + bint missing_go_to_left ) noexcept nogil cdef intp_t partition_samples( self, - float64_t current_threshold + float64_t current_threshold, + bint missing_go_to_left ) noexcept nogil cdef void partition_samples_final( self, - intp_t best_pos, - float64_t best_threshold, - intp_t best_feature, - intp_t n_missing, + const SplitRecord* best_split, ) noexcept nogil @@ -134,6 +133,7 @@ cdef class SparsePartitioner: cdef void sort_samples_and_feature_values( self, intp_t current_feature ) noexcept nogil + cdef void shift_missing_to_the_left(self) noexcept nogil cdef void init_node_split( self, intp_t start, @@ -148,18 +148,17 @@ cdef class SparsePartitioner: cdef void next_p( self, intp_t* p_prev, - intp_t* p + intp_t* p, + bint missing_go_to_left ) noexcept nogil cdef intp_t partition_samples( self, - float64_t current_threshold + float64_t current_threshold, + bint missing_go_to_left, ) noexcept nogil cdef void partition_samples_final( self, - intp_t best_pos, - float64_t best_threshold, - intp_t best_feature, - intp_t n_missing, + const SplitRecord* best_split, ) noexcept nogil cdef void extract_nnz( @@ -168,16 +167,13 @@ cdef class SparsePartitioner: ) noexcept nogil cdef intp_t _partition( self, - float64_t threshold, - intp_t zero_pos + float64_t threshold ) noexcept nogil -cdef void shift_missing_values_to_left_if_required( - SplitRecord* best, - intp_t[::1] samples, - intp_t end, -) noexcept nogil +cdef void sort(floating* feature_values, intp_t* samples, intp_t n) noexcept nogil -cdef void sort(floating* feature_values, intp_t* samples, intp_t n) noexcept nogil +ctypedef fused array_data_type: + intp_t + float32_t diff --git a/sklearn/tree/_partitioner.pyx b/sklearn/tree/_partitioner.pyx index c479988f0eac7..a6b1c318f8476 100644 --- a/sklearn/tree/_partitioner.pyx +++ b/sklearn/tree/_partitioner.pyx @@ -13,11 +13,14 @@ and sparse data stored in a Compressed Sparse Column (CSC) format. from cython cimport final from libc.math cimport isnan, log2 from libc.stdlib cimport qsort -from libc.string cimport memcpy +from libc.string cimport memcpy, memmove import numpy as np +cimport numpy as cnp +cnp.import_array() from scipy.sparse import issparse +from sklearn.tree._splitter cimport SplitRecord # Constant to switch between algorithm non zero value extract algorithm # in SparsePartitioner @@ -44,6 +47,10 @@ cdef class DensePartitioner: self.samples = samples self.feature_values = feature_values self.missing_values_in_feature_mask = missing_values_in_feature_mask + buffer_size = samples.size * max(samples.itemsize, feature_values.itemsize) + self.swap_buffer = np.empty(buffer_size, dtype=np.uint8) + # TODO: As optimization we could make `swap_array_slices` always pick the smallest side + # to get copied in the buffer, which would allow to use a buffer twice smaller. cdef inline void init_node_split(self, intp_t start, intp_t end) noexcept nogil: """Initialize splitter at the beginning of node_split.""" @@ -98,6 +105,24 @@ cdef class DensePartitioner: sort(&feature_values[self.start], &samples[self.start], self.end - self.start - n_missing) self.n_missing = n_missing + cdef void shift_missing_to_the_left(self) noexcept nogil: + """Moves missing values from the right to the left. + + All missing values are expected to be grouped at the right hand side of the + [self.start:self.end] slices of the self.samples and self.feature_values arrays + before calling this method. This will be the case for nominal use as + the splitter calls sort_samples_and_feature_values() first: + that method groups missing values on the right and sets self.n_missing. + shift_missing_to_the_left() is then called only for the second split search + pass when evaluating missing_go_to_left=True. + + Non-missing values are correspondingly moved from the left to the right while + preserving their inner ordering. + """ + cdef intp_t n_non_missing = self.end - self.start - self.n_missing + swap_array_slices(self.samples, self.start, self.end, n_non_missing, self.swap_buffer) + swap_array_slices(self.feature_values, self.start, self.end, n_non_missing, self.swap_buffer) + cdef inline void find_min_max( self, intp_t current_feature, @@ -110,161 +135,145 @@ cdef class DensePartitioner: values observed in feature_values is stored in self.n_missing. """ cdef: - intp_t p, current_end + intp_t p float32_t current_feature_value - const float32_t[:, :] X = self.X intp_t[::1] samples = self.samples float32_t min_feature_value = INFINITY_32t float32_t max_feature_value = -INFINITY_32t float32_t[::1] feature_values = self.feature_values intp_t n_missing = 0 - const uint8_t[::1] missing_values_in_feature_mask = self.missing_values_in_feature_mask - - # We are copying the values into an array and finding min/max of the array in - # a manner which utilizes the cache more effectively. We need to also count - # the number of missing-values there are. - if missing_values_in_feature_mask is not None and missing_values_in_feature_mask[current_feature]: - p, current_end = self.start, self.end - 1 - # Missing values are placed at the end and do not participate in the - # min/max calculation. - while p <= current_end: - # Finds the right-most value that is not missing so that - # it can be swapped with missing values towards its left. - if isnan(X[samples[current_end], current_feature]): - n_missing += 1 - current_end -= 1 - continue - - # X[samples[current_end], current_feature] is a non-missing value - if isnan(X[samples[p], current_feature]): - samples[p], samples[current_end] = samples[current_end], samples[p] - n_missing += 1 - current_end -= 1 - - current_feature_value = X[samples[p], current_feature] - feature_values[p] = current_feature_value - if current_feature_value < min_feature_value: - min_feature_value = current_feature_value - elif current_feature_value > max_feature_value: - max_feature_value = current_feature_value - p += 1 - else: - min_feature_value = X[samples[self.start], current_feature] - max_feature_value = min_feature_value + bint seen_non_missing = False - feature_values[self.start] = min_feature_value - for p in range(self.start + 1, self.end): - current_feature_value = X[samples[p], current_feature] - feature_values[p] = current_feature_value + for p in range(self.start, self.end): + current_feature_value = self.X[samples[p], current_feature] + feature_values[p] = current_feature_value - if current_feature_value < min_feature_value: - min_feature_value = current_feature_value - elif current_feature_value > max_feature_value: - max_feature_value = current_feature_value + if isnan(current_feature_value): + n_missing += 1 + elif not seen_non_missing: + min_feature_value = current_feature_value + max_feature_value = current_feature_value + seen_non_missing = True + elif current_feature_value < min_feature_value: + min_feature_value = current_feature_value + elif current_feature_value > max_feature_value: + max_feature_value = current_feature_value min_feature_value_out[0] = min_feature_value max_feature_value_out[0] = max_feature_value self.n_missing = n_missing - cdef inline void next_p(self, intp_t* p_prev, intp_t* p) noexcept nogil: - """Compute the next p_prev and p for iterating over feature values. - - The missing values are not included when iterating through the feature values. + cdef inline void next_p( + self, + intp_t* p_prev, + intp_t* p, + bint missing_go_to_left, + ) noexcept nogil: """ - cdef intp_t end_non_missing = self.end - self.n_missing - - while ( - p[0] + 1 < end_non_missing and - self.feature_values[p[0] + 1] <= self.feature_values[p[0]] + FEATURE_THRESHOLD - ): + Compute the next p_prev and p for iterating over feature values. + + This method is used inside the best-split search function pass which starts + by setting p = start at the beginning of each search pass and calls + this method repeatedly with the same missing_go_to_left as for that pass. + The expected layout of self.feature_values[start:end] is: + - first pass (missing_go_to_left=False): after + sort_samples_and_feature_values(), non-missing values are sorted and + missing values are grouped at the right; + - second pass (missing_go_to_left=True): after + shift_missing_to_the_left(), missing values are grouped at the left. + + Given that layout, this method advances p to the next valid split + position while skipping ties up to FEATURE_THRESHOLD: + - if missing_go_to_left: iterate p in [start + n_missing + 1, end) + - otherwise: iterate p in [start, end - n_missing]. + The special case p == end - n_missing corresponds to "all non-missing + values on the left and all missing values on the right". The next + call then sets p to end to terminate the search loop. + """ + cdef intp_t end_non_missing = ( + self.end if missing_go_to_left + else self.end - self.n_missing) + + if p[0] == end_non_missing and not missing_go_to_left: + # skip the missing values up to the end + # (which will end the for loop in the best split function) + p[0] = self.end + p_prev[0] = self.end + else: + if missing_go_to_left and p[0] == self.start: + # skip the missing values up to the first non-missing value: + p[0] = self.start + self.n_missing p[0] += 1 - - p_prev[0] = p[0] - - # By adding 1, we have - # (feature_values[p] >= end) or (feature_values[p] > feature_values[p - 1]) - p[0] += 1 + while ( + p[0] < end_non_missing and + self.feature_values[p[0]] <= self.feature_values[p[0] - 1] + FEATURE_THRESHOLD + ): + p[0] += 1 + p_prev[0] = p[0] - 1 cdef inline intp_t partition_samples( self, - float64_t current_threshold + float64_t threshold, + bint missing_go_to_left ) noexcept nogil: - """Partition samples for feature_values at the current_threshold.""" - cdef: - intp_t p = self.start - intp_t partition_end = self.end - self.n_missing - intp_t[::1] samples = self.samples - float32_t[::1] feature_values = self.feature_values + """Partition self.samples and self.feature_values + on current self.feature_values for a given threshold. - while p < partition_end: - if feature_values[p] <= current_threshold: - p += 1 + Used while searching splits through random threshold sampling. + """ + cdef: + # Local invariance: start <= partition_start <= partition_end <= end + intp_t partition_start = self.start + intp_t partition_end = self.end + intp_t* samples = &self.samples[0] + float32_t* feature_values = &self.feature_values[0] + bint go_to_left + + while partition_start < partition_end: + go_to_left = ( + missing_go_to_left if isnan(feature_values[partition_start]) + else feature_values[partition_start] <= threshold + ) + if go_to_left: + partition_start += 1 else: partition_end -= 1 - - feature_values[p], feature_values[partition_end] = ( - feature_values[partition_end], feature_values[p] - ) - samples[p], samples[partition_end] = samples[partition_end], samples[p] + swap(feature_values, samples, partition_start, partition_end) return partition_end cdef inline void partition_samples_final( self, - intp_t best_pos, - float64_t best_threshold, - intp_t best_feature, - intp_t best_n_missing, + const SplitRecord* best_split, ) noexcept nogil: - """Partition samples for X at the best_threshold and best_feature. + """Partition self.samples according to the split described by best_split. - If missing values are present, this method partitions `samples` - so that the `best_n_missing` missing values' indices are in the - right-most end of `samples`, that is `samples[end_non_missing:end]`. + If missing values are present, this method partitions them accordingly + to the split strategy. """ cdef: - # Local invariance: start <= p <= partition_end <= end - intp_t start = self.start - intp_t p = start - intp_t end = self.end - 1 - intp_t partition_end = end - best_n_missing - intp_t[::1] samples = self.samples - const float32_t[:, :] X = self.X + # Local invariance: start <= partition_start <= partition_end <= end + intp_t partition_start = self.start + intp_t partition_end = self.end + intp_t* samples = &self.samples[0] + float64_t best_threshold = best_split[0].threshold + intp_t best_feature = best_split[0].feature + bint best_missing_go_to_left = best_split[0].missing_go_to_left float32_t current_value + bint go_to_left - if best_n_missing != 0: - # Move samples with missing values to the end while partitioning the - # non-missing samples - while p <= partition_end: - # Keep samples with missing values at the end - if isnan(X[samples[end], best_feature]): - end -= 1 - continue - - # Swap sample with missing values with the sample at the end - current_value = X[samples[p], best_feature] - if isnan(current_value): - samples[p], samples[end] = samples[end], samples[p] - end -= 1 - - # The swapped sample at the end is always a non-missing value, so - # we can continue the algorithm without checking for missingness. - current_value = X[samples[p], best_feature] - - # Partition the non-missing samples - if current_value <= best_threshold: - p += 1 - else: - samples[p], samples[partition_end] = samples[partition_end], samples[p] - partition_end -= 1 - else: - # Partitioning routine when there are no missing values - while p < partition_end: - if X[samples[p], best_feature] <= best_threshold: - p += 1 - else: - samples[p], samples[partition_end] = samples[partition_end], samples[p] - partition_end -= 1 + while partition_start < partition_end: + current_value = self.X[samples[partition_start], best_feature] + go_to_left = ( + best_missing_go_to_left if isnan(current_value) + else current_value <= best_threshold + ) + if go_to_left: + partition_start += 1 + else: + partition_end -= 1 + samples[partition_start], samples[partition_end] = ( + samples[partition_end], samples[partition_start]) @final @@ -351,6 +360,9 @@ cdef class SparsePartitioner: # number of missing values for current_feature self.n_missing = 0 + cdef void shift_missing_to_the_left(self) noexcept nogil: + pass # Missing values are not supported for sparse data. + cdef inline void find_min_max( self, intp_t current_feature, @@ -394,8 +406,17 @@ cdef class SparsePartitioner: min_feature_value_out[0] = min_feature_value max_feature_value_out[0] = max_feature_value - cdef inline void next_p(self, intp_t* p_prev, intp_t* p) noexcept nogil: - """Compute the next p_prev and p for iterating over feature values.""" + cdef inline void next_p( + self, + intp_t* p_prev, + intp_t* p, + bint missing_go_to_left, + ) noexcept nogil: + """Compute the next p_prev and p for iterating over feature values. + + The missing_go_to_left argument is ignored for sparse data because + sparse partitioning does not currently support missing values. + """ cdef intp_t p_next if p[0] + 1 != self.end_negative: @@ -416,24 +437,28 @@ cdef class SparsePartitioner: cdef inline intp_t partition_samples( self, - float64_t current_threshold + float64_t current_threshold, + bint missing_go_to_left ) noexcept nogil: """Partition samples for feature_values at the current_threshold.""" - return self._partition(current_threshold, self.start_positive) + return self._partition(current_threshold) cdef inline void partition_samples_final( self, - intp_t best_pos, - float64_t best_threshold, - intp_t best_feature, - intp_t n_missing, + const SplitRecord* best_split, ) noexcept nogil: - """Partition samples for X at the best_threshold and best_feature.""" - self.extract_nnz(best_feature) - self._partition(best_threshold, best_pos) + """Partition samples for X according to the split described by best_split.""" + self.extract_nnz(best_split[0].feature) + self._partition(best_split[0].threshold) - cdef inline intp_t _partition(self, float64_t threshold, intp_t zero_pos) noexcept nogil: - """Partition samples[start:end] based on threshold.""" + cdef inline intp_t _partition(self, float64_t threshold) noexcept nogil: + """ + Partition samples[start:end] based on threshold. + Assume extract_nnz was called beforehand, and partitioned samples in: + - samples[start:end_negative] -> < 0 + - samples[end_negative:start_positive] -> zeros + - samples[end_negative:start_positive] -> > 0 + """ cdef: intp_t p, partition_end intp_t[::1] index_to_samples = self.index_to_samples @@ -447,8 +472,8 @@ cdef class SparsePartitioner: p = self.start_positive partition_end = self.end else: - # Data are already split - return zero_pos + # If threshold is 0, extract_nnz already did the necessary partitioning + return self.start_positive while p < partition_end: if feature_values[p] <= threshold: @@ -672,32 +697,6 @@ cdef inline void sparse_swap(intp_t[::1] index_to_samples, intp_t[::1] samples, index_to_samples[samples[pos_2]] = pos_2 -cdef inline void shift_missing_values_to_left_if_required( - SplitRecord* best, - intp_t[::1] samples, - intp_t end, -) noexcept nogil: - """Shift missing value sample indices to the left of the split if required. - - Note: this should always be called at the very end because it will - move samples around, thereby affecting the criterion. - This affects the computation of the children impurity, which affects - the computation of the next node. - """ - cdef intp_t i, p, current_end - # The partitioner partitions the data such that the missing values are in - # samples[-n_missing:] for the criterion to consume. If the missing values - # are going to the right node, then the missing values are already in the - # correct position. If the missing values go left, then we move the missing - # values to samples[best.pos:best.pos+n_missing] and update `best.pos`. - if best.n_missing > 0 and best.missing_go_to_left: - for p in range(best.n_missing): - i = best.pos + p - current_end = end - 1 - p - samples[i], samples[current_end] = samples[current_end], samples[i] - best.pos += best.n_missing - - def _py_sort(float32_t[::1] feature_values, intp_t[::1] samples, intp_t n): """Used for testing sort.""" sort(&feature_values[0], &samples[0], n) @@ -815,3 +814,41 @@ cdef void heapsort(floating* feature_values, intp_t* samples, intp_t n) noexcept swap(feature_values, samples, 0, end) sift_down(feature_values, samples, 0, end) end = end - 1 + + +cdef void swap_array_slices( + array_data_type[::1] array, intp_t start, intp_t end, intp_t n, + char[::1] buffer +) noexcept nogil: + """Swaps the order of the slices array[start:start + n] and array[start + n:end]. + + Preserves the order within the slices. Works for any itemsize. + """ + if start >= end: + return + cdef size_t itemsize = sizeof(array[0]) + cdef intp_t n_rev = end - start - n + cdef char* arr = <char*> &array[0] + cdef char* buf = &buffer[0] + # Copy array[start + n : end] to temporary buffer + memcpy(buf, arr + (start + n) * itemsize, n_rev * itemsize) + # Move array[start : start + n] to array[start + n_rev : end] + # `memmove` is needed as the dest & source regions overlap + memmove(arr + (start + n_rev) * itemsize, arr + start * itemsize, n * itemsize) + # array[start : start + n_rev] = buffer[:n_rev] + memcpy(arr + start * itemsize, buf, n_rev * itemsize) + + +def _py_swap_array_slices(cnp.ndarray array, intp_t start, intp_t end, intp_t n): + """ + Python wrapper for swap_array_slices for testing. + `array` must be contiguous. + """ + buffer = np.empty(array.size * array.dtype.itemsize, dtype=np.uint8) + # Dispatch to the appropriate specialized version based on dtype + if array.dtype == np.intp: + swap_array_slices[intp_t](array, start, end, n, buffer) + elif array.dtype == np.float32: + swap_array_slices[float32_t](array, start, end, n, buffer) + else: + raise ValueError(f"Unsupported dtype: {array.dtype}. Expected np.intp or np.float32") diff --git a/sklearn/tree/_splitter.pxd b/sklearn/tree/_splitter.pxd index b3f458d8c5185..c988abb33996b 100644 --- a/sklearn/tree/_splitter.pxd +++ b/sklearn/tree/_splitter.pxd @@ -23,7 +23,7 @@ cdef struct SplitRecord: float64_t lower_bound # Lower bound on value of both children for monotonicity float64_t upper_bound # Upper bound on value of both children for monotonicity uint8_t missing_go_to_left # Controls if missing values go to the left node. - intp_t n_missing # Number of missing values for the feature being split on + cdef class Splitter: # The splitter searches in the input space for a feature and a threshold diff --git a/sklearn/tree/_splitter.pyx b/sklearn/tree/_splitter.pyx index bd80adcfe251c..cc48cf5019139 100644 --- a/sklearn/tree/_splitter.pyx +++ b/sklearn/tree/_splitter.pyx @@ -26,7 +26,6 @@ from sklearn.utils._typedefs cimport int8_t from sklearn.tree._criterion cimport Criterion from sklearn.tree._partitioner cimport ( FEATURE_THRESHOLD, DensePartitioner, SparsePartitioner, - shift_missing_values_to_left_if_required ) from sklearn.tree._utils cimport RAND_R_MAX, rand_int, rand_uniform @@ -53,7 +52,6 @@ cdef inline void _init_split(SplitRecord* self, intp_t start_pos) noexcept nogil self.threshold = 0. self.improvement = -INFINITY self.missing_go_to_left = False - self.n_missing = 0 cdef class Splitter: """Abstract splitter class. @@ -194,8 +192,6 @@ cdef class Splitter: self.y = y self.sample_weight = sample_weight - if missing_values_in_feature_mask is not None: - self.criterion.init_sum_missing() return 0 cdef int node_reset( @@ -291,7 +287,6 @@ cdef inline int node_split_best( cdef intp_t n_left, n_right cdef bint missing_go_to_left - cdef intp_t[::1] samples = splitter.samples cdef intp_t[::1] features = splitter.features cdef intp_t[::1] constant_features = splitter.constant_features cdef intp_t n_features = splitter.n_features @@ -396,38 +391,35 @@ cdef inline int node_split_best( f_i -= 1 features[f_i], features[f_j] = features[f_j], features[f_i] has_missing = n_missing != 0 - criterion.init_missing(n_missing) # initialize even when n_missing == 0 # Evaluate all splits # If there are missing values, then we search twice for the most optimal split. - # The first search will have all the missing values going to the right node. + # The first search will have all the missing values going to the right node + # and the split with right node being only missing values is evaluated. # The second search will have all the missing values going to the left node. + # This logic is governed by the partitionner and used here, so there is a strong coupling. # If there are no missing values, then we search only once for the most # optimal split. n_searches = 2 if has_missing else 1 for i in range(n_searches): missing_go_to_left = i == 1 - criterion.missing_go_to_left = missing_go_to_left + if missing_go_to_left: + partitioner.shift_missing_to_the_left() + criterion.reset() p = start - while p < end_non_missing: - partitioner.next_p(&p_prev, &p) - - if p >= end_non_missing: + while p < end: + partitioner.next_p(&p_prev, &p, missing_go_to_left) + if p == end: continue - if missing_go_to_left: - n_left = p - start + n_missing - n_right = end_non_missing - p - else: - n_left = p - start - n_right = end_non_missing - p + n_missing - # Reject if min_samples_leaf is not guaranteed + n_left = p - start + n_right = end - p if n_left < min_samples_leaf or n_right < min_samples_leaf: continue @@ -455,21 +447,23 @@ cdef inline int node_split_best( if current_proxy_improvement > best_proxy_improvement: best_proxy_improvement = current_proxy_improvement - # sum of halves is used to avoid infinite value - current_split.threshold = ( - feature_values[p_prev] / 2.0 + feature_values[p] / 2.0 - ) - - if ( - current_split.threshold == feature_values[p] or - current_split.threshold == INFINITY or - current_split.threshold == -INFINITY - ): - current_split.threshold = feature_values[p_prev] - - current_split.n_missing = n_missing + if p == end_non_missing and not missing_go_to_left: + # Split with the right node being only the missing values. + # Note that partioner.next_p never considers candidate + # splits for which the left node would move only the + # the missing values as this would be redundant with the + # split that only send missing values to the right. + # We use inf as a threshold because nan <= inf is false + # according to IEEE 754. + current_split.threshold = INFINITY + else: + # Split between two non-missing values: sum of halves is + # used to avoid infinite value. + current_split.threshold = ( + feature_values[p_prev] / 2.0 + feature_values[p] / 2.0 + ) - # if there are no missing values in the training data, during + # If there are no missing values in the training data, during # test time, we send missing values to the branch that contains # the most samples during training time. if n_missing == 0: @@ -479,53 +473,24 @@ cdef inline int node_split_best( best_split = current_split # copy - # Evaluate when there are missing values and all missing values goes - # to the right node and non-missing values goes to the left node. - if has_missing: - n_left, n_right = end - start - n_missing, n_missing - p = end - n_missing - missing_go_to_left = 0 - - if not (n_left < min_samples_leaf or n_right < min_samples_leaf): - criterion.missing_go_to_left = missing_go_to_left - criterion.update(p) - - if not ((criterion.weighted_n_left < min_weight_leaf) or - (criterion.weighted_n_right < min_weight_leaf)): - current_proxy_improvement = criterion.proxy_impurity_improvement() - - if current_proxy_improvement > best_proxy_improvement: - best_proxy_improvement = current_proxy_improvement - current_split.threshold = INFINITY - current_split.missing_go_to_left = missing_go_to_left - current_split.n_missing = n_missing - current_split.pos = p - best_split = current_split - # Reorganize into samples[start:best_split.pos] + samples[best_split.pos:end] if best_split.pos < end: partitioner.partition_samples_final( - best_split.pos, - best_split.threshold, - best_split.feature, - best_split.n_missing + &best_split ) - criterion.init_missing(best_split.n_missing) - criterion.missing_go_to_left = best_split.missing_go_to_left criterion.reset() criterion.update(best_split.pos) criterion.children_impurity( &best_split.impurity_left, &best_split.impurity_right ) + best_split.improvement = criterion.impurity_improvement( impurity, best_split.impurity_left, best_split.impurity_right ) - shift_missing_values_to_left_if_required(&best_split, samples, end) - # Respect invariant for constant features: the original order of # element in features[:n_known_constants] must be preserved for sibling # and child nodes @@ -560,13 +525,11 @@ cdef inline int node_split_random( # Draw random splits and pick the best cdef intp_t start = splitter.start cdef intp_t end = splitter.end - cdef intp_t end_non_missing cdef intp_t n_missing = 0 cdef bint has_missing = 0 cdef intp_t n_left, n_right cdef bint missing_go_to_left - cdef intp_t[::1] samples = splitter.samples cdef intp_t[::1] features = splitter.features cdef intp_t[::1] constant_features = splitter.constant_features cdef intp_t n_features = splitter.n_features @@ -649,11 +612,10 @@ cdef inline int node_split_random( current_split.feature, &min_feature_value, &max_feature_value ) n_missing = partitioner.n_missing - end_non_missing = end - n_missing if ( # All values for this feature are missing, or - end_non_missing == start or + end - start == n_missing or # This feature is considered constant (max - min <= FEATURE_THRESHOLD) (max_feature_value <= min_feature_value + FEATURE_THRESHOLD and n_missing == 0) ): @@ -669,7 +631,6 @@ cdef inline int node_split_random( f_i -= 1 features[f_i], features[f_j] = features[f_j], features[f_i] has_missing = n_missing != 0 - criterion.init_missing(n_missing) # Draw a random threshold current_split.threshold = rand_uniform( @@ -691,22 +652,17 @@ cdef inline int node_split_random( missing_go_to_left = rand_int(0, 2, random_state) else: missing_go_to_left = 0 - criterion.missing_go_to_left = missing_go_to_left if current_split.threshold == max_feature_value: current_split.threshold = min_feature_value # Partition current_split.pos = partitioner.partition_samples( - current_split.threshold + current_split.threshold, missing_go_to_left ) - if missing_go_to_left: - n_left = current_split.pos - start + n_missing - n_right = end_non_missing - current_split.pos - else: - n_left = current_split.pos - start - n_right = end_non_missing - current_split.pos + n_missing + n_left = current_split.pos - start + n_right = end - current_split.pos # Reject if min_samples_leaf is not guaranteed if n_left < min_samples_leaf or n_right < min_samples_leaf: @@ -738,8 +694,6 @@ cdef inline int node_split_random( current_proxy_improvement = criterion.proxy_impurity_improvement() if current_proxy_improvement > best_proxy_improvement: - current_split.n_missing = n_missing - # if there are no missing values in the training data, during # test time, we send missing values to the branch that contains # the most samples during training time. @@ -755,13 +709,8 @@ cdef inline int node_split_random( if best_split.pos < end: if current_split.feature != best_split.feature: partitioner.partition_samples_final( - best_split.pos, - best_split.threshold, - best_split.feature, - best_split.n_missing + &best_split ) - criterion.init_missing(best_split.n_missing) - criterion.missing_go_to_left = best_split.missing_go_to_left criterion.reset() criterion.update(best_split.pos) @@ -774,8 +723,6 @@ cdef inline int node_split_random( best_split.impurity_right ) - shift_missing_values_to_left_if_required(&best_split, samples, end) - # Respect invariant for constant features: the original order of # element in features[:n_known_constants] must be preserved for sibling # and child nodes diff --git a/sklearn/tree/tests/test_split.py b/sklearn/tree/tests/test_split.py index ab1e80a2b6dd9..cd5a56eaf7601 100644 --- a/sklearn/tree/tests/test_split.py +++ b/sklearn/tree/tests/test_split.py @@ -167,11 +167,6 @@ def make_simple_dataset( def test_split_impurity(Tree, criterion, sparse, missing_values, global_random_seed): is_clf = criterion in CLF_CRITERIONS - # TODO: (remove in PR #32119) - if missing_values and criterion == "absolute_error": - pytest.skip("AE + missing values not supported yet") - if missing_values and criterion == "poisson": - pytest.xfail("Poisson criterion is faulty for now") rng = np.random.default_rng(global_random_seed) ns = [5] * 5 + [10] * 5 + [20, 30, 50, 100] diff --git a/sklearn/tree/tests/test_swap.py b/sklearn/tree/tests/test_swap.py new file mode 100644 index 0000000000000..c465f2cb07ede --- /dev/null +++ b/sklearn/tree/tests/test_swap.py @@ -0,0 +1,43 @@ +import numpy as np +import pytest + +from sklearn.tree._partitioner import _py_swap_array_slices + + +@pytest.mark.parametrize("dtype", [np.float32, np.intp]) +def test_py_swap_array_slices_random(dtype, global_random_seed): + def swap_slices_np(arr, start, end, n): + """ + Swaps the two slices array[start:start + n] and + array[start + n:end] while preserving the order in the slices. + """ + arr = arr.copy() + arr[start:end] = np.concatenate([arr[start + n : end], arr[start : start + n]]) + return arr + + rng = np.random.default_rng(global_random_seed) + + for _ in range(20): + size = rng.integers(1, 101) + arr = rng.permutation(size).astype(dtype) + n = rng.integers(0, size) + start = rng.integers(0, size - n) + end = rng.integers(start + n, size) + # test the swap of arr[start:start + n] with arr[start + n:end] + expected = swap_slices_np(arr, start, end, n) + + _py_swap_array_slices(arr, start, end, n) + np.testing.assert_array_equal(arr, expected) + + # test some edge cases: + size = 30 + n = 10 + start = rng.integers(0, size - n) + arr = np.arange(size, dtype=dtype) + expected = arr.copy() + # n == end - start should be no-op: + _py_swap_array_slices(arr, start, start + n, n) + np.testing.assert_array_equal(arr, expected) + # n == 0 should be no-op: + _py_swap_array_slices(arr, start, size, 0) + np.testing.assert_array_equal(arr, expected) diff --git a/sklearn/tree/tests/test_tree.py b/sklearn/tree/tests/test_tree.py index beca79e3c18f8..53c301fa19035 100644 --- a/sklearn/tree/tests/test_tree.py +++ b/sklearn/tree/tests/test_tree.py @@ -2443,18 +2443,19 @@ def test_min_sample_split_1_error(Tree): # TODO(1.11): remove the deprecated friedman_mse criterion parametrization @pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") -@pytest.mark.parametrize("criterion", ["squared_error", "friedman_mse"]) +@pytest.mark.parametrize("criterion", REG_CRITERIONS) def test_missing_values_best_splitter_on_equal_nodes_no_missing(criterion): """Check missing values goes to correct node during predictions.""" X = np.array([[0, 1, 2, 3, 8, 9, 11, 12, 15]]).T y = np.array([0.1, 0.2, 0.3, 0.2, 1.4, 1.4, 1.5, 1.6, 2.6]) + node_value_func = np.median if criterion == "absolute_error" else np.mean dtc = DecisionTreeRegressor(random_state=42, max_depth=1, criterion=criterion) dtc.fit(X, y) # Goes to right node because it has the most data points y_pred = dtc.predict([[np.nan]]) - assert_allclose(y_pred, [np.mean(y[-5:])]) + assert_allclose(y_pred, [node_value_func(y[-5:])]) # equal number of elements in both nodes X_equal = X[:-1] @@ -2466,13 +2467,13 @@ def test_missing_values_best_splitter_on_equal_nodes_no_missing(criterion): # Goes to right node because the implementation sets: # missing_go_to_left = n_left > n_right, which is False y_pred = dtc.predict([[np.nan]]) - assert_allclose(y_pred, [np.mean(y_equal[-4:])]) + assert_allclose(y_pred, [node_value_func(y_equal[-4:])]) # TODO(1.11): remove the deprecated friedman_mse criterion parametrization @pytest.mark.filterwarnings("ignore:.*friedman_mse.*:FutureWarning") @pytest.mark.parametrize("seed", range(3)) -@pytest.mark.parametrize("criterion", ["squared_error", "friedman_mse"]) +@pytest.mark.parametrize("criterion", REG_CRITERIONS) def test_missing_values_random_splitter_on_equal_nodes_no_missing(criterion, seed): """Check missing values go to the correct node during predictions for ExtraTree. @@ -2570,12 +2571,12 @@ def test_missing_values_best_splitter_missing_both_classes_has_nan(criterion): assert_array_equal(y_pred, [1, 0, 1]) -@pytest.mark.parametrize("sparse_container", [None] + CSR_CONTAINERS) +@pytest.mark.parametrize("sparse_container", CSR_CONTAINERS) @pytest.mark.parametrize( "tree", [ - DecisionTreeRegressor(criterion="absolute_error"), - ExtraTreeRegressor(criterion="absolute_error"), + DecisionTreeRegressor(), + ExtraTreeRegressor(), ], ) def test_missing_value_errors(sparse_container, tree): @@ -2584,8 +2585,7 @@ def test_missing_value_errors(sparse_container, tree): X = np.array([[1, 2, 3, 5, np.nan, 10, 20, 30, 60, np.nan]]).T y = np.array([0] * 5 + [1] * 5) - if sparse_container is not None: - X = sparse_container(X) + X = sparse_container(X) with pytest.raises(ValueError, match="Input X contains NaN"): tree.fit(X, y) @@ -2760,29 +2760,31 @@ def test_deterministic_pickle(): np.array([1, 2, 3, np.nan, 6, np.nan]), ], ) -@pytest.mark.parametrize("criterion", ["squared_error", "friedman_mse"]) +@pytest.mark.parametrize("criterion", REG_CRITERIONS) def test_regression_tree_missing_values_toy(Tree, X, criterion, global_random_seed): - """Check that we properly handle missing values in regression trees using a toy - dataset. - - The regression targeted by this test was that we were not reinitializing the - criterion when it comes to the number of missing values. Therefore, the value - of the critetion (i.e. MSE) was completely wrong. + """Check that regression trees correctly handle missing values in impurity + calculations. - This test check that the MSE is null when there is a single sample in the leaf. + This test verifies that: + 1. Impurity is always non-negative + 2. Impurity is zero for leaves with a single sample + 3. For decision trees, impurity matches reference trees after the first split Non-regression test for: - https://github.com/scikit-learn/scikit-learn/issues/28254 - https://github.com/scikit-learn/scikit-learn/issues/28316 + - Missing values handling in regression criteria: + https://github.com/scikit-learn/scikit-learn/issues/28254 + https://github.com/scikit-learn/scikit-learn/issues/28316 + - Incorrect/negative impurites for the Poisson criterion with missing values: + https://github.com/scikit-learn/scikit-learn/issues/32870 """ X = X.reshape(-1, 1) - y = np.arange(6) + y = np.arange(1, 7) tree = Tree(criterion=criterion, random_state=global_random_seed).fit(X, y) tree_ref = clone(tree).fit(y.reshape(-1, 1), y) impurity = tree.tree_.impurity - assert all(impurity >= 0), impurity.min() # MSE should always be positive + assert all(impurity >= 0), impurity.min() # impurity should always be positive # Note: the impurity matches after the first split only on greedy trees # see https://github.com/scikit-learn/scikit-learn/issues/32125 @@ -2790,7 +2792,7 @@ def test_regression_tree_missing_values_toy(Tree, X, criterion, global_random_se # Check the impurity match after the first split assert_allclose(tree.tree_.impurity[:2], tree_ref.tree_.impurity[:2]) - # Find the leaves with a single sample where the MSE should be 0 + # Find the leaves with a single sample where the impurity should be 0 leaves_idx = np.flatnonzero( (tree.tree_.children_left == -1) & (tree.tree_.n_node_samples == 1) ) @@ -3043,3 +3045,29 @@ def test_missing_values_and_constant_toy(): def test_friedman_mse_deprecation(): with pytest.warns(FutureWarning, match="friedman_mse"): _ = DecisionTreeRegressor(criterion="friedman_mse") + + +@pytest.mark.parametrize( + "X,y", + [ + (np.array([[np.nan], [0.0], [1.0], [2.0]]), np.array([0.0, 1.0, 2.0, 3.0])), + (np.array([[np.nan], [1.0], [np.nan]]), np.array([0.0, 1.0, 0.0])), + ], + ids=["multiple-non-missing", "single-non-missing"], +) +def test_random_splitter_missing_values_uses_non_missing_min_max(X, y): + """ + Check random-split thresholds are finite when the first sample is missing. + + Non-regression test for a subtle bug, see + https://github.com/scikit-learn/scikit-learn/pull/32119#issuecomment-3765288780 + """ + tree = ExtraTreeRegressor(max_depth=1, random_state=0) + tree.fit(X, y) + + assert tree.tree_.children_left[0] != TREE_LEAF + threshold = tree.tree_.threshold[0] + non_missing = X[~np.isnan(X)] + + assert np.isfinite(threshold) + assert non_missing.min() <= threshold <= non_missing.max() From b03e64c2ec8ed0f7012a0f7264ea3b59bc965dc3 Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Thu, 5 Mar 2026 14:22:41 +0100 Subject: [PATCH 258/462] MAINT only run the cuda tests on the CUDA CI runner (#33445) --- .github/workflows/cuda-ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cuda-ci.yml b/.github/workflows/cuda-ci.yml index d79d646b0bd92..8e2da554f9362 100644 --- a/.github/workflows/cuda-ci.yml +++ b/.github/workflows/cuda-ci.yml @@ -66,6 +66,9 @@ jobs: conda activate sklearn python -c "import sklearn; sklearn.show_versions()" - SCIPY_ARRAY_API=1 pytest --pyargs sklearn -k 'array_api' -vl + # Since we are billed GPU usage by the minute, we only run the tests that + # are likely to exercise the CUDA GPU and rely on free CI runners to run + # the tests with PyTorch on non-CUDA devices. + SCIPY_ARRAY_API=1 pytest --pyargs sklearn -k 'cuda or cupy' -vl # Run in /home/runner to not load sklearn from the checkout repo working-directory: /home/runner From 81e7a3eda86c80d07e952b82bf599fac2258a690 Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Fri, 6 Mar 2026 20:47:39 +1100 Subject: [PATCH 259/462] TST Add common test for mixed array API inputs for metrics (#32755) --- sklearn/metrics/_base.py | 8 +- sklearn/metrics/_classification.py | 4 +- sklearn/metrics/_ranking.py | 26 ++- sklearn/metrics/_regression.py | 4 +- sklearn/metrics/tests/test_common.py | 226 ++++++++++++++++++++++++++ sklearn/utils/_array_api.py | 72 +++++++- sklearn/utils/tests/test_array_api.py | 39 ++--- 7 files changed, 334 insertions(+), 45 deletions(-) diff --git a/sklearn/metrics/_base.py b/sklearn/metrics/_base.py index 9964929a446b5..03547142ffbaa 100644 --- a/sklearn/metrics/_base.py +++ b/sklearn/metrics/_base.py @@ -12,7 +12,11 @@ import sklearn.externals.array_api_extra as xpx from sklearn.utils import check_array, check_consistent_length -from sklearn.utils._array_api import _average, _ravel, get_namespace_and_device +from sklearn.utils._array_api import ( + _average, + _ravel, + get_namespace_and_device, +) from sklearn.utils.multiclass import type_of_target @@ -59,7 +63,7 @@ def _average_binary_score(binary_metric, y_true, y_score, average, sample_weight classes. """ - xp, _, _device = get_namespace_and_device(y_true, y_score, sample_weight) + xp, _, _device = get_namespace_and_device(y_score, sample_weight) average_options = (None, "micro", "macro", "weighted", "samples") if average not in average_options: raise ValueError("average has to be one of {0}".format(average_options)) diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 9c451f52b9dda..a4ff45ae3e2e1 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -225,7 +225,7 @@ def _one_hot_encoding_multiclass_target(y_true, labels, target_xp, target_device ) transformed_labels = lb.transform(y_true) - transformed_labels = target_xp.asarray(transformed_labels, device=target_device) + transformed_labels = move_to(transformed_labels, xp=target_xp, device=target_device) if transformed_labels.shape[1] == 1: transformed_labels = target_xp.concat( (1 - transformed_labels, transformed_labels), axis=1 @@ -3607,7 +3607,7 @@ def _one_hot_encoding_binary_target(y_true, pos_label, target_xp, target_device) """ xp_y_true, _ = get_namespace(y_true) y_true_pos = xp_y_true.asarray(y_true == pos_label, dtype=xp_y_true.int64) - y_true_pos = target_xp.asarray(y_true_pos, device=target_device) + y_true_pos = move_to(y_true_pos, xp=target_xp, device=target_device) return target_xp.stack((1 - y_true_pos, y_true_pos), axis=1) diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index 2f04ea67d9254..6385b3a1c2799 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -30,6 +30,7 @@ ) from sklearn.utils._array_api import ( _max_precision_float_dtype, + get_namespace, get_namespace_and_device, move_to, size, @@ -231,7 +232,10 @@ def average_precision_score( 0.77 """ xp, _, device = get_namespace_and_device(y_score) - y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) + # To allow mixed string `y_true`/numeric `y_score` input, cannot move `y_true` + # until it has been converted to an integer (e.g., via `label_binarize`) + # Ensures `test_array_api_classification_mixed_string_numeric_input` passes. + sample_weight = move_to(sample_weight, xp=xp, device=device) if sample_weight is not None: sample_weight = column_or_1d(sample_weight) @@ -256,7 +260,8 @@ def _binary_uninterpolated_average_precision( return float(max(0.0, -xp.sum(xp.diff(recall) * precision[:-1]))) y_type = type_of_target(y_true, input_name="y_true") - present_labels = xp.unique_values(y_true) + xp_y_true, _ = get_namespace(y_true) + present_labels = xp_y_true.unique_values(y_true) if y_type == "binary": if present_labels.shape[0] == 2 and pos_label not in present_labels: @@ -278,6 +283,7 @@ def _binary_uninterpolated_average_precision( "Do not set pos_label or set pos_label to 1." ) y_true = label_binarize(y_true, classes=present_labels) + y_true = move_to(y_true, xp=xp, device=device) if not y_score.shape == y_true.shape: raise ValueError( "`y_score` needs to be of shape `(n_samples, n_classes)`, since " @@ -956,7 +962,14 @@ def confusion_matrix_at_thresholds( if not (y_type == "binary" or (y_type == "multiclass" and pos_label is not None)): raise ValueError("{0} format is not supported".format(y_type)) - xp, _, device = get_namespace_and_device(y_true, y_score, sample_weight) + xp, _, device = get_namespace_and_device(y_score) + pos_label = _check_pos_label_consistency(pos_label, y_true) + xp_y_true, _ = get_namespace(y_true) + # Make `y_true` a boolean vector. Use `asarray` as `y_true` could be a list + y_true = xp_y_true.asarray( + xp_y_true.asarray(y_true) == pos_label, dtype=xp_y_true.int32 + ) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) check_consistent_length(y_true, y_score, sample_weight) y_true = column_or_1d(y_true) @@ -973,11 +986,6 @@ def confusion_matrix_at_thresholds( y_score = y_score[nonzero_weight_mask] sample_weight = sample_weight[nonzero_weight_mask] - pos_label = _check_pos_label_consistency(pos_label, y_true) - - # make y_true a boolean vector - y_true = y_true == pos_label - # sort scores and corresponding truth values desc_score_indices = xp.argsort(y_score, stable=True, descending=True) y_score = y_score[desc_score_indices] @@ -1126,7 +1134,7 @@ def precision_recall_curve( >>> thresholds array([0.1 , 0.35, 0.4 , 0.8 ]) """ - xp, _, device = get_namespace_and_device(y_true, y_score) + xp, _, device = get_namespace_and_device(y_score) _, fps, _, tps, thresholds = confusion_matrix_at_thresholds( y_true, y_score, pos_label=pos_label, sample_weight=sample_weight diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 855912ca2d4a4..007c192e424a2 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -22,6 +22,7 @@ _median, get_namespace, get_namespace_and_device, + move_to, size, ) from sklearn.utils._array_api import _xlogy as xlogy @@ -1345,7 +1346,8 @@ def max_error(y_true, y_pred): >>> max_error(y_true, y_pred) 1.0 """ - xp, _ = get_namespace(y_true, y_pred) + xp, _, device = get_namespace_and_device(y_pred) + y_true = move_to(y_true, xp=xp, device=device) y_type, y_true, y_pred, _, _ = _check_reg_targets( y_true, y_pred, sample_weight=None, multioutput=None, xp=xp ) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 7c41acb9570c8..a05d39950d185 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -3,6 +3,7 @@ from functools import partial from inspect import signature from itertools import chain, permutations, product +from typing import Tuple import numpy as np import pytest @@ -86,6 +87,10 @@ _atol_for_type, _convert_to_numpy, _get_namespace_device_dtype_ids, + _max_precision_float_dtype, + device, + get_namespace, + yield_mixed_namespace_input_permutations, yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import ( @@ -613,6 +618,18 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "root_mean_squared_log_error", } +# Metrics that support mixed namespace/device array API inputs +# Mixed mixed namespace/device support is NOT planned for pairwise metrics +METRICS_SUPPORTING_MIXED_NAMESPACE = [ + "average_precision_score", + "brier_score_loss", + "confusion_matrix_at_thresholds", + "d2_brier_score", + "d2_log_loss_score", + "log_loss", + "max_error", +] + def _require_positive_targets(y1, y2): """Make targets strictly positive""" @@ -2475,6 +2492,215 @@ def test_array_api_compliance(metric, array_namespace, device, dtype_name, check check_func(metric, array_namespace, device, dtype_name) +def _check_output(out_np, out_xp, xp_to, y2_xp): + if isinstance(out_np, float): + assert isinstance(out_xp, float) + elif hasattr(out_np, "shape"): + assert hasattr(out_xp, "shape") + assert get_namespace(out_xp)[0] == xp_to + assert device(out_xp) == device(y2_xp) + # `classification_report` returns str (with default `output_dict=False`) + elif isinstance(out_np, str): + assert isinstance(out_xp, str) + + +@pytest.mark.parametrize( + "from_ns_and_device, to_ns_and_device", + [ + pytest.param(*args[:2], id=args[2]) + for args in yield_mixed_namespace_input_permutations() + ], +) +@pytest.mark.parametrize("metric_name", sorted(METRICS_SUPPORTING_MIXED_NAMESPACE)) +def test_mixed_array_api_namespace_input_compliance( + metric_name, from_ns_and_device, to_ns_and_device +): + """Check `y_true` and `sample_weight` follows `y_pred` for mixed namespace inputs. + + Compares the output for all-numpy vs mixed-type inputs. + If the output is a float, checks that both all-numpy and mixed-type inputs return + a float. + If output is an array, checks it is of the same namespace and device as `y_pred` + (`to_ns_and_device`). + If the output is a tuple, checks that each element, whether float or array, + is correct, as detailed above. + """ + xp_to = _array_api_for_tests(to_ns_and_device.xp, to_ns_and_device.device) + xp_from = _array_api_for_tests(from_ns_and_device.xp, from_ns_and_device.device) + + metric = ALL_METRICS[metric_name] + + data_all = { + "binary": ([0, 0, 1, 1], [0, 1, 0, 1]), + "binary_continuous": ([1, 0, 1, 0], [0.5, 0.2, 0.7, 0.6]), + "label_indicator_continuous": ([[1, 0, 1, 0]], [[0.5, 0.2, 0.7, 0.6]]), + "regression_integer": ([2, 1, 3, 4], [2, 1, 2, 2]), + "regression_continuous": ([2.1, 1.0, 3.0, 4.0], [2.2, 1.1, 2.0, 2.0]), + } + sample_weight = [1, 1, 2, 2] + + # Deal with max mps float precision being float32 + def _get_dtype(data, xp, device): + # Assume list is all float if first element is float + if isinstance(data[0], float): + dtype = _max_precision_float_dtype(xp, device) + else: + dtype = xp.int64 + return dtype + + if metric_name in CLASSIFICATION_METRICS: + # These should all accept binary label input as there are no + # `CLASSIFICATION_METRICS` that are in `METRIC_UNDEFINED_BINARY` and are + # NOT `partial`s (which we do not test for in array API compliance) + data_cases = ["binary"] + elif metric_name in {**CONTINUOUS_CLASSIFICATION_METRICS, **CURVE_METRICS}: + if metric_name not in METRIC_UNDEFINED_BINARY: + data_cases = ["binary_continuous"] + else: + data_cases = ["label_indicator_continuous"] + elif metric_name in REGRESSION_METRICS: + data_cases = ["regression_integer", "regression_continuous"] + + with config_context(array_api_dispatch=True): + for data_case in data_cases: + y1, y2 = data_all[data_case] + + dtype = _get_dtype(y1, xp_from, from_ns_and_device.device) + y1_xp = xp_from.asarray(y1, device=from_ns_and_device.device, dtype=dtype) + + metric_kwargs_xp = metric_kwargs_np = {} + if metric_name not in METRICS_WITHOUT_SAMPLE_WEIGHT: + # use `from_ns_and_device` for `sample_weight` as well + sample_weight_np = np.array(sample_weight) + metric_kwargs_np = {"sample_weight": sample_weight_np} + sample_weight_xp = xp_from.asarray( + sample_weight_np, device=from_ns_and_device.device + ) + metric_kwargs_xp = {"sample_weight": sample_weight_xp} + + dtype = _get_dtype(y2, xp_to, to_ns_and_device.device) + y2_xp = xp_to.asarray(y2, device=to_ns_and_device.device, dtype=dtype) + + metric_xp = metric(y1_xp, y2_xp, **metric_kwargs_xp) + metric_np = metric(y1, y2, **metric_kwargs_np) + + if isinstance(metric_np, Tuple): + for out_np, out_xp in zip(metric_np, metric_xp): + _check_output(out_np, out_xp, xp_to, y2_xp) + else: + _check_output(metric_np, metric_xp, xp_to, y2_xp) + + +# Check thresholded classification metrics, minus multilabel ranking metrics +# (`METRIC_UNDEFINED_BINARY`), which take label indicator input (and thus never +# string input). +@pytest.mark.parametrize( + "metric_name", + sorted( + set(METRICS_SUPPORTING_MIXED_NAMESPACE) + & (set(CLASSIFICATION_METRICS.keys()) - METRIC_UNDEFINED_BINARY) + ), +) +def test_array_api_classification_string_input(metric_name): + """Check string inputs accepted with array API dispatch enabled. + + All thresholded classification metrics that do not require label indicator format + input should work when both inputs (e.g.,`y_true` and `y_pred`) are string (numpy + namespace only) and dispatch is enabled. + Note thresholded classification metrics do not support mixed string and numeric + inputs. + """ + metric = ALL_METRICS[metric_name] + y_true = np.array(["a", "b", "a", "a"]) + y_pred = np.array(["a", "b", "b", "a"]) + + kwargs = {} + if metric_name in METRICS_WITH_POS_LABEL: + kwargs["pos_label"] = "a" + + with config_context(array_api_dispatch=True): + metric_enabled = metric(y_true, y_pred, **kwargs) + + with config_context(array_api_dispatch=False): + metric_disabled = metric(y_true, y_pred, **kwargs) + + _check_output(metric_enabled, metric_disabled, get_namespace(y_pred)[0], y_pred) + + +@pytest.mark.parametrize( + "array_namespace, device, dtype_name", + yield_namespace_device_dtype_combinations(), + ids=_get_namespace_device_dtype_ids, +) +# All continuous classification metrics, minus multilabel ranking metrics +# (`METRIC_UNDEFINED_BINARY`), which take label indicator input (and thus never +# string input) +@pytest.mark.parametrize( + "metric_name", + sorted( + set(METRICS_SUPPORTING_MIXED_NAMESPACE) + & ( + (set(CONTINUOUS_CLASSIFICATION_METRICS.keys()) | set(CURVE_METRICS.keys())) + - METRIC_UNDEFINED_BINARY + ) + ), +) +def test_array_api_classification_mixed_string_numeric_input( + metric_name, array_namespace, device, dtype_name +): + """Check string inputs and numeric inputs from mixed namespace and devices accepted. + + Non-thresholded (aka continuous/ranking) classification metrics should accept + a mix of string and numeric inputs (numeric input should be able to be of + any supported namespace/device), with array API dispatch enabled. + """ + xp = _array_api_for_tests(array_namespace, device) + metric = ALL_METRICS[metric_name] + + # Binary + y_true = np.array(["a", "b", "a", "a"]) + y_prob_np = np.array([0.5, 0.2, 0.7, 0.6], dtype=dtype_name) + y_prob_xp = xp.asarray(y_prob_np, device=device) + + kwargs = {} + if metric_name in METRICS_WITH_POS_LABEL: + kwargs["pos_label"] = "a" + + with config_context(array_api_dispatch=True): + metric_np = metric(y_true, y_prob_np, **kwargs) + metric_xp = metric(y_true, y_prob_xp, **kwargs) + + if isinstance(metric_np, Tuple): + for out_np, out_xp in zip(metric_np, metric_xp): + _check_output(out_np, out_xp, xp, y_prob_xp) + else: + _check_output(metric_np, metric_xp, xp, y_prob_xp) + + # Multiclass + if metric_name not in METRIC_UNDEFINED_MULTICLASS: + y_true = np.array(["a", "b", "c", "d"]) + y_prob_np = np.array( + [ + [0.5, 0.2, 0.2, 0.1], + [0.4, 0.4, 0.1, 0.1], + [0.1, 0.1, 0.7, 0.1], + [0.1, 0.2, 0.6, 0.1], + ], + dtype=dtype_name, + ) + y_prob_xp = xp.asarray(y_prob_np, device=device) + + with config_context(array_api_dispatch=True): + metric_np = metric(y_true, y_prob_np) + metric_xp = metric(y_true, y_prob_xp) + + if isinstance(metric_np, Tuple): + for out_np, out_xp in zip(metric_np, metric_xp): + _check_output(out_np, out_xp, xp, y_prob_xp) + else: + _check_output(metric_np, metric_xp, xp, y_prob_xp) + + @pytest.mark.parametrize("df_lib_name", ["pandas", "polars"]) @pytest.mark.parametrize("metric_name", sorted(ALL_METRICS)) def test_metrics_dataframe_series(metric_name, df_lib_name): diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 0bd1869695952..154f8666e52d3 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -6,6 +6,7 @@ import itertools import math import os +from collections import namedtuple import numpy import scipy @@ -129,6 +130,61 @@ def _get_namespace_device_dtype_ids(param): return "device2" +def yield_mixed_namespace_input_permutations(): + """Yield mixed namespace and device inputs for testing. + + We do not test for all possible permutations of namespace/device from + `yield_namespace_device_dtype_combinations` (excluding dtype variations, this is + P(8,2)=56), to avoid slow testing and maintenance burden. + + The included selection ensures that the following conversions are tested: + + * non-NumPy to NumPy (including GPU to CPU) + * NumPy to non-NumPy (including CPU to GPU) + * non-NumPy to non-NumPy (GPU to GPU) + * array-api-strict to non-NumPy (this pair also has no special hardware + requirements to allow for local testing) + """ + + NamespaceAndDevice = namedtuple("NamespaceAndDevice", ["xp", "device"]) + + yield ( + NamespaceAndDevice("cupy", None), + NamespaceAndDevice("torch", "cuda"), + "cupy to torch cuda", + ) + yield ( + NamespaceAndDevice("torch", "mps"), + NamespaceAndDevice("numpy", None), + "torch mps to numpy", + ) + yield ( + NamespaceAndDevice("numpy", None), + NamespaceAndDevice("torch", "cuda"), + "numpy to torch cuda", + ) + yield ( + NamespaceAndDevice("numpy", None), + NamespaceAndDevice("torch", "mps"), + "numpy to torch mps", + ) + + try: + import array_api_strict + + device = array_api_strict.Device("device1") + except ImportError: + # This case will generally be skipped when `array_api_strict` is not installed + # but we still include it so it shows in the test output. + device = None + + yield ( + NamespaceAndDevice("array_api_strict", device), + NamespaceAndDevice("torch", "cpu"), + "array_api_strict to torch cpu", + ) + + def _check_array_api_dispatch(array_api_dispatch): """Checks that array API support is functional. @@ -532,9 +588,19 @@ def move_to(*arrays, xp, device): "namespace is Numpy" ) - converted_arrays = [] + arrays_ = arrays + # Down cast float64 `arrays` when highest precision of `xp`/`device` is float32 + if _max_precision_float_dtype(xp, device) == xp.float32: + arrays_ = [] + for array in arrays: + xp_array, _ = get_namespace(array) + if getattr(array, "dtype", None) == xp_array.float64: + arrays_.append(xp_array.astype(array, xp_array.float32)) + else: + arrays_.append(array) - for array, is_sparse, is_none in zip(arrays, sparse_mask, none_mask): + converted_arrays = [] + for array, is_sparse, is_none in zip(arrays_, sparse_mask, none_mask): if is_none: converted_arrays.append(None) elif is_sparse: @@ -562,7 +628,7 @@ def move_to(*arrays, xp, device): # kwargs in the from_dlpack method and their expected # meaning by namespaces implementing the array API spec. # TODO: try removing this once DLPack v1 more widely supported - # TODO: ValueError should not be needed but is in practice: + # TODO: ValueError not needed once min NumPy >=2.4.0: # https://github.com/numpy/numpy/issues/30341 except ( AttributeError, diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index e1abb40fc7a51..13052977ac4d9 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -42,6 +42,7 @@ move_to, np_compat, supported_float_dtypes, + yield_mixed_namespace_input_permutations, yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import ( @@ -147,38 +148,21 @@ def mock_getenv(key): @pytest.mark.parametrize( "array_input, reference", [ - pytest.param(("cupy", None), ("torch", "cuda"), id="cupy to torch cuda"), - pytest.param(("torch", "mps"), ("numpy", None), id="torch mps to numpy"), - pytest.param(("numpy", None), ("torch", "cuda"), id="numpy to torch cuda"), - pytest.param(("numpy", None), ("torch", "mps"), id="numpy to torch mps"), - pytest.param( - ("array_api_strict", None), - ("torch", "mps"), - id="array_api_strict to torch mps", - ), + pytest.param(*args[:2], id=args[2]) + for args in yield_mixed_namespace_input_permutations() ], ) def test_move_to_array_api_conversions(array_input, reference): - """Check conversion between various namespace and devices.""" - if array_input[0] == "array_api_strict": - array_api_strict = pytest.importorskip( - "array_api_strict", reason="array-api-strict not available" - ) - xp = _array_api_for_tests(reference[0], reference[1]) - xp_array = _array_api_for_tests(array_input[0], array_input[1]) + """Check conversion between various namespace-device-pairs.""" + xp_to = _array_api_for_tests(reference.xp, reference.device) + xp_from = _array_api_for_tests(array_input[0], array_input[1]) with config_context(array_api_dispatch=True): - device_ = device(xp.asarray([1], device=reference[1])) - - if array_input[0] == "array_api_strict": - array_device = array_api_strict.Device("CPU_DEVICE") - else: - array_device = array_input[1] - array = xp_array.asarray([1, 2, 3], device=array_device) - - array_out = move_to(array, xp=xp, device=device_) - assert get_namespace(array_out)[0] == xp - assert device(array_out) == device_ + array_in = xp_from.asarray([1, 2, 3], device=array_input.device) + device_reference = device(xp_to.asarray([1], device=reference.device)) + array_out = move_to(array_in, xp=xp_to, device=device_reference) + assert get_namespace(array_out)[0] == xp_to + assert device(array_out) == device_reference def test_move_to_sparse(): @@ -187,7 +171,6 @@ def test_move_to_sparse(): xp_torch = _array_api_for_tests("torch", "cpu") sparse1 = sp.csr_array([0, 1, 2, 3]) - sparse2 = sp.csr_array([0, 1, 0, 1]) numpy_array = numpy.array([1, 2, 3]) with config_context(array_api_dispatch=True): From 3acced3fdb9e008726d48321a8b20c5e45a0a0c9 Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Sat, 7 Mar 2026 16:58:50 +1100 Subject: [PATCH 260/462] FEA Add metric_at_thresholds (#32732) --- doc/api_reference.py | 1 + doc/modules/classification_threshold.rst | 15 +- doc/modules/model_evaluation.rst | 2 +- .../sklearn.metrics/32732.major-feature.rst | 3 + sklearn/metrics/__init__.py | 2 + sklearn/metrics/_ranking.py | 182 ++++++++-- sklearn/metrics/tests/test_ranking.py | 337 ++++++++++++++++-- .../_classification_threshold.py | 2 +- sklearn/tests/test_public_functions.py | 1 + 9 files changed, 491 insertions(+), 54 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/32732.major-feature.rst diff --git a/doc/api_reference.py b/doc/api_reference.py index 1afc689dc837c..52167e270c7ce 100644 --- a/doc/api_reference.py +++ b/doc/api_reference.py @@ -744,6 +744,7 @@ def _get_submodule(module_name, submodule_name): "jaccard_score", "log_loss", "matthews_corrcoef", + "metric_at_thresholds", "multilabel_confusion_matrix", "ndcg_score", "precision_recall_curve", diff --git a/doc/modules/classification_threshold.rst b/doc/modules/classification_threshold.rst index 94a5e0a30b716..fcc746e65eb7c 100644 --- a/doc/modules/classification_threshold.rst +++ b/doc/modules/classification_threshold.rst @@ -1,6 +1,6 @@ .. currentmodule:: sklearn.model_selection -.. _TunedThresholdClassifierCV: +.. _threshold_tunning: ================================================== Tuning the decision threshold for class prediction @@ -63,7 +63,7 @@ Post-tuning the decision threshold One solution to address the problem stated in the introduction is to tune the decision threshold of the classifier once the model has been trained. The -:class:`~sklearn.model_selection.TunedThresholdClassifierCV` tunes this threshold using +:class:`TunedThresholdClassifierCV` tunes this threshold using an internal cross-validation. The optimum threshold is chosen to maximize a given metric. @@ -136,6 +136,17 @@ The option `cv="prefit"` should only be used when the provided classifier was al trained, and you just want to find the best decision threshold using a new validation set. +.. _metric_at_thresholds: + +Visualizing thresholds +---------------------- + +A useful visualization when tuning the decision threshold is a plot of metric values +across different thresholds. This is particularly valuable when there is more than +one metric of interest. The :func:`~sklearn.metrics.metric_at_thresholds` function +computes metric values at each unique score threshold, returning both the metric +array and corresponding threshold values for easy plotting. + .. _FixedThresholdClassifier: Manually setting the decision threshold diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index bdcf3a85f48dd..1ab12270e4c48 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -63,7 +63,7 @@ The most common decisions are done on binary classification tasks, where the res probability of rain a decision is made on how to act (whether to take mitigating measures like an umbrella or not). For classifiers, this is what :term:`predict` returns. -See also :ref:`TunedThresholdClassifierCV`. +See also :ref:`threshold_tunning`. There are many scoring functions which measure different aspects of such a decision, most of them are covered with or derived from the :func:`metrics.confusion_matrix`. diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/32732.major-feature.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/32732.major-feature.rst new file mode 100644 index 0000000000000..c5deeff54dd50 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.metrics/32732.major-feature.rst @@ -0,0 +1,3 @@ +- :func:`metrics.metric_at_thresholds` has been added to compute + a metric's values across all possible thresholds. + By :user:`Carlo Lemos <vitaliset>` and :user:`Lucy Liu <lucyleeow>`. diff --git a/sklearn/metrics/__init__.py b/sklearn/metrics/__init__.py index 85ea7035e738f..0d6e530e266ec 100644 --- a/sklearn/metrics/__init__.py +++ b/sklearn/metrics/__init__.py @@ -42,6 +42,7 @@ det_curve, label_ranking_average_precision_score, label_ranking_loss, + metric_at_thresholds, ndcg_score, precision_recall_curve, roc_auc_score, @@ -161,6 +162,7 @@ "mean_squared_log_error", "mean_tweedie_deviance", "median_absolute_error", + "metric_at_thresholds", "multilabel_confusion_matrix", "mutual_info_score", "nan_euclidean_distances", diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index 6385b3a1c2799..a1d0a69acb60c 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -875,6 +875,52 @@ def _multiclass_roc_auc_score( ) +def _sort_inputs_and_compute_classification_thresholds( + y_true, y_score, sample_weight=None +): + """Validate and sort inputs, and compute classification thresholds. + + Performs the following functions: + + * Array validation on `y_true`, `y_score` and `sample_weight` + * Filters out 0-weighted samples + * Sorts `y_score`, `y_true` and `sample_weight` according to descending `y_score` + * Computes thresholds i.e. indices where sorted `y_score` changes + """ + xp, _, device = get_namespace_and_device(y_score) + + check_consistent_length(y_true, y_score, sample_weight) + y_true = column_or_1d(y_true) + y_score = column_or_1d(y_score) + assert_all_finite(y_true) + assert_all_finite(y_score) + + # Filter out zero-weighted samples, as they should not impact the result + if sample_weight is not None: + sample_weight = column_or_1d(sample_weight) + sample_weight = _check_sample_weight(sample_weight, y_true) + nonzero_weight_mask = sample_weight != 0 + y_true = y_true[nonzero_weight_mask] + y_score = y_score[nonzero_weight_mask] + sample_weight = sample_weight[nonzero_weight_mask] + + # sort scores and corresponding truth values + desc_score_indices = xp.argsort(y_score, stable=True, descending=True) + y_score = y_score[desc_score_indices] + y_true = y_true[desc_score_indices] + if sample_weight is not None: + sample_weight = sample_weight[desc_score_indices] + + # y_score typically has many tied values. Here we extract + # the indices associated with the distinct values. We also + # concatenate a value for the end of the curve. + distinct_value_indices = xp.nonzero(xp.diff(y_score))[0] + threshold_idxs = xp.concat( + [distinct_value_indices, xp.asarray([size(y_true) - 1], device=device)] + ) + return y_true, y_score, sample_weight, threshold_idxs + + @_deprecate_positional_args(version="1.11") @validate_params( { @@ -971,37 +1017,13 @@ def confusion_matrix_at_thresholds( ) y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) - check_consistent_length(y_true, y_score, sample_weight) - y_true = column_or_1d(y_true) - y_score = column_or_1d(y_score) - assert_all_finite(y_true) - assert_all_finite(y_score) - - # Filter out zero-weighted samples, as they should not impact the result - if sample_weight is not None: - sample_weight = column_or_1d(sample_weight) - sample_weight = _check_sample_weight(sample_weight, y_true) - nonzero_weight_mask = sample_weight != 0 - y_true = y_true[nonzero_weight_mask] - y_score = y_score[nonzero_weight_mask] - sample_weight = sample_weight[nonzero_weight_mask] - - # sort scores and corresponding truth values - desc_score_indices = xp.argsort(y_score, stable=True, descending=True) - y_score = y_score[desc_score_indices] - y_true = y_true[desc_score_indices] - if sample_weight is not None: - weight = sample_weight[desc_score_indices] - else: - weight = 1.0 - - # y_score typically has many tied values. Here we extract - # the indices associated with the distinct values. We also - # concatenate a value for the end of the curve. - distinct_value_indices = xp.nonzero(xp.diff(y_score))[0] - threshold_idxs = xp.concat( - [distinct_value_indices, xp.asarray([size(y_true) - 1], device=device)] + y_true, y_score, weight, threshold_idxs = ( + _sort_inputs_and_compute_classification_thresholds( + y_true, y_score, sample_weight + ) ) + if weight is None: + weight = 1.0 # accumulate the true positives with decreasing threshold max_float_dtype = _max_precision_float_dtype(xp, device) @@ -2223,3 +2245,103 @@ def top_k_accuracy_score( return float(np.sum(hits)) else: return float(np.dot(hits, sample_weight)) + + +@validate_params( + { + "y_true": ["array-like"], + "y_score": ["array-like"], + "metric_func": [callable], + "sample_weight": ["array-like", None], + "metric_params": [dict, None], + }, + prefer_skip_nested_validation=True, +) +def metric_at_thresholds( + y_true, + y_score, + metric_func, + *, + sample_weight=None, + metric_params=None, +): + r"""Compute `metric_func` per threshold for :term:`binary` data. + + Aids visualization of metric values across thresholds when tuning the + :ref:`decision threshold <threshold_tunning>`. + + Read more in the :ref:`User Guide <metric_at_thresholds>`. + + .. versionadded:: 1.9 + + Parameters + ---------- + y_true : array-like of shape (n_samples,) + Ground truth (correct) target labels. + + y_score : array-like of shape (n_samples,) + Continuous prediction scores, either estimated probabilities of the + positive class or output of a :term:`decision_function`. + + metric_func : callable + The metric function to use. It will be called as + `metric_func(y_true, y_pred, **metric_params)`, where `y_pred` are + thresholded predictions, internally computed as + `y_pred = (y_score >= threshold)`. The output should be + a single numeric or a collection where each element has the same size. + + sample_weight : array-like of shape (n_samples,), default=None + Sample weights. If not `None`, will be passed to `metric_func`. + + metric_params : dict, default=None + Parameters to pass to `metric_func`. + + Returns + ------- + metric_values : ndarray of shape (n_thresholds,) or (n_thresholds, \*n_outputs) + The scores associated with each threshold. If `metric_func` returns a + collection (e.g., a tuple of floats), the output would be a 2D array + of shape (n_thresholds, \*n_outputs). + + thresholds : ndarray of shape (n_thresholds,) + The thresholds used to compute the scores. + + See Also + -------- + confusion_matrix_at_thresholds : Compute binary confusion matrix per threshold. + precision_recall_curve : Compute precision-recall pairs for different + probability thresholds. + det_curve : Compute error rates for different probability thresholds. + roc_curve : Compute Receiver operating characteristic (ROC) curve. + + Examples + -------- + >>> import numpy as np + >>> from sklearn.metrics import accuracy_score, metric_at_thresholds + >>> y_true = np.array([0, 0, 1, 1]) + >>> y_score = np.array([0.1, 0.4, 0.35, 0.8]) + >>> metric_values, thresholds = metric_at_thresholds( + ... y_true, y_score, accuracy_score) + >>> thresholds + array([0.8 , 0.4 , 0.35, 0.1 ]) + >>> metric_values + array([0.75, 0.5 , 0.75, 0.5 ]) + """ + y_true, y_score, sample_weight, threshold_idxs = ( + _sort_inputs_and_compute_classification_thresholds( + y_true, y_score, sample_weight + ) + ) + metric_params = { + **(metric_params or {}), + **({"sample_weight": sample_weight} if sample_weight is not None else {}), + } + + thresholds = y_score[threshold_idxs] + metric_values = [] + for threshold in thresholds: + y_pred = (y_score >= threshold).astype(np.int32) + metric_values.append(metric_func(y_true, y_pred, **metric_params)) + + metric_values = np.asarray(metric_values) + return metric_values, thresholds diff --git a/sklearn/metrics/tests/test_ranking.py b/sklearn/metrics/tests/test_ranking.py index dbb77f69f9c0e..abab50ea5def6 100644 --- a/sklearn/metrics/tests/test_ranking.py +++ b/sklearn/metrics/tests/test_ranking.py @@ -13,19 +13,27 @@ accuracy_score, auc, average_precision_score, + confusion_matrix, confusion_matrix_at_thresholds, coverage_error, dcg_score, det_curve, label_ranking_average_precision_score, label_ranking_loss, + metric_at_thresholds, ndcg_score, precision_recall_curve, + precision_score, + recall_score, roc_auc_score, roc_curve, top_k_accuracy_score, ) -from sklearn.metrics._ranking import _dcg_sample_scores, _ndcg_sample_scores +from sklearn.metrics._ranking import ( + _dcg_sample_scores, + _ndcg_sample_scores, + _sort_inputs_and_compute_classification_thresholds, +) from sklearn.model_selection import train_test_split from sklearn.preprocessing import label_binarize from sklearn.random_projection import _sparse_random_matrix @@ -195,25 +203,6 @@ def _partial_roc(y_true, y_predict, max_fpr): return 0.5 * (1 + (partial_auc - min_area) / (max_area - min_area)) -def test_confusion_matrix_at_thresholds(global_random_seed): - """Smoke test for confusion_matrix_at_thresholds.""" - rng = np.random.RandomState(global_random_seed) - - n_samples = 100 - y_true = rng.randint(0, 2, size=100) - y_score = rng.uniform(size=100) - - n_pos = np.sum(y_true) - n_neg = n_samples - n_pos - - tns, fps, fns, tps, thresholds = confusion_matrix_at_thresholds(y_true, y_score) - - assert len(tns) == len(fps) == len(fns) == len(tps) == len(thresholds) - assert_allclose(tps + fns, n_pos) - assert_allclose(tns + fps, n_neg) - assert_allclose(tns + fps + fns + tps, n_samples) - - @pytest.mark.parametrize("drop", [True, False]) def test_roc_curve(drop): # Test Area under Receiver Operating Characteristic (ROC) curve @@ -859,6 +848,104 @@ def test_auc_score_non_binary_class(): roc_auc_score(y_true, y_pred) +def test_sort_inputs_and_compute_classification_thresholds_input_validation(): + """Test `_sort_inputs_and_compute_classification_thresholds` input validation.""" + # Inconsistent lengths + y_true = np.array([0, 1, 0]) + y_score = np.array([0.1, 0.9]) + + with pytest.raises(ValueError, match="inconsistent numbers of samples"): + _sort_inputs_and_compute_classification_thresholds(y_true, y_score) + + # Non-finite value + y_true = np.array([0, 1, 0, 1]) + y_score = np.array([0.1, np.nan, 0.3, 0.7]) + + with pytest.raises(ValueError, match="Input.*contains NaN"): + _sort_inputs_and_compute_classification_thresholds(y_true, y_score) + + +def test_sort_inputs_and_compute_classification_thresholds_zero_weights(): + """Test zero weights in `_sort_inputs_and_compute_classification_thresholds`.""" + y_true = np.array([0, 1, 0, 1, 0, 1]) + y_score = np.array([0.1, 0.9, 0.3, 0.7, 0.5, 0.2]) + # Indices 0 and 4 zero weight + sample_weight = np.array([0.0, 2.0, 1.0, 1.5, 0.0, 0.8]) + + y_true_sorted, y_score_sorted, weight_sorted, _ = ( + _sort_inputs_and_compute_classification_thresholds( + y_true, y_score, sample_weight + ) + ) + + assert len(y_true_sorted) == len(y_score_sorted) == len(weight_sorted) == 4 + assert 0.1 not in y_score_sorted + assert 0.5 not in y_score_sorted + + # Check default `sample_weight=None` gives None + _, _, weight, _ = _sort_inputs_and_compute_classification_thresholds( + y_true, y_score + ) + assert weight is None + + # All zero weights raises error + y_true = np.array([0, 1, 0]) + y_score = np.array([0.1, 0.9, 0.3]) + sample_weight = np.array([0.0, 0.0, 0.0]) + + with pytest.raises(ValueError, match="Sample weights must contain at least"): + _sort_inputs_and_compute_classification_thresholds( + y_true, y_score, sample_weight + ) + + +def test_sort_inputs_and_compute_classification_thresholds_sorting(): + """Test sorting in `_sort_inputs_and_compute_classification_thresholds`.""" + y_true = np.array([0, 1, 0, 1, 1]) + y_score = np.array([0.1, 0.9, 0.3, 0.7, 0.3]) + sample_weight = np.array([1.0, 2.0, 1.5, 0.5, 0.3]) + + y_true_sorted, y_score_sorted, weight_sorted, threshold_idxs = ( + _sort_inputs_and_compute_classification_thresholds( + y_true, y_score, sample_weight + ) + ) + # Check descending sort + assert np.all(y_score_sorted[:-1] >= y_score_sorted[1:]) + assert_array_equal(weight_sorted, np.array([2.0, 0.5, 1.5, 0.3, 1.0])) + assert_array_equal(threshold_idxs, np.array([0, 1, 3, 4])) + # Check stable sort + assert_array_equal(y_score_sorted[2:4], [0.3, 0.3]) + assert_array_equal(y_true_sorted[2:4], [0, 1]) + + # All identical scores + y_score_same = np.array([0.5, 0.5, 0.5, 0.5, 0.5]) + _, _, _, threshold_idxs = _sort_inputs_and_compute_classification_thresholds( + y_true, y_score_same + ) + # Threshold is the final index + assert_array_equal(threshold_idxs, np.array([4])) + + +def test_confusion_matrix_at_thresholds(global_random_seed): + """Smoke test for confusion_matrix_at_thresholds.""" + rng = np.random.RandomState(global_random_seed) + + n_samples = 100 + y_true = rng.randint(0, 2, size=100) + y_score = rng.uniform(size=100) + + n_pos = np.sum(y_true) + n_neg = n_samples - n_pos + + tns, fps, fns, tps, thresholds = confusion_matrix_at_thresholds(y_true, y_score) + + assert len(tns) == len(fps) == len(fns) == len(tps) == len(thresholds) + assert_allclose(tps + fns, n_pos) + assert_allclose(tns + fps, n_neg) + assert_allclose(tns + fps + fns + tps, n_samples) + + @pytest.mark.parametrize("curve_func", CURVE_FUNCS) def test_confusion_matrix_at_thresholds_multiclass_error(curve_func): rng = check_random_state(404) @@ -2307,6 +2394,216 @@ def test_roc_curve_with_probablity_estimates(global_random_seed): assert np.isinf(thresholds[0]) +def _dummy_metric(y_true, y_pred, sample_weight=None): + """Dummy metric that returns a tuple of two values.""" + if sample_weight is None: + sample_weight = np.ones_like(y_pred) + y_pred_sum = np.sum(y_pred * sample_weight) + y_true_sum = np.sum(y_true * sample_weight) + return (y_pred_sum, y_true_sum) + + +@pytest.mark.parametrize( + "metric_func", + [ + accuracy_score, + precision_score, + roc_auc_score, + # Test metric that returns tuple instead of single float + _dummy_metric, + ], +) +@pytest.mark.parametrize("sample_weight", [None, np.array([1, 2, 1, 0, 2])]) +def test_metric_at_thresholds(metric_func, sample_weight): + """Test `metric_at_thresholds` outputs correct.""" + y_true = np.array([0, 0, 1, 1, 1]) + y_score = np.array([0.1, 0.6, 0.4, 0.9, 0.4]) + + metric_values, thresholds = metric_at_thresholds( + y_true, y_score, metric_func, sample_weight=sample_weight + ) + + # Calculate expected scores manually at each threshold + expected_scores = [] + for threshold in thresholds: + y_pred = (y_score >= threshold).astype(int) + expected_scores.append(metric_func(y_true, y_pred, sample_weight=sample_weight)) + + assert len(metric_values) == len(thresholds) + # Thresholds are descending + assert np.all(np.diff(thresholds) <= 0) + # Thresholds correspond to unique `y_score`s + if sample_weight is not None: + # Filter out 0 weight in `y_score` + assert_allclose( + thresholds, np.sort(np.unique(y_score[sample_weight != 0]))[::-1] + ) + else: + assert_allclose(thresholds, np.sort(np.unique(y_score))[::-1]) + assert_allclose(metric_values, expected_scores) + + +def _dummy_metric_no_sample_weight(y_true, y_pred): + """Dummy metric that does not accept `sample_weight`.""" + return (np.sum(y_pred), np.sum(y_true)) + + +def test_metric_at_thresholds_sample_weight_error(): + """Test `TypeError` is raised when `metric_func` does not take `sample_weight`.""" + y_true = np.array([0, 0, 1, 1, 1]) + y_score = np.array([0.1, 0.4, 0.35, 0.6, 0.9]) + sample_weight = np.array([1, 2, 3, 1, 2]) + + with pytest.raises(TypeError, match="got an unexpected keyword argument"): + _, _ = metric_at_thresholds( + y_true, y_score, _dummy_metric_no_sample_weight, sample_weight=sample_weight + ) + + +@pytest.mark.parametrize("normalize", [True, False]) +def test_metric_at_thresholds_metric_params(normalize): + """Test `metric_params` passed correctly to `metric_at_thresholds`.""" + y_true = np.array([0, 0, 1, 1, 1]) + y_score = np.array([0.1, 0.4, 0.35, 0.6, 0.9]) + + metric_values, thresholds = metric_at_thresholds( + y_true, y_score, accuracy_score, metric_params={"normalize": normalize} + ) + + expected_values = [] + for threshold in thresholds: + y_pred = (y_score >= threshold).astype(int) + expected_values.append(accuracy_score(y_true, y_pred, normalize=normalize)) + + assert_allclose(metric_values, expected_values) + assert len(thresholds) == len(np.unique(y_score)) + + +@pytest.mark.parametrize("pos_label", [0, 1]) +def test_metric_at_thresholds_pos_label(pos_label): + """Test `pos_label` is passed correctly to `metric_at_thresholds`.""" + y_true = np.array([0, 0, 1, 1, 1]) + y_score = np.array([0.1, 0.6, 0.4, 0.9, 0.4]) + + metric_values, thresholds = metric_at_thresholds( + y_true, + y_score, + precision_score, + metric_params={"pos_label": pos_label, "zero_division": 0}, + ) + + expected_scores = [] + for threshold in thresholds: + y_pred = (y_score >= threshold).astype(int) + expected_scores.append( + precision_score(y_true, y_pred, pos_label=pos_label, zero_division=0) + ) + + assert_allclose(metric_values, expected_scores) + + +def test_metric_at_thresholds_y_score_order(): + """Test `y_score` order does not effect `metric_at_thresholds`.""" + y_true = np.array([0, 0, 1, 1, 1]) + y_score = np.array([0.9, 0.6, 0.5, 0.1, 0.4]) + sample_weight = np.array([1, 2, 3, 1, 2]) + # Permutate `y_true`, `y_score` and `sample_weight` + rng = check_random_state(42) + perm_indices = rng.permutation(len(y_score)) + y_true_perm = y_true[perm_indices] + y_score_perm = y_score[perm_indices] + sample_weight_perm = sample_weight[perm_indices] + + metric_1, thresh_1 = metric_at_thresholds( + y_true, y_score, accuracy_score, sample_weight=sample_weight + ) + metric_2, thresh_2 = metric_at_thresholds( + y_true_perm, y_score_perm, accuracy_score, sample_weight=sample_weight_perm + ) + + assert_allclose(metric_1, metric_2) + assert_allclose(thresh_1, thresh_2) + + +def test_metric_at_thresholds_y_score_order_duplicate_y_score(): + """Test duplicate `y_score` edge cases in `metric_at_thresholds`. + + If there are duplicate `y_score` values and `y_true` differs between + these duplicate values, `y_score` order will not affect metric output. + + However, if there are duplicate `y_score` values and `sample_weight` differs + between these duplicate values, `y_score` order can affect metric output, + as stable sort preserves relative order. + """ + # duplicate scores + y_score = np.array([0.6, 0.9, 0.1, 0.4, 0.6]) + # `y_true` differs between duplicates + y_true_1 = np.array([1, 0, 1, 1, 0]) + y_true_2 = np.array([0, 0, 1, 1, 1]) + + metric_1, thresh_1 = metric_at_thresholds(y_true_1, y_score, accuracy_score) + metric_2, thresh_2 = metric_at_thresholds(y_true_2, y_score, accuracy_score) + + assert_allclose(thresh_1, thresh_2) + assert_allclose(metric_1, metric_2) + + # `sample_weight` differs between duplicates + sample_weight_1 = np.array([1, 2, 1, 0, 2]) + sample_weight_2 = np.array([2, 2, 1, 0, 1]) + + metric_1, thresh_1 = metric_at_thresholds( + y_true_1, y_score, accuracy_score, sample_weight=sample_weight_1 + ) + metric_2, thresh_2 = metric_at_thresholds( + y_true_1, y_score, accuracy_score, sample_weight=sample_weight_2 + ) + + # Thresholds should still be the same + assert_allclose(thresh_1, thresh_2) + # Metric output differs for the test data + with pytest.raises(AssertionError): + assert_allclose(metric_1, metric_2) + + +def test_metric_at_thresholds_consistency_with_confusion_matrix(): + """Test `metric_at_thresholds` consistency with `confusion_matrix_at_thresholds`. + + This also checks output when `metric_func` returns a tuple of arrays. + """ + y_true = np.array([0, 0, 1, 1, 1]) + y_score = np.array([0.1, 0.4, 0.4, 0.6, 0.9]) + + tns, fps, fns, tps, thresholds_cm = confusion_matrix_at_thresholds( + y_true, + y_score, + ) + + metric_values, thresholds = metric_at_thresholds( + y_true, y_score, confusion_matrix, metric_params={"labels": [0, 1]} + ) + + assert_array_equal(thresholds, thresholds_cm) + + # As `labels=[0, 1]` -> [TN, FP, FN, TP] + assert_array_equal(metric_values[:, 0, 0], tns) + assert_array_equal(metric_values[:, 0, 1], fps) + assert_array_equal(metric_values[:, 1, 0], fns) + assert_array_equal(metric_values[:, 1, 1], tps) + + +def test_metric_at_thresholds_with_nan_outputs(): + """Test `metric_at_thresholds` with NaN output.""" + # No positive labels means recall undefined (TP + FN = 0) at all thresholds + y_true = np.array([0, 0, 0, 0, 0]) + y_score = np.array([0.1, 0.2, 0.3, 0.4, 0.5]) + + metric_values, _ = metric_at_thresholds( + y_true, y_score, recall_score, metric_params={"zero_division": np.nan} + ) + + assert np.all(np.isnan(metric_values)) + + # TODO(1.11): remove this test def test_confusion_matrix_at_thresholds_positional_args_deprecation(): y_true = np.array([0, 1, 1, 0]) diff --git a/sklearn/model_selection/_classification_threshold.py b/sklearn/model_selection/_classification_threshold.py index ea16b91dbe6e2..381ee42fee5eb 100644 --- a/sklearn/model_selection/_classification_threshold.py +++ b/sklearn/model_selection/_classification_threshold.py @@ -504,7 +504,7 @@ class TunedThresholdClassifierCV(BaseThresholdClassifier): into a class label. The tuning is done by optimizing a binary metric, potentially constrained by another metric. - Read more in the :ref:`User Guide <TunedThresholdClassifierCV>`. + Read more in the :ref:`User Guide <threshold_tunning>`. .. versionadded:: 1.5 diff --git a/sklearn/tests/test_public_functions.py b/sklearn/tests/test_public_functions.py index 51e4e38a50c45..c19644fe7ffc7 100644 --- a/sklearn/tests/test_public_functions.py +++ b/sklearn/tests/test_public_functions.py @@ -264,6 +264,7 @@ def _check_function_param_validation( "sklearn.metrics.mean_squared_log_error", "sklearn.metrics.mean_tweedie_deviance", "sklearn.metrics.median_absolute_error", + "sklearn.metrics.metric_at_thresholds", "sklearn.metrics.multilabel_confusion_matrix", "sklearn.metrics.mutual_info_score", "sklearn.metrics.ndcg_score", From 438cb99b2462b1a1cb7cd477903fb91578249a6f Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Mon, 9 Mar 2026 08:21:23 +0100 Subject: [PATCH 261/462] DOC mention Newton boosting for HGBT in user guide (#33467) --- doc/modules/ensemble.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/modules/ensemble.rst b/doc/modules/ensemble.rst index 028a4d380dfca..3e813026c687d 100644 --- a/doc/modules/ensemble.rst +++ b/doc/modules/ensemble.rst @@ -460,7 +460,8 @@ is the number of samples at the node. :class:`HistGradientBoostingClassifier` and :class:`HistGradientBoostingRegressor`, in contrast, do not require sorting the -feature values and instead use a data-structure called a histogram, where the +feature values and instead use a data-structure called +`histogram <https://en.wikipedia.org/wiki/Histogram>`_ , where the samples are implicitly ordered. Building a histogram has a :math:`\mathcal{O}(n)` complexity, so the node splitting procedure has a :math:`\mathcal{O}(n_\text{features} \times n)` complexity, much smaller @@ -474,6 +475,11 @@ values, but it only happens once at the very beginning of the boosting process (not at each node, like in :class:`GradientBoostingClassifier` and :class:`GradientBoostingRegressor`). +A second major reason for being faster is the fact that +:class:`HistGradientBoostingClassifier` and :class:`HistGradientBoostingRegressor` both +use second order information about the loss, i.e. the Hessian. This is called Newton +boosting and avoids the line-search step of the ordinary gradient boosting. + Finally, many parts of the implementation of :class:`HistGradientBoostingClassifier` and :class:`HistGradientBoostingRegressor` are parallelized. From d3dbfe2c854711c84e6ed3eb0e6e525fe7902018 Mon Sep 17 00:00:00 2001 From: James Lamb <jaylamb20@gmail.com> Date: Mon, 9 Mar 2026 04:03:49 -0500 Subject: [PATCH 262/462] DOC update LightGBM links (#33486) --- doc/modules/ensemble.rst | 2 +- sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py | 4 ++-- sklearn/ensemble/_hist_gradient_boosting/grower.py | 2 +- sklearn/ensemble/_hist_gradient_boosting/utils.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/modules/ensemble.rst b/doc/modules/ensemble.rst index 3e813026c687d..c75b12830d307 100644 --- a/doc/modules/ensemble.rst +++ b/doc/modules/ensemble.rst @@ -55,7 +55,7 @@ Histogram-Based Gradient Boosting Scikit-learn 0.21 introduced two new implementations of gradient boosted trees, namely :class:`HistGradientBoostingClassifier` and :class:`HistGradientBoostingRegressor`, inspired by -`LightGBM <https://github.com/Microsoft/LightGBM>`__ (See [LightGBM]_). +`LightGBM <https://github.com/lightgbm-org/LightGBM>`__ (See [LightGBM]_). These histogram-based estimators can be **orders of magnitude faster** than :class:`GradientBoostingClassifier` and diff --git a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py index a2977cdc6b64c..e96267228e081 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py +++ b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py @@ -1493,7 +1493,7 @@ class HistGradientBoostingRegressor(RegressorMixin, BaseHistGradientBoosting): usecase example of this feature. This implementation is inspired by - `LightGBM <https://github.com/Microsoft/LightGBM>`_. + `LightGBM <https://github.com/lightgbm-org/LightGBM>`_. Read more in the :ref:`User Guide <histogram_based_gradient_boosting>`. @@ -1894,7 +1894,7 @@ class HistGradientBoostingClassifier(ClassifierMixin, BaseHistGradientBoosting): missing values are mapped to whichever child has the most samples. This implementation is inspired by - `LightGBM <https://github.com/Microsoft/LightGBM>`_. + `LightGBM <https://github.com/lightgbm-org/LightGBM>`_. Read more in the :ref:`User Guide <histogram_based_gradient_boosting>`. diff --git a/sklearn/ensemble/_hist_gradient_boosting/grower.py b/sklearn/ensemble/_hist_gradient_boosting/grower.py index 6ebb5154bdf64..d734c390ad824 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/grower.py +++ b/sklearn/ensemble/_hist_gradient_boosting/grower.py @@ -661,7 +661,7 @@ def _compute_interactions(self, node): / \ / \ Right split at feature 2 has only group {1, 2} from now on. LightGBM uses the same logic for overlapping groups. See - https://github.com/microsoft/LightGBM/issues/4481 for details. + https://github.com/lightgbm-org/LightGBM/issues/4481 for details. Parameters: ---------- diff --git a/sklearn/ensemble/_hist_gradient_boosting/utils.py b/sklearn/ensemble/_hist_gradient_boosting/utils.py index a0f917d3926c2..3107177cac87a 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/utils.py +++ b/sklearn/ensemble/_hist_gradient_boosting/utils.py @@ -72,7 +72,7 @@ def get_equivalent_estimator(estimator, lib="lightgbm", n_classes=None): # LightGBM 3.0 introduced a different scaling of the hessian for the multiclass # case. # It is equivalent of scaling the learning rate. - # See https://github.com/microsoft/LightGBM/pull/3256. + # See https://github.com/lightgbm-org/LightGBM/pull/3256. if n_classes is not None: lightgbm_params["learning_rate"] *= n_classes / (n_classes - 1) From bfb45db1c92232e74a8c7f86b839536de4eeb6e8 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 9 Mar 2026 05:12:20 -0400 Subject: [PATCH 263/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33487) Co-authored-by: Lock file bot <noreply@github.com> --- .../github/pylatest_pip_scipy_dev_linux-64_conda.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index 3069757ddc1ef..c60f88b51fc45 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -24,26 +24,26 @@ https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.cond https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa -# pip charset-normalizer @ https://files.pythonhosted.org/packages/67/ff/f6b948ca32e4f2a4576aa129d8bed61f2e0543bf9f5f2b7fc3758ed005c9/charset_normalizer-3.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838 +# pip charset-normalizer @ https://files.pythonhosted.org/packages/38/9c/71336bff6934418dc8d1e8a1644176ac9088068bc571da612767619c97b3/charset_normalizer-3.4.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 # pip coverage @ https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea -# pip imagesize @ https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl#sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b +# pip imagesize @ https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl#sha256=5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip markupsafe @ https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 # pip meson @ https://files.pythonhosted.org/packages/9c/d5/582789135863eec7c8c1fa31fbde401b3d5d82dbbb4a0973351a1698f738/meson-1.10.1-py3-none-any.whl#sha256=fe43d1cc2e6de146fbea78f3a062194bcc0e779efc8a0f0d7c35544dfb86731f # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 -# pip platformdirs @ https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl#sha256=9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd +# pip platformdirs @ https://files.pythonhosted.org/packages/63/d7/97f7e3a6abb67d8080dd406fd4df842c2be0efaf712d1c899c32a075027c/platformdirs-4.9.4-py3-none-any.whl#sha256=68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b # pip roman-numerals @ https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl#sha256=647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7 From c278d029431a735a4966bd70e0a88229ad47acdf Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 9 Mar 2026 05:14:53 -0400 Subject: [PATCH 264/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33489) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/circle/doc_linux-64_conda.lock | 81 +++++++++-------- .../doc_min_dependencies_linux-64_conda.lock | 55 ++++++------ build_tools/github/debian_32bit_lock.txt | 18 ++-- ...latest_conda_forge_mkl_linux-64_conda.lock | 88 +++++++++---------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 25 +++--- .../pylatest_conda_forge_osx-arm64_conda.lock | 60 ++++++------- ...st_pip_openblas_pandas_linux-64_conda.lock | 14 +-- ...n_conda_forge_arm_linux-aarch64_conda.lock | 44 +++++----- ...nblas_min_dependencies_linux-64_conda.lock | 39 ++++---- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 23 +++-- ...min_conda_forge_openblas_win-64_conda.lock | 28 +++--- build_tools/github/ubuntu_atlas_lock.txt | 16 ++-- 12 files changed, 246 insertions(+), 245 deletions(-) diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 05dccd161d9d8..ce61b78abae09 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -9,7 +9,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.co https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda#06901733131833f5edd68cf3d9679798 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 @@ -36,6 +36,7 @@ https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b +https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda#7af961ef4aa2c1136e11dd43ded245ab https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -43,11 +44,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#e https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e -https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda#2c42649888aac645608191ffdc80d13a +https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.8.1-h1fbca29_0.conda#d83958768626b3c8471ce032e28afcd3 https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda#a77f85f77be52ff59391544bfe73390a +https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.3-hecca717_0.conda#937ca49a245fcf2b88d51b6b52959426 https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717_0.conda#dbe3ec0f120af456b3477743ffd99b74 https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 @@ -64,7 +66,6 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.c https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b -https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.20-h4ab18f5_0.conda#a587892d3c13b6621a6091be690dbca2 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -74,7 +75,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd -https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.0-hecca717_0.conda#9a6117aee038999ffefe6082ff1e9a81 +https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.1-hecca717_0.conda#2a2170a3e5c9a354d09e4be718c43235 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 @@ -85,17 +86,16 @@ https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#34672 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.0-hc31b594_0.conda#f3ac2d8b1b3ac0ba4e42050279ef6ce8 -https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 -https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.1-hc31b594_0.conda#68ceffc6cadae61846a207cae60de094 +https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_0.conda#b7113551db5a3e2403cdd052c66e9999 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 @@ -105,37 +105,38 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_101.conda#83aa53cb3f5fc849851a84d777a60551 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 -https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 +https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda#22d5cc5fb45aab8ed3c00cde2938b825 +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.0-hcfa2d63_0.conda#e226d3dbe1e2482fd8e15cb924fd1e7c https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 -https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.3-h8d634f6_0.conda#792d5b6e99677177f5527a758a02bc07 -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 -https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h387f397_9.conda#8035e5b54c08429354d5d64027041cad +https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda#755b096086851e1193f3b10347415d7c https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda#537296d57ea995666c68c821b00e360b +https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_101.conda#9902aeb08445c03fb31e01beeb173988 https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_101.conda#dec96579f9a7035a59492bf6ee613b53 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2#576d629e47797577ab0f1b351297ef4a -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda#beb628209b2b354b98203066f90b3287 https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.14-py311hd8ed1ab_3.conda#85bce7761323f3b9b0854437afde219c +https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.15-py311hd8ed1ab_0.conda#bf0d09d5c2b61aaf7b11c551c8545cfa https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2#961b3a227b437d82ad7054484cfa71b2 @@ -143,7 +144,7 @@ https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/doit-0.37.0-pyhcf101f3_0.conda#37b3d4c558f2bb2b5378c43f4d6f1fb5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac @@ -157,16 +158,16 @@ https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b96 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.0-hf7376ad_0.conda#213f51bbcce2964ff2ec00d0fdd38541 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.16.0-pyhcf101f3_0.conda#648a62e4e4cf1605abf73e7f48b87d5e +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.17.0-pyhcf101f3_0.conda#538f3a813e0805c7e3f037603f12a400 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 @@ -183,7 +184,6 @@ https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#4 https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda#23029aae904a2ba587daba708208012f https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda#a61bf9ec79426938ff785eb69dbb1960 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 -https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda#a24add9a3bababee946f3bc1c829acfe https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h57d2397_2.conda#759edfe34f07c5c4565b6c5ec0c7fb17 https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f @@ -215,7 +215,6 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0. https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 -https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_0.conda#ea5be9abc2939c8431893b4e123a2065 https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda#7c5ebdc286220e8021bf55e6384acd67 https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 @@ -233,20 +232,21 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c +https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b11e360fc4de2b0035fc8aaa74f17fd6 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py311h2e04523_1.conda#a8105076864776eceae69d64d30e24d7 https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 -https://conda.anaconda.org/conda-forge/noarch/plotly-6.5.2-pyhd8ed1ab_0.conda#7702bcd70891dd0154d765a69e1afa94 +https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda#3e9427ee186846052e81fadde8ebe96a https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.14-hd8ed1ab_3.conda#ba766ecdcff5b3f015498ad81f4d266e +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.15-hd8ed1ab_0.conda#8793751936480e56ce4047b4f54b997f https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 @@ -268,21 +268,20 @@ https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h9837d23_1.conda#e30309a8776e0e969fa7092d7801641b +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda#7b8bace4943e0dc345fc45938826f2b8 -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.1-pyhcf101f3_0.conda#b8e1f542770b5f88b663012fc77f9628 -https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.3-pyhcf101f3_0.conda#8ecf1988b05090fafc3387ada297e22b https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.conda#3ac73c673df24589b5b84d43a4afd235 https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_1.conda#f4dda6316cc4718cbcab7009b5d60c41 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 @@ -291,15 +290,15 @@ https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.cond https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.0-pyhcf101f3_0.conda#97624651e6fc9ca05effe0b4a80766e3 +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.1-pyhcf101f3_0.conda#4552b601cf622dea2bb5075baccc2c5b https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-h17e89b9_5.conda#6c4f73c9a7e9b51f3a8e321c3e867bb6 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.2.20-pyhd8ed1ab_0.conda#9ee854e39faa623a8e79ae20ac374f1f +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.3.3-pyhd8ed1ab_0.conda#cecacab21bc8f4ed17fac11bc8b08cf0 https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 670e19a21060b..e1fc5ce83ca2a 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -10,13 +10,13 @@ https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he0 https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_463.conda#291727757c8a8613312aaa4b52e82ad8 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda#06901733131833f5edd68cf3d9679798 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -49,11 +49,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#e https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e -https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.7.1-h8fae777_3.conda#2c42649888aac645608191ffdc80d13a +https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.8.1-h1fbca29_0.conda#d83958768626b3c8471ce032e28afcd3 https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 +https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.3-hecca717_0.conda#937ca49a245fcf2b88d51b6b52959426 https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d @@ -85,7 +86,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd -https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.0-hecca717_0.conda#9a6117aee038999ffefe6082ff1e9a81 +https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.1-hecca717_0.conda#2a2170a3e5c9a354d09e4be718c43235 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_5.conda#6a0eb48e58684cca4d7acc8b7a0fd3c7 @@ -95,19 +96,18 @@ https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#34672 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.0-hc31b594_0.conda#f3ac2d8b1b3ac0ba4e42050279ef6ce8 -https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.2-h59595ed_0.conda#4336bd67920dd504cd8c6761d6a99645 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.1-hc31b594_0.conda#68ceffc6cadae61846a207cae60de094 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_0.conda#b7113551db5a3e2403cdd052c66e9999 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda#1d4c18d75c51ed9d00092a891a547a7d https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 @@ -118,29 +118,30 @@ https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-de https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_0.conda#70a09b6817c7ad694ef4543204c59c25 +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda#b52b769cd13f7adaa6ccdc68ef801709 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.3.0-h316e467_3.conda#22d5cc5fb45aab8ed3c00cde2938b825 +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.0-hcfa2d63_0.conda#e226d3dbe1e2482fd8e15cb924fd1e7c https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.3-h8d634f6_0.conda#792d5b6e99677177f5527a758a02bc07 -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 -https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda#def531a3ac77b7fb8c21d17bb5d0badb +https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_101.conda#9902aeb08445c03fb31e01beeb173988 https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_101.conda#dec96579f9a7035a59492bf6ee613b53 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda#beb628209b2b354b98203066f90b3287 https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -148,7 +149,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.con https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac @@ -159,8 +160,9 @@ https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.0-hf7376ad_0.conda#213f51bbcce2964ff2ec00d0fdd38541 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc @@ -194,22 +196,22 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 -https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_0.conda#ea5be9abc2939c8431893b4e123a2065 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd -https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_0.conda#937834a2fb235626c3f8e8a83afd6b75 +https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 +https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda#9f6a8664f1fe752f79473eeb9bf33a60 @@ -226,7 +228,7 @@ https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.con https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 -https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.4-pyhd8ed1ab_2.conda#d10d9393680734a8febc4b362a4c94f2 +https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.5-pyhd8ed1ab_0.conda#4c8327180586e7b1cd8b6815fc8827f1 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 @@ -236,7 +238,6 @@ https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 -https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.4-pyhd8ed1ab_2.conda#bb0230917e2473c77d615104dbe8a49d https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 @@ -255,7 +256,7 @@ https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.con https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-hc240232_7.conda#fa3bbe293d907990f3ca5b8b9d4b10f0 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.1.14-py311h9837d23_1.conda#e30309a8776e0e969fa7092d7801641b +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.conda#643f8cb35133eb1be4919fb953f0a25f https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 @@ -267,7 +268,7 @@ https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.2.20-pyhd8ed1ab_0.conda#9ee854e39faa623a8e79ae20ac374f1f +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.3.3-pyhd8ed1ab_0.conda#cecacab21bc8f4ed17fac11bc8b08cf0 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.22.0-py311h320fe9a_2.conda#e94b7f09b52628b89e66cdbd8c3029dd https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.12.0-pyhd8ed1ab_0.tar.bz2#05ee2fb22c1eca4309c06d11aff049f3 diff --git a/build_tools/github/debian_32bit_lock.txt b/build_tools/github/debian_32bit_lock.txt index c369887a51a01..c19d7786d5046 100644 --- a/build_tools/github/debian_32bit_lock.txt +++ b/build_tools/github/debian_32bit_lock.txt @@ -2,24 +2,24 @@ # This file is autogenerated by pip-compile with Python 3.12 # by the following command: # -# pip-compile --output-file=build_tools/azure/debian_32bit_lock.txt build_tools/azure/debian_32bit_requirements.txt +# pip-compile --output-file=build_tools/github/debian_32bit_lock.txt build_tools/github/debian_32bit_requirements.txt # coverage[toml]==7.13.4 # via pytest-cov cython==3.2.4 - # via -r build_tools/azure/debian_32bit_requirements.txt + # via -r build_tools/github/debian_32bit_requirements.txt execnet==2.1.2 # via pytest-xdist iniconfig==2.3.0 # via pytest joblib==1.5.3 - # via -r build_tools/azure/debian_32bit_requirements.txt + # via -r build_tools/github/debian_32bit_requirements.txt meson==1.10.1 # via meson-python meson-python==0.19.0 - # via -r build_tools/azure/debian_32bit_requirements.txt + # via -r build_tools/github/debian_32bit_requirements.txt ninja==1.13.0 - # via -r build_tools/azure/debian_32bit_requirements.txt + # via -r build_tools/github/debian_32bit_requirements.txt packaging==26.0 # via # meson-python @@ -35,12 +35,12 @@ pyproject-metadata==0.11.0 # via meson-python pytest==9.0.2 # via - # -r build_tools/azure/debian_32bit_requirements.txt + # -r build_tools/github/debian_32bit_requirements.txt # pytest-cov # pytest-xdist pytest-cov==6.3.0 - # via -r build_tools/azure/debian_32bit_requirements.txt + # via -r build_tools/github/debian_32bit_requirements.txt pytest-xdist==3.8.0 - # via -r build_tools/azure/debian_32bit_requirements.txt + # via -r build_tools/github/debian_32bit_requirements.txt threadpoolctl==3.6.0 - # via -r build_tools/azure/debian_32bit_requirements.txt + # via -r build_tools/github/debian_32bit_requirements.txt diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock index 4888a1815813f..6c8c37687f7d4 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -12,10 +12,10 @@ https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1. https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 @@ -91,21 +91,21 @@ https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-h3ca20c3_1.conda#c9aa75692f24cce182c3ecd001a1a595 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 -https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 +https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_0.conda#b7113551db5a3e2403cdd052c66e9999 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 @@ -115,22 +115,22 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.co https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.9-h841be55_2.conda#7e1ea1a67435a32e04305fda877acd1e https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.10-hf621c6d_0.conda#977e7d3cba1ef84fc088869b292672fe https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 -https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 +https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-hcf29cc6_1.conda#1707cdd636af2ff697b53186572c9f77 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 -https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.13.1-h3d65ac4_0.conda#45fe531d027ce218b895565110a79a1f +https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.14.0-h3d65ac4_0.conda#2ef8b1658ab236df39a14f2b1126796e https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-hbb90d81_1.conda#9269175175f18091b8844c8e9f213205 https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 -https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e @@ -139,16 +139,16 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.14.0-ha25ca29_1.con https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda#beb628209b2b354b98203066f90b3287 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda#3bb89e4f795e5414addaa531d6b1500a https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.3-pyhd8ed1ab_0.conda#9dbb20eec24beb026291c20a35ce1ff9 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.0-pyhd8ed1ab_0.conda#49a92015e912176999ae81bea11ea778 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.2-py314h42812f9_0.conda#511748f9debe034ff88eef99bc215fd3 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e @@ -159,23 +159,23 @@ https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py314h97ea11e_2 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.0-h1d1128b_1.conda#66055700c90b50c0405a4e515bb4fe3c https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.0-hf7376ad_0.conda#213f51bbcce2964ff2ec00d0fdd38541 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 -https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda#fab1be106a50e20f10fe5228fd1d1651 +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py314h8ec4b1a_0.conda#79678378ae235e24b3aa83cee1b38207 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/linux-64/playwright-1.58.2-h5585027_0.conda#1650804f26dd992fd7418fe603f1c653 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.2-pyhc7ab6ef_0.conda#0c2d37c332453bd66b254bc71311fa30 +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac @@ -206,14 +206,14 @@ https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py314h28848ee_2.cond https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-h9d11ab5_1.conda#cd398eb8374fb626a710b7a35b7ffa98 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-h9692893_2.conda#c3de1cc30bc11edbc98aed352381449d -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 -https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.2-pyh7a1b43c_0.conda#44dff15b5d850481807888197b254b46 -https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.0-pyhd8ed1ab_0.conda#ec33a030c3bc90f0131305a8eba5f8a3 +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff +https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.1-pyhd8ed1ab_0.conda#eadf0f76d9121a6297be754e9d7cc099 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda#235765e4ea0d0301c75965985163b5a1 @@ -222,52 +222,52 @@ https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.2-hb153662_3.conda#c3bb19fc041068029018ab183baa8982 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.3-hb153662_0.conda#9ce778ddbd927385bf145224e291e2a1 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_1.conda#384a1730ea66a72692e377cb45996d61 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 -https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py314h9891dd4_0.conda#6c7bdf1b5e901fd16789cdddce83956f +https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.58.0-pyhcf101f3_0.conda#3b886c49cf44aa133d0eb07e4d0cac89 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 +https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-hc9b1074_13.conda#e7b0b55965db0d2b85c9ae1397d14012 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-h133b1ee_1.conda#36afc05aac7c7f516749cdd3b5e978d9 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hffdcd12_0.conda#b659a59ec7b67623dcaec02388e06fb9 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-h17e89b9_5.conda#6c4f73c9a7e9b51f3a8e321c3e867bb6 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-h3e112c1_2_cpu.conda#f5c13f8872a5b4450e95411f7bd18135 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-h711ef25_3_cpu.conda#2c3ae75a99b9d824c0b64a6c2daa533c https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py314hf36963e_0.conda#46a2b79da4213038907306040c9c9fd8 https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_2_cpu.conda#d57c916f0036b8c29f99924e62a29a2b +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_3_cpu.conda#9d22a47a7902caf8736275487cfabd4e https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_2_cpu.conda#d2b6e411baf659ad8ec33941b75cc767 -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h7058990_102.conda#478b66bfe4b3b33f92442eb2131cc42b +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_3_cpu.conda#7941cce779e45e6803d39408dd20f373 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h7058990_103.conda#2df90510834746b1f52c5299bc99a81f https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_1.conda#4ea6b620fdf24a1a0bc4f1c7134dfafb https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c -https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 +https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_2_cpu.conda#b3b15f7f4a368d9e542ca37e739ff5d1 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_3_cpu.conda#312f95714162590832593173872b9e1d https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py314hb4ffadd_0.conda#23fc526360815090f6bfcd7c6c8e4954 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py314h969be7f_0_cpu.conda#97c21b0d5952f4e0f80bb790df1a5c88 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h6018c46_102.conda#1719e8fde93354419f0f6e1b46d67fcf -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py314hf07bd8e_1.conda#c7df812186fb1290bc00d9b7b5a50b18 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h6018c46_103.conda#a3c40f317db763f9631d078d0fb2759e +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.1.0-pyhcf101f3_0.conda#57d364589a8c710c5b34e8b4a5312ea6 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_2_cpu.conda#1213e3cebce15e93ed92105a47178168 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_3_cpu.conda#9d4fcb24972610d1ad53acf6773f92cb https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_102.conda#9061f7a9fc6c51108ecfb97132161167 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_2_cpu.conda#b9ba37f40b02eecf9701527650c50b0e +https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_103.conda#54ad123774a53ce33aa7e99b6e53b4a6 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_3_cpu.conda#1035c10de0713956d0b503eed07825b5 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py314hdafbbf9_0.conda#860f29e99f5b5f15b0d6a21166588bab diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 53dc3dc045c2a..1f5aef251e4ae 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -6,9 +6,10 @@ https://conda.anaconda.org/conda-forge/osx-64/mkl-include-2023.2.0-h694c41f_5050 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda#4173ac3b19ec0a4f400b4f782910368b -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda#30334add4de016489b731c6662511684 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 -https://conda.anaconda.org/conda-forge/osx-64/libcxx-21.1.8-h4fb565c_2.conda#1ac756454e65fb3fd7bc7de599526e43 +https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.0-h19cb2f5_1.conda#836389b6b9ae58f3fbcf7cafebd5c7f2 https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda#a684eb8a19b2aa68fde0267df172a1e3 https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda#66a0dc7464927d0853b590b6f53ba3ea @@ -18,7 +19,7 @@ https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda#688 https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda#ec88ba8a245855935b871a7324373105 https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda#7bb6608cf1f83578587297a158a6630b https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda#003a54a4e32b02f7355b50a837e699da -https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-21.1.8-h472b3d1_0.conda#e2d811e9f464dd67398b4ce1f9c7c872 +https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.0-h0d3cbff_0.conda#3921780bab286f2439ba483c22b90345 https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda#ced34dd9929f491ca6dab6a2927aff25 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda#47f1b8b4a76ebd0cd22bd7153e54a4dc @@ -30,9 +31,9 @@ https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.cond https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda#5a088b358e37ccb4f4e5c573ff37a9f9 https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.55-h07817ec_0.conda#4fc7ed44d55aaf1d72b8fbc18774b90c -https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.2-hb99441e_0.conda#d910105ce2b14dfb2b32e92ec7653420 +https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.52.0-h77d7759_0.conda#d553eb96758e038b04027b30fe314b2d https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc -https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.1-hd57b93d_1.conda#060f6892620dc862f3b54b9b2da8f177 +https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.2-h7a90416_0.conda#0c8bdbfd118f5963ab343846094932a3 https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda#afda563484aa0017278866707807a335 https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda#30bb8d08b99b9a7600d39efb3559fff0 https://conda.anaconda.org/conda-forge/osx-64/qhull-2020.2-h3c5361c_5.conda#dd1ea9ff27c93db7c01a7b7656bd4ad4 @@ -41,11 +42,11 @@ https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda#6e6efb7 https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.3-h8bce59a_1.conda#b3ecb6480fd46194e3f7dd0ff4445dff https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf -https://conda.anaconda.org/conda-forge/osx-64/ccache-4.12.3-h23dfd00_0.conda#9184b1fd28dd26fafba199afd2a2b713 -https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.1-h6912278_0.conda#dfbdc8fd781dc3111541e4234c19fdbd +https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13-h894318c_0.conda#46f5cb2b8d79732c282aedd47a92709f +https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.2-h58fbd8d_0.conda#2e6760656fde7df787fdef045d0fc65d https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda#9a5cb96e43f5c2296690186e15b3296f https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 -https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.1-h745d5cb_1.conda#1fd2c75a8a9adc629983ed629dec42e1 +https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.2-hd552753_0.conda#eea3155f3b4a3b75af504c871ec23858 https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda#030ec23658b941438ac42303aff0db2b https://conda.anaconda.org/conda-forge/osx-64/brotli-1.2.0-hf139dec_1.conda#149d8ee7d6541a02a6117d8814fd9413 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 @@ -55,12 +56,12 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.9-py314hf3ac25a_2.conda#28a77c52c425fa9c6d914c609c626b1a https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.18-h90db99b_0.conda#753acc10c7277f953f168890e5397c80 -https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.1-h694c41f_0.conda#e0e2edaf5e0c71b843e25a7ecc451cc9 +https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.2-h694c41f_0.conda#bf29ee73174c610d7cad0b081b500df7 https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda#ca52daf58cea766656266c8771d8be81 https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h87e8dc5_0.conda#a67d3517ebbf615b91ef9fdc99934e0c +https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h52bb76a_0.conda#46e628da6e796c948fa8ec9d6d10bda3 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -77,7 +78,7 @@ https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.1-py314h4f144dc_ https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.4-py314h10d0514_0.conda#f27072a17bcb5061cd46de7d01f69028 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f -https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.1-h694c41f_0.conda#ca641fdf8b7803f4b7212b6d66375930 +https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.2-h694c41f_0.conda#0959d7034baef0a8274387fde505c347 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda#34a9f67498721abcfef00178bcf4b190 https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.1-py314hf9dbaa9_0.conda#9a35ec32776ac587bf178233fd2176e4 @@ -98,7 +99,7 @@ https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.2-py314hfc4c462_1.conda# https://conda.anaconda.org/conda-forge/osx-64/blas-devel-3.9.0-20_osx64_mkl.conda#cc3260179093918b801e373c6e888e02 https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h22a2ed9_4.conda#511f02f632e1fb0555da3cb4261851d9 https://conda.anaconda.org/conda-forge/osx-64/pandas-3.0.1-py314h99bb933_0.conda#8efb0ea54eaf4aff69a0a16a5e5efb4c -https://conda.anaconda.org/conda-forge/osx-64/scipy-1.17.0-py314h6328ba2_1.conda#e519933e2e628d7cd159147c224366bf +https://conda.anaconda.org/conda-forge/osx-64/scipy-1.17.1-py314h5727af0_0.conda#adbed17bd17ac00193e6dce1f1a37781 https://conda.anaconda.org/conda-forge/osx-64/blas-2.120-mkl.conda#b041a7677a412f3d925d8208936cb1e2 https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.8-py314hd47142c_0.conda#91d76a5937b47f7f0894857ce88feb9f https://conda.anaconda.org/conda-forge/osx-64/pyamg-5.3.0-py314h81027db_1.conda#47390f4299f43bcdae539d454178596e diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock index d5d55aa80af95..47e562623d1fa 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock @@ -9,10 +9,10 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539 https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_7.conda#5f0ebbfea12d8e5bddff157e271fdb2f https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda#620b85a3f45526a8bc4d23fd78fc22f0 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 -https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-h38cb7af_0.conda#1e93aca311da0210e660d2247812fa02 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda#114e6bfe7c5ad2525eb3597acdbf2300 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa -https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-21.1.8-h55c6f16_2.conda#4cb5878bdb9ebfa65b7cdff5445087c5 +https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.0-h55c6f16_1.conda#e9c56daea841013e7774b5cd46f41564 https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda#a92e310ae8dfc206ff449f362fc4217f @@ -24,7 +24,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda#c0d87c3c8e075daf1daf6c31b53e8083 https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda#e5e7d467f80da752be17796b87fe6385 https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda#369964e85dc26bfe78f41399b366c435 -https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-21.1.8-h4a912ad_0.conda#206ad2df1b5550526e386087bef543c7 +https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.0-hc7d1edf_0.conda#ff0820b5588b20be3b858552ecf8ffae https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda#068d497125e4bf8a66bf707254fff5ae https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda#415816daf82e0b23a736a069a75e9da7 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda#78b548eed8227a689f93775d5d23ae09 @@ -41,9 +41,9 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.c https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda#58b2c5aee0ad58549bf92baead9baead https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.55-h132b30e_0.conda#871dc88b0192ac49b6a5509932c31377 -https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.2-h1ae2325_0.conda#4b0bf313c53c3e89692f020fb55d5f2c +https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.52.0-h1ae2325_0.conda#f6233a3fddc35a2ec9f617f79d6f3d71 https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 -https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.1-h5ef1a60_1.conda#7eed1026708e26ee512f43a04d9d0027 +https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.2-h5ef1a60_0.conda#b284e2b02d53ef7981613839fb86beee https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda#175809cc57b2c67f27a0f238bd7f069d https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda#f4f6ad63f98f64191c3e77c5f5f29d76 https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda#6483b1f59526e05d7d894e466b5b6924 @@ -55,13 +55,13 @@ https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda#e31 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.3-hed4e4f5_1.conda#d99c2a23a31b0172e90f456f580b695e https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c -https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.12.3-h414bf82_0.conda#11dee8592fccf816ae8bd46f08c3ca31 -https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.1-h6da58f4_0.conda#6d4ede03e2a8e20eb51f7f681d2a2550 +https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13-h414bf82_0.conda#2c80c04f787fc8f9acacdc44707b18dc +https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.2-hdfa99f5_0.conda#e726e134a392ae5d7bafa6cc4a3d5725 https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda#92df6107310b1fff92c4cc84f0de247b https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.33.5-h4a5acfd_0.conda#b839e3295b66434f20969c8b940f056a https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda#c08557d00807785decafb932b5be7ef5 https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 -https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.1-h8d039ee_1.conda#fd804ee851e20faca4fecc7df0901d07 +https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.2-h8d039ee_0.conda#e476ba84e57f2bd2004a27381812ad4e https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.1-hb693164_3.conda#4e4ea852d54cc2b869842de5044662fb https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda#753c8d0447677acb7ddbcc6e03e82661 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda#48ece20aa479be6ac9a284772827d00c @@ -70,25 +70,25 @@ https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.c https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py314hc6117b3_0.conda#1289de88f884ac89144949cb97ccabe7 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.3-pyhd8ed1ab_0.conda#9dbb20eec24beb026291c20a35ce1ff9 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.0-pyhd8ed1ab_0.conda#49a92015e912176999ae81bea11ea778 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py314h42813c9_2.conda#9aa431bf603c231e8c77a1b0842a85ed https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.18-hdfa7624_0.conda#6631a7bd2335bb9699b1dbc234b19784 -https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.1-hce30654_0.conda#f35fb38e89e2776994131fbf961fa44b +https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.2-hce30654_0.conda#a3a53232936b55ffea76806aefe19e8b https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda#c4a6f7989cffb0544bfd9207b6789971 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 -https://conda.anaconda.org/conda-forge/noarch/markupsafe-3.0.3-pyh7db6752_0.conda#fab1be106a50e20f10fe5228fd1d1651 +https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py314h6e9b3f0_1.conda#d33c0a15882b70255abdd54711b06a45 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.3.1-h8f1351a_1.conda#a5635df796b71f6ca400fc7026f50701 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hbfb3c88_0.conda#6bf3d24692c157a41c01ce0bd17daeea +https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hd9e9057_0.conda#4b5d3a91320976eec71678fad1e3569b https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.2-pyhc7ab6ef_0.conda#0c2d37c332453bd66b254bc71311fa30 +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 @@ -103,57 +103,57 @@ https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py314h6c2aa https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.4-py314h6e9b3f0_0.conda#96c7bf4f2b5010d29604a62e91e634bb https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f -https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.1-hce30654_0.conda#1ec9a1ee7a2c9339774ad9bb6fe6caec +https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.2-hce30654_0.conda#ca730d8e7d1de1f71013edfef0e08f13 https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.2.1-py314h07d5e28_2.conda#2e07295c0b3bcdae3551d525b70e396f https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_4.conda#eaf3d06e3a8a10dee7565e8d76ae618d -https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_7.conda#5600ae1b88144099572939e773f4b20b +https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_8.conda#445fc95210a8e15e8b5f9f93782e3f80 https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda#26981599908ed2205366e8fc91b37fc6 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.1.1-py314hab283cf_0.conda#bcb38a8005e93a3b240a0dbcf28df87a -https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.2-pyh7a1b43c_0.conda#44dff15b5d850481807888197b254b46 +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_7.conda#3b992d143f0008588ca26df8a324eee9 +https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_8.conda#06c1a0f7eb6c393e16cc99e280784b36 https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_4.conda#22eb76f8d98f4d3b8319d40bda9174de https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h8d724d3_accelerate.conda#c32b3b0d73d5cb1ab2a095a69bf3a7bd https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.18.0-py314h784bc60_0.conda#4f367ea978ceb7f4c5e90ecc7b9f50fc +https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.19.0-py314h6cfcd04_0.conda#0c8942bc23758aaeafed2707902fc48e https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 +https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_he8a363d_4.conda#76c651b923e048f3f3e0ecb22c966f70 https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_h752f6bc_accelerate.conda#e5733907c1c77e6db5012c299e42a5ad https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hcb0d94e_accelerate.conda#3b5a735865842f8d6bf8b78b376ca9e1 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_4.conda#caf7c8e48827c2ad0c402716159fe0a2 -https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_h6d92914_4.conda#df5cd5c925df1412426e3db71d31363f +https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_hd01ab73_4.conda#0d059c5db9d880ff37b2da53bf06509e https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-5_hbdd07e9_accelerate.conda#29c7d09cbe6d342ced64b0447e1f3792 -https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.10.0-cpu_generic_hf7cc835_2.conda#3662b7ef51f97c1030b28bcd4bb0d8a0 +https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.10.0-cpu_generic_hf7cc835_3.conda#98f89ad42eaba858443d31336677aed2 https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.2-py314hae46ccb_1.conda#0f0ddf0575b98d91cda9e3ca9eaeb9a2 -https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 +https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-5_h55bc449_accelerate.conda#6696b095e91860523bcc97303e11d30d https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py314hf8a3a22_4.conda#cddc851000ce131d757678c2f329eaad https://conda.anaconda.org/conda-forge/osx-arm64/pandas-3.0.1-py314h5e21a50_0.conda#840cec8154769d52f65f0fdaaf4aa4c9 -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.10.0-cpu_generic_py314_he36690f_2.conda#58e87541ac9cbcbf6761d85a95b88578 -https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.0-py314hfc1f868_1.conda#09978c420b2e017134c825c06250bf23 +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.10.0-cpu_generic_py314_he36690f_3.conda#51da3d684a7d90b35adfd742fb551cc4 +https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.1-py314hfc1f868_0.conda#7806ce54b78b0b11517b465a3398e910 https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.305-accelerate.conda#5f941c90faaca70599ef8302d0c2738f https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py314hd63e3f0_0.conda#c84152e510d41378b8758826655b6ed7 https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py314h95ce61a_1.conda#44282cc9330eb206f808c4f5be281fe2 -https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.10.0-cpu_generic_hcc7c195_2.conda#9e989335f05b5d19538cf538805544da +https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.10.0-cpu_generic_hcc7c195_3.conda#e7ebf31f2c197adaba9bbf84a40dffd9 https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py314he55896b_0.conda#ad9a3f773f13989b92b41c0eabed5a38 https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda#148516e0c9edf4e9331a4d53ae806a9b -https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_7.conda#13150cdd8e6bc61aa68b55d1a2a69083 +https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_8.conda#ededa5c4f241dad0a7ebc99bb11e5dbb https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda#8d99c82e0f5fed6cc36fcf66a11e03f0 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_impl_osx-arm64-14.3.0-h6d03799_1.conda#1e9ec88ecc684d92644a45c6df2399d0 https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 -https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_7.conda#bde6fcb6b1fcefb687a7fb95675c6ec8 +https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_8.conda#6bee2e04d81e5023286770ef6b56e146 https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_31.conda#6645630920c0980a33f055a49fbdb88e -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_7.conda#4fa4a9227c428372847c534a9bffd698 -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_hc995acf_7.conda#0c1f688616da9aac0ce556d74a24f740 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_8.conda#c5d2fcbd218812e18feb9f60a04359e3 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_hc995acf_8.conda#5ec2b8416b3a6af3650f9bb3984ba439 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_osx-arm64-14.3.0-h3c33bd0_0.conda#8db8c0061c0f3701444b7b9cc9966511 https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_31.conda#bd6926e81dc196064373b614af3bc9ff https://conda.anaconda.org/conda-forge/osx-arm64/gfortran-14.3.0-h3ef1dbf_0.conda#e148e0bc9bbc90b6325a479a5501786d diff --git a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock index 6c598f2736a02..628693b40c145 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -4,7 +4,7 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 @@ -24,15 +24,15 @@ https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.cond https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 -# pip certifi @ https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl#sha256=9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c -# pip charset-normalizer @ https://files.pythonhosted.org/packages/f5/83/6ab5883f57c9c801ce5e5677242328aa45592be8a00644310a008d04f922/charset_normalizer-3.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894 +# pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa +# pip charset-normalizer @ https://files.pythonhosted.org/packages/94/0a/af49691938dfe175d71b8a929bd7e4ace2809c0c5134e28bc535660d5262/charset_normalizer-3.4.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 # pip coverage @ https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 # pip cython @ https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 @@ -40,7 +40,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip fonttools @ https://files.pythonhosted.org/packages/a3/4b/d67eedaed19def5967fade3297fed8161b25ba94699efc124b14fb68cdbc/fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl#sha256=64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5 # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea -# pip imagesize @ https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl#sha256=0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b +# pip imagesize @ https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl#sha256=5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip joblib @ https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl#sha256=5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 # pip kiwisolver @ https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098 @@ -64,7 +64,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip sphinxcontrib-serializinghtml @ https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl#sha256=6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb # pip urllib3 @ https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl#sha256=bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 -# pip array-api-strict @ https://files.pythonhosted.org/packages/e1/7b/81bef4348db9705d829c58b9e563c78eddca24438f1ce1108d709e6eed55/array_api_strict-2.4.1-py3-none-any.whl#sha256=22198ceb47cd3d9c0534c50650d265848d0da6ff71707171215e6678ce811ca5 +# pip array-api-strict @ https://files.pythonhosted.org/packages/22/a3/ed2786497cb3cb90f13ff3eb5f3cf92b447ae3f8451307c0e94eeb2bb445/array_api_strict-2.5-py3-none-any.whl#sha256=0438dd48df521c710ca33d13e8f7e41dd74a9c2427a5d8f549d6f2fe93f8d945 # pip contourpy @ https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl#sha256=85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 5ea8743d3ed2b..0b7b0fdcfefa6 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -11,7 +11,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18. https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda#468fd3bb9e1f671d36c2cbc677e56f1d -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda#cf105bce884e4ef8c8ccdca9fe6695e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 @@ -44,7 +44,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5c https://conda.anaconda.org/conda-forge/linux-aarch64/xxhash-0.8.3-hd794028_0.conda#f2accdfbd632e2be9a63bed23cb08045 https://conda.anaconda.org/conda-forge/linux-aarch64/double-conversion-3.4.0-hfae3067_0.conda#9fd794eaf983eabf975ead524540b4be https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda#4aa540e9541cc9d6581ab23ff2043f13 -https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.2-hb1525cb_0.conda#15b35dc33e185e7d2aac1cfcd6778627 +https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.2-hcab7f73_0.conda#998ee7d53e32f7ab57fc35707285527e https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.0.0-hfdc4d58_1.conda#60dceb7e876f4d74a9cbd42bbbc6b9cf https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf_1.conda#47e5b71b77bb8b47b4ecf9659492977f https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda#6553a5d017fe14859ea8a4e6ea5def8f @@ -67,15 +67,15 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0 https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda#f731af71c723065d91b4c01bb822641b https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 -https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.12.3-h185addb_0.conda#3fc03e82e28b1a9b346f1395585f53ff -https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.21.3-h50a48e9_0.conda#29c10432a2ca1472b53f299ffb2ffa37 +https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13-h185addb_0.conda#e82dd46d52f3696ad7451abe0af74831 +https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda#d9ca108bd680ea86a963104b6b3e95ca https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda#35b2ae7fadf364b8e5fb8185aaeb80e5 -https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.1-hdae7a39_0.conda#9c2f56b6e011c6d8010ff43b796aab2f -https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_0.conda#81dd1078cd9366563f977918f60a1b31 +https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.2-hdae7a39_0.conda#69d1cdfdabb66464cbde17890e8be3b9 +https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_1.conda#4ac4372fc4d7f20630a91314cdac8afd https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e -https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.51.2-h10b116e_0.conda#4e3ba0d5d192f99217b85f07a0761e64 +https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda#77891484f18eca74b8ad83694da9815e https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d -https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.1-h79dcc73_1.conda#e42758e7b065c34fd1b0e5143752f970 +https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda#e3ec9079759d35b875097d6a9a69e744 https://conda.anaconda.org/conda-forge/linux-aarch64/qhull-2020.2-h70be974_5.conda#bb138086d938e2b64f5f364945793ebf https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-0.4.1-hca56bd8_2.conda#159ffec8f7fab775669a538f0b29373a https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-keysyms-0.4.1-h5c728e9_0.conda#57ca8564599ddf8b633c4ea6afee6f3a @@ -83,19 +83,19 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-renderutil-0.3.10- https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-wm-0.4.2-h5c728e9_0.conda#f14dcda6894722e421da2b7dcffb0b78 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.13-h63a1b12_0.conda#22dd10425ef181e80e130db50675d615 https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-hd651790_1.conda#5c933384d588a06cd8dac78ca2864aab -https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.28-h6c5dea3_0.conda#b6d06b46e791add99cc39fbbc34530d5 +https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.28-h6598af7_1.conda#f4fbf4001970e3e58984281a12c99969 https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda#a4b6b82427d15f0489cef0df2d82f926 https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda#bb960f01525b5e001608afef9d47b79c https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda#5afcea37a46f76ec1322943b3c4dfdc0 -https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h5cdc715_5.conda#ac0333d338076ef19170938bbaf97582 -https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.1-h8af1aa0_0.conda#1e61fb236ccd3d6ccaf9e91cb2d7e12d +https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h4f2b762_6.conda#67828c963b17db7dc989fe5d509ef04a +https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.2-h8af1aa0_0.conda#93bce8dee6a0a4906331db294ec250fe https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a -https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.1-h825857f_1.conda#eb4665cdf78fd02d4abc4edf8c15b7b9 +https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda#19de96909ee1198e2853acd8aba89f6c https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.30-pthreads_h3a8cbd8_4.conda#e3f245ed352bd66d181b73a78d886038 https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c -https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.14-h91f4b29_3_cpython.conda#b4b58af4399ab0fc63ec86181494832b +https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.15-h91f4b29_0_cpython.conda#bb09184ea3313703da05516cd730e8f8 https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-image-0.4.0-h5c728e9_2.conda#b82e5c78dbbfa931980e8bfe83bce913 -https://conda.anaconda.org/conda-forge/linux-aarch64/xkeyboard-config-2.46-he30d5cf_0.conda#9524f30d9dea7dd5d6ead43a8823b6c2 +https://conda.anaconda.org/conda-forge/linux-aarch64/xkeyboard-config-2.47-he30d5cf_0.conda#4ac707a4279972357712af099cd1ae50 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.7-he30d5cf_0.conda#fb42b683034619915863d68dd9df03a3 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5cf_0.conda#e8b4056544341daf1d415eaeae7a040c https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda#ae2c2dd0e2d38d249887727db2af960e @@ -104,18 +104,18 @@ https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4 https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.4-py311hdc11669_0.conda#931a90956062cc7219c6bce6c6ccfe7f https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda#0fed1ff55f4938a65907f3ecf62609db -https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.1-h8af1aa0_0.conda#0c8f36ebd3678eed1685f0fc93fc2175 +https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.2-h8af1aa0_0.conda#9cb47d7bbb36646c44d7cf1cb8047887 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.4.9-py311h229e7f7_2.conda#18358d47ebdc1f936003b7d407c9e16f https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda#0b2f1143ae2d0aa4c991959d0daaf256 https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda#0d00176464ebb25af83d40736a2cd3bb https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda#88d1e4133d1182522b403e9ba7435f04 -https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm21-21.1.8-hfd2ba90_0.conda#de59c5148c2a8347c02e437e3ed242a0 +https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.0-hfd2ba90_0.conda#c109137a7e54fde795637863f62485a1 https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h30c48ee_0.conda#48f31a61be512ec1929f4b4a9cedf4bd +https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h2fb54aa_1.conda#b761e5f1358577a16ca187c6116d9fcc https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.1-py311h8e17b9e_0.conda#2f611dceeef334e4d3448944bf714277 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -141,10 +141,10 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.4-py311h2dad8 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.1-py311h164a683_0.conda#b59452fef1470e7e5c34a7c5deefe853 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_3.conda#4ba7653ca09e74e8968120c6aea4bfb1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-21.1.8-default_h94a09a5_3.conda#d294b96fc51b22e382e5220937c738f4 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp22.1-22.1.0-default_he95a3c9_0.conda#1519a50e2f4caca01098a33d39f45f5c +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.0-default_h94a09a5_0.conda#4e1023aa62d0919a4014954d57bcb786 https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-5_hb558247_openblas.conda#8046d5ae90150f00c8b40455d9b2e180 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.2-hf8816c8_0.conda#c54b5b1eb1b2c0f41781293fd4b530b3 +https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.3-h7d4fc67_0.conda#7eb18b198b1d35da9352062c69c4ee64 https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.341.0-h8b8848b_0.conda#06bb91a87fb97ea09398d2e121e00c39 https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.2-py311h669026d_1.conda#6b411688a868a37d95abfb99ebc8b88e https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 @@ -157,11 +157,11 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-12.3.2-h1134a53_0. https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.0-py311h399493a_1.conda#ea481eda36e28a2487d0fe2891d168ff +https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.1-py311h399493a_0.conda#be28b3d39c6942f89652b505e85ae3d6 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.305-openblas.conda#2efe635198609d0d2a122c6a0923b8f8 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.10.2-h5343e53_4.conda#d21d5b2950f78f8f187aec04869bc9b3 +https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.10.2-h4f79d1e_5.conda#c5a6c2e22d9e1a1ef8870a5997fe2eda https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.10.2-py311hf1caecd_0.conda#a245e6ef62e8403f5c5e449e6227924d https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.8-py311hfecb2dc_0.conda#3920b856b59a909812f1913b96adaad8 diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 60d040339ba52..f0f3b99ff8dff 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -8,10 +8,10 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77 https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 @@ -33,7 +33,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.c https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 -https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb9d3cd8_3.conda#20ab6b90150325f1af7ca96bffafde63 +https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb03c661_3.conda#672fad24c7fedff73c684c3e9e9848b3 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b @@ -87,7 +87,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1.conda#f883d61afbc95c50f7b3f62546da4235 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd @@ -95,17 +95,17 @@ https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h5959 https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.conda#081aa22f4581c08e4372b0b6c2f8478e https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.conda#1f0a03af852a9659ed2bf08f2f1704fd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_0.conda#b7113551db5a3e2403cdd052c66e9999 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda#1d4c18d75c51ed9d00092a891a547a7d https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h8fd135c_2.conda#bbf65f7688512872f063810623b755dc https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318b08df404f9c9be5712aaa5a6f0bb0 https://conda.anaconda.org/conda-forge/linux-64/rdma-core-28.9-h59595ed_1.conda#aeffb7c06b5f65e55e6c637408dc4100 https://conda.anaconda.org/conda-forge/linux-64/re2-2023.03.02-h8c504da_0.conda#206f8fa808748f6e90599c3368a1114e @@ -119,22 +119,22 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.13.27-h3870b5a_0.cond https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.conda#d47dee1856d9cb955b8076eeff304a5b https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_0.conda#70a09b6817c7ad694ef4543204c59c25 +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda#b52b769cd13f7adaa6ccdc68ef801709 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-1.8.4-h2f23424_0.conda#4bb92585a250e67d49b46c073d29f9dd -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f https://conda.anaconda.org/conda-forge/linux-64/ucx-1.14.1-h64cca9d_5.conda#39aa3b356d10d7e5add0c540945a0944 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 -https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e @@ -142,14 +142,14 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.3.1-h1e0337 https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.7.10-h9ab9c9b_2.conda#cf49873da2e59f876a2ad4794b05801b https://conda.anaconda.org/conda-forge/linux-64/brotli-1.0.9-h166bdaf_9.conda#4601544b4982ba1861fa9b9c607b2c06 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.0.9-py311ha362b79_9.conda#ced5340f5dc6cff43a80deac8d0e398f -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda#beb628209b2b354b98203066f90b3287 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -159,6 +159,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openbla https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.0-hf7376ad_0.conda#213f51bbcce2964ff2ec00d0fdd38541 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 @@ -192,12 +193,12 @@ https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py311h3778330_0.conda#6b1b19bdc407007d5e41079eab797ddc https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 -https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_0.conda#937834a2fb235626c3f8e8a83afd6b75 +https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 @@ -235,5 +236,5 @@ https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.con https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b -# pip pytz @ https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl#sha256=5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00 +# pip pytz @ https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl#sha256=f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a # pip pandas @ https://files.pythonhosted.org/packages/fa/fe/c81ad3991f2c6aeacf01973f1d37b1dc76c0682f312f104741602a9557f1/pandas-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=e252a9e49b233ff96e2815c67c29702ac3a062098d80a170c506dff3470fd060 diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 3790d3c3dad73..02c1194c1e4ec 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -4,7 +4,7 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 @@ -39,23 +39,24 @@ https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.14-hd63d673_3_cpython.conda#26d8f4db8c578dedba9f2c11423e59e5 +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a +https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.1.4-pyhd8ed1ab_0.conda#eacc711330cd46939f66cd401ff9c44b -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.4-pyhd8ed1ab_0.conda#a22d1fd9bf98827e280a02875d9a007a +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda#beb628209b2b354b98203066f90b3287 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 @@ -67,14 +68,13 @@ https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.b https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_0.conda#0954f1a6a26df4a510b54f73b2a0345c +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/pytz-2025.2-pyhd8ed1ab_0.conda#bc8e3267d44011051f2eb14d22fb0960 https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 @@ -83,7 +83,6 @@ https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_0.conda#ea5be9abc2939c8431893b4e123a2065 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d @@ -98,7 +97,7 @@ https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.c https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.conda#3ac73c673df24589b5b84d43a4afd235 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.0-py311hbe70eeb_1.conda#f4dda6316cc4718cbcab7009b5d60c41 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 diff --git a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock index 4a8d9e79263a5..53eeacbef001d 100644 --- a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock @@ -9,7 +9,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.co https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda#71b24316859acd00bdb8b38f5e2ce328 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-h4c7d964_0.conda#84d389c9eee640dda3d26fc5335c67d8 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda#f001e6e220355b7f87403a4d0e5bf1ca https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda#8a86073cf3b343b87d03f41790d8b4e5 https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda#242d9f25d2ae60c76b38a5e42858e51d @@ -32,7 +32,7 @@ https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#645 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda#56a686f92ac0273c0f6af58858a3f013 https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda#ba0bfd4c3cf73f299ffe46ff0eaeb8e3 https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.30-pthreads_h877e47f_4.conda#f551f8ae0ae6535be1ffde181f9377f3 -https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.2-hf5d6505_0.conda#903979414b47d777d548e5f0165e6cd8 +https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda#8830689d537fda55f990620680934bb1 https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.341.0-h477610d_0.conda#804880b2674119b84277d6c16b01677d https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda#f9bbae5e2537e3b06e0f7310ba76c893 https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda#41fbfac52c601159df6c01f875de31b9 @@ -42,17 +42,17 @@ https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda#08c https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda#854fbdff64b572b5c0b470f334d34c11 https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda#0481bfd9814bf525bd4b3ee4b51494c4 https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.3-h0261ad2_1.conda#46a21c0a4e65f1a135251fc7c8663f83 -https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.3-hdf4eb48_0.conda#31aec030344e962fbd7dbbbbd68e60a9 +https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda#4432f52dc0c8eb6a7a6abc00a037d93c https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_h0adab6e_openblas.conda#bae34d8f039de36cc4384371aa12bd61 https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda#450e3ae947fc46b60f1d8f8f318b40d4 https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda#ccd93cfa8e54fd9df4e83dbe55ff6e8c https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda#2cf0cf76cc15d360dfa2f17fd6cf9772 https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.55-h7351971_0.conda#43f47a9151b9b8fc100aeefcf350d1a0 -https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.1-h3cfd58e_1.conda#07d73826fde28e7dbaec52a3297d7d26 +https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h3cfd58e_0.conda#f6dd496a1f2b66951110a3a0817f699b https://conda.anaconda.org/conda-forge/win-64/openblas-0.3.30-pthreads_h4a7f399_4.conda#482e61f83248a880d180629bf8ed36b2 https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda#77eaf2336f3ae749e712f63e36b0f0a1 https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda#3c8f2573569bb816483e5cf57efbbe29 -https://conda.anaconda.org/conda-forge/win-64/python-3.11.14-h0159041_3_cpython.conda#05ded1dca7befb66ec95a9ec6d34a71a +https://conda.anaconda.org/conda-forge/win-64/python-3.11.15-h0159041_0_cpython.conda#d09dbf470b41bca48cbe6a78ba1e009b https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda#8436cab9a76015dfe7208d3c9f97c156 https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda#a7c03e38aa9c0e84d41881b9236eacfb https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda#053b84beec00b71ea8ff7a4f84b55207 @@ -64,13 +64,13 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py311h275cad7_2.conda#e9eb24a8d111be48179bf82a9e0e13ca https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a8eebe_openblas.conda#1db756824d3aec6a25599c7821cb3e24 -https://conda.anaconda.org/conda-forge/win-64/libclang13-21.1.8-default_ha2db4b5_3.conda#06e385238457018ad1071179b67e39d1 -https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.1-hdbac1cb_0.conda#6e7c5c5ab485057b5d07fd8188ba5c28 -https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.4-h0c9aed9_0.conda#275eb125dd1490f287e85ffd544b6403 +https://conda.anaconda.org/conda-forge/win-64/libclang13-22.1.0-default_ha2db4b5_0.conda#7ad437870ea7d487e1b0e663503b6b1d +https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.2-hdbac1cb_0.conda#c21a474a38982cdb56b3454cf4f78389 +https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.4-h0c9aed9_1.conda#0329a7e92c8c8b61fcaaf7ad44642a96 https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hd232482_openblas.conda#78240c2b4322025a74e7e6edad247103 https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c -https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.1-h779ef1b_1.conda#68dc154b8d415176c07b6995bd3a65d9 +https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h779ef1b_0.conda#be3843e412c9f9d697958aa68c72d09d https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 @@ -90,11 +90,11 @@ https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.4-py311h3f79411_0.co https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/win-64/lcms2-2.18-hf2c6c5f_0.conda#b6c68d6b829b044cd17a41e0a8a23ca1 -https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.1-h57928b3_0.conda#3235024fe48d4087721797ebd6c9d28c +https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.2-h57928b3_0.conda#153d52fd0e4ba2a5bd5bb4f4afa41417 https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-5_hbb0e6ff_openblas.conda#b96fdd694dc8b7a5869613121c40d086 https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.2-py311h80b3fa1_1.conda#a824c6667179120c458beb9e9394932f -https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h24db6dd_0.conda#5af852046226bb3cb15c7f61c2ac020a +https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h0e57b4f_0.conda#e723ab7cc2794c954e1b22fde51c16e4 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f @@ -102,18 +102,18 @@ https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-5_ha590de0_openb https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h275cad7_4.conda#9fb1f375c704c5287c97c60f6a88d137 https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda#a0b1b87e871011ca3b783bbf410bc39f https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py311h3f79411_0.conda#e5445b571c6e2919198c40c6db3d25c5 -https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.1-h57928b3_0.conda#d69c21967f35eb2ce7f1f85d6b6022d3 +https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.2-h57928b3_0.conda#c360b467564b875a9f5dc481b8726cee https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.1-py311h17b8079_0.conda#b17fe050184f2f7fd03e094a5fdc56ae https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.0-py311h9c22a71_1.conda#0d03c857517a5db3c1af5b553a528fac +https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.1-py311h9c22a71_0.conda#24047b0ff1fa264427c456e4c7f68283 https://conda.anaconda.org/conda-forge/win-64/blas-2.305-openblas.conda#19bbf270f61bbef238e16a9509377a52 https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda#52ea1beba35b69852d210242dd20f97d https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/win-64/harfbuzz-12.3.2-h5a1b470_0.conda#fb5d7b9527b418f83e3316f3e6daa8a2 -https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.10.2-h68b6638_4.conda#f2dc18a6006aac4ac0050861c6df4120 +https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.10.2-h35725d6_5.conda#193fcaa5c64aa817cd8cde92afbc9d4e https://conda.anaconda.org/conda-forge/win-64/pyside6-6.10.2-py311hf70c7b4_0.conda#8512eff5fd02b371f36b0da26f5a78ee https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py311h1ea47a8_0.conda#64fe28aa2486e41918239d385336e88e diff --git a/build_tools/github/ubuntu_atlas_lock.txt b/build_tools/github/ubuntu_atlas_lock.txt index cd7c3a7582e19..7803f0d8406c4 100644 --- a/build_tools/github/ubuntu_atlas_lock.txt +++ b/build_tools/github/ubuntu_atlas_lock.txt @@ -2,22 +2,22 @@ # This file is autogenerated by pip-compile with Python 3.12 # by the following command: # -# pip-compile --output-file=build_tools/azure/ubuntu_atlas_lock.txt build_tools/azure/ubuntu_atlas_requirements.txt +# pip-compile --output-file=build_tools/github/ubuntu_atlas_lock.txt build_tools/github/ubuntu_atlas_requirements.txt # cython==3.1.2 - # via -r build_tools/azure/ubuntu_atlas_requirements.txt + # via -r build_tools/github/ubuntu_atlas_requirements.txt execnet==2.1.2 # via pytest-xdist iniconfig==2.3.0 # via pytest joblib==1.3.0 - # via -r build_tools/azure/ubuntu_atlas_requirements.txt + # via -r build_tools/github/ubuntu_atlas_requirements.txt meson==1.10.1 # via meson-python meson-python==0.19.0 - # via -r build_tools/azure/ubuntu_atlas_requirements.txt + # via -r build_tools/github/ubuntu_atlas_requirements.txt ninja==1.13.0 - # via -r build_tools/azure/ubuntu_atlas_requirements.txt + # via -r build_tools/github/ubuntu_atlas_requirements.txt packaging==26.0 # via # meson-python @@ -31,9 +31,9 @@ pyproject-metadata==0.11.0 # via meson-python pytest==9.0.2 # via - # -r build_tools/azure/ubuntu_atlas_requirements.txt + # -r build_tools/github/ubuntu_atlas_requirements.txt # pytest-xdist pytest-xdist==3.8.0 - # via -r build_tools/azure/ubuntu_atlas_requirements.txt + # via -r build_tools/github/ubuntu_atlas_requirements.txt threadpoolctl==3.2.0 - # via -r build_tools/azure/ubuntu_atlas_requirements.txt + # via -r build_tools/github/ubuntu_atlas_requirements.txt From fba5a2ce7ab70ac06032031077342c5be9a9ba72 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 9 Mar 2026 05:17:10 -0400 Subject: [PATCH 265/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33488) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/github/pylatest_free_threaded_linux-64_conda.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index 9b78e026012c6..1522105aec7c5 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -27,10 +27,10 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-he1279bd_1_cp314t.conda#19b5d632d02f56f9f95ce07dc1e086b5 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 From 1a4cadbeab062bc12c8e1c5d0e4e727ec857078c Mon Sep 17 00:00:00 2001 From: Matthias De Lozzo <53711375+mdelozzo@users.noreply.github.com> Date: Mon, 9 Mar 2026 13:10:42 +0100 Subject: [PATCH 266/462] Fix: GaussianProcessRegressor optimizes the default kernel when optimizer is not None (#32964) Co-authored-by: Matthias De Lozzo <matthias.delozzo@irt-saintexupery.com> Co-authored-by: Adrin Jalali <adrin.jalali@gmail.com> --- .../sklearn.gaussian_process/32964.fix.rst | 5 +++++ sklearn/gaussian_process/_gpr.py | 19 ++++++++----------- sklearn/gaussian_process/tests/test_gpr.py | 12 +++++++----- 3 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.gaussian_process/32964.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.gaussian_process/32964.fix.rst b/doc/whats_new/upcoming_changes/sklearn.gaussian_process/32964.fix.rst new file mode 100644 index 0000000000000..73f915b8dde93 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.gaussian_process/32964.fix.rst @@ -0,0 +1,5 @@ +- The hyperparameters of the default kernel of :class:`~sklearn.gaussian_process.GaussianProcessRegressor`, + namely `ConstantKernel() * RBF()`, + are now optimized when `optimizer` is not `None`. + Thus, `gpr = GaussianProcessRegressor().fit(X, y)` uses optimized kernel hyperparameters. + By :user:`Matthias De Lozzo <mdelozzo>`. diff --git a/sklearn/gaussian_process/_gpr.py b/sklearn/gaussian_process/_gpr.py index 40b0bd84aea30..cf1917a8d9c13 100644 --- a/sklearn/gaussian_process/_gpr.py +++ b/sklearn/gaussian_process/_gpr.py @@ -55,11 +55,13 @@ class GaussianProcessRegressor(MultiOutputMixin, RegressorMixin, BaseEstimator): Parameters ---------- kernel : kernel instance, default=None - The kernel specifying the covariance function of the GP. If None is - passed, the kernel ``ConstantKernel(1.0, constant_value_bounds="fixed") - * RBF(1.0, length_scale_bounds="fixed")`` is used as default. Note that - the kernel hyperparameters are optimized during fitting unless the - bounds are marked as "fixed". + The kernel specifying the covariance function of the GP. + If `None` is passed, + the kernel `ConstantKernel() * RBF()` is used as default. + Note that + the kernel hyperparameters are optimized during fitting + unless the bounds are marked as `"fixed"` + or the argument `optimizer` is set to `None`. alpha : float or ndarray of shape (n_samples,), default=1e-10 Value added to the diagonal of the kernel matrix during fitting. @@ -244,12 +246,7 @@ def fit(self, X, y): self : object GaussianProcessRegressor class instance. """ - if self.kernel is None: # Use an RBF kernel as default - self.kernel_ = C(1.0, constant_value_bounds="fixed") * RBF( - 1.0, length_scale_bounds="fixed" - ) - else: - self.kernel_ = clone(self.kernel) + self.kernel_ = C() * RBF() if self.kernel is None else clone(self.kernel) self._rng = check_random_state(self.random_state) diff --git a/sklearn/gaussian_process/tests/test_gpr.py b/sklearn/gaussian_process/tests/test_gpr.py index a5a97af101c14..9a2b2474bfaeb 100644 --- a/sklearn/gaussian_process/tests/test_gpr.py +++ b/sklearn/gaussian_process/tests/test_gpr.py @@ -201,11 +201,13 @@ def test_sample_statistics(kernel): ) -def test_no_optimizer(): - # Test that kernel parameters are unmodified when optimizer is None. - kernel = RBF(1.0) - gpr = GaussianProcessRegressor(kernel=kernel, optimizer=None).fit(X, y) - assert np.exp(gpr.kernel_.theta) == 1.0 +@pytest.mark.parametrize("optimizer", [None, "fmin_l_bfgs_b"]) +@pytest.mark.parametrize("kernel", [None, RBF()]) +def test_no_optimizer(optimizer, kernel): + """Test that kernel parameters are unmodified when optimizer is None.""" + gpr = GaussianProcessRegressor(kernel=kernel, optimizer=optimizer) + gpr.fit(X, y) + assert bool((gpr.kernel_.theta == 0.0).all()) is (optimizer is None) @pytest.mark.parametrize("kernel", kernels) From 598817ba56cb24bbefdc5555e711be21116f487d Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 9 Mar 2026 09:17:40 -0400 Subject: [PATCH 267/462] =?UTF-8?q?=F0=9F=94=92=20=F0=9F=A4=96=20CI=20Upda?= =?UTF-8?q?te=20lock=20files=20for=20array-api=20CI=20build(s)=20?= =?UTF-8?q?=F0=9F=94=92=20=F0=9F=A4=96=20(#33432)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lock file bot <noreply@github.com> --- ...a_forge_cuda_array-api_linux-64_conda.lock | 86 +++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 8d5202b4a2dc8..637ae1cfb4c71 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -13,7 +13,7 @@ https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a668 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda#bddacf101bb4dd0e51811cb69c7790e2 +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/noarch/cuda-cccl_linux-64-12.9.27-ha770c72_0.conda#87ff6381e33b76e5b9b179a2cdd005ec https://conda.anaconda.org/conda-forge/noarch/cuda-crt-dev_linux-64-12.9.86-ha770c72_2.conda#79d280de61e18010df5997daea4743df https://conda.anaconda.org/conda-forge/linux-64/cuda-crt-tools-12.9.86-ha770c72_2.conda#503a94e20d2690d534d676a764a1852c @@ -23,7 +23,7 @@ https://conda.anaconda.org/conda-forge/noarch/cuda-nvvm-dev_linux-64-12.9.86-ha7 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/noarch/libnvptxcompiler-dev_linux-64-12.9.86-ha770c72_2.conda#a66a909acf08924aced622903832a937 -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-21.1.8-h4922eb0_0.conda#f8640b709b37dc7758ddce45ea18d000 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_linux-64-12.9.79-h3f2d84a_0.conda#86e40eb67d83f1a58bdafdd44e5a77c6 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -119,30 +119,30 @@ https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-h3ca20c3_1.conda#c9aa75692f24cce182c3ecd001a1a595 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.12.3-hedf47ba_0.conda#a91187cb5184d2bfedb03cbdc2000c19 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_1.conda#55a83761db33f82d92d7d7a4a61662e5 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 -https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 +https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.conda#af0df9bc982b5ed2c67e8f5062d1f8c1 https://conda.anaconda.org/conda-forge/linux-64/libcurand-dev-10.3.10.19-h676940d_1.conda#fc716aaff5af15b80ccbd28b3e67672c https://conda.anaconda.org/conda-forge/linux-64/libcusparse-12.5.10.65-hecca717_2.conda#890ebfaad48c887d3d82847ec9d6bc79 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.1-h73754d4_0.conda#8e7251989bca326a28f4a5ffbd74557a -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_0.conda#b7113551db5a3e2403cdd052c66e9999 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-openmp_hd680484_4.conda#c0512e4f60d62ccccb4c3c8333b33608 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 https://conda.anaconda.org/rapidsai/linux-64/librmm-26.02.00-cuda12_260204_498dafcf.conda#057e94dab29e9c69b4542eb0c61b161e -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.2-hf4e2dac_0.conda#da5be73701eecd0e8454423fd6ffcf30 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-259.1-h6569c3e_0.conda#dbd34a7b836b479604b8b5f07c3a35ba +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-259.3-h6569c3e_0.conda#14f6f781723e56e33ca7e04d406511e4 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libudev1-259.1-h6569c3e_0.conda#8b11ee89763fc236d854c46cab7e762d -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.1-hca6bf5a_1.conda#3fdd8d99683da9fe279c2f4cecd1e048 +https://conda.anaconda.org/conda-forge/linux-64/libudev1-259.3-h6569c3e_0.conda#41fd789b8466d0f68083ff37b637a090 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 @@ -154,21 +154,21 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.10-hf621c6d_0.co https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvcc-impl-12.9.86-h85509e4_2.conda#67458d2685e7503933efa550f3ee40f3 https://conda.anaconda.org/conda-forge/linux-64/cuda-profiler-api-12.9.79-h7938cbb_1.conda#90d09865fb37d11d510444e34ebe6a09 -https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 +https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcublas-dev-12.9.1.4-h676940d_1.conda#f90f4ff087ac29005c6989ea0fb2735a https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.conda#a178a1f3642521f104ecceeefa138d01 https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_1.conda#c5b8ea827c65e5811d61aa49cd0bae9a -https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-hcf29cc6_1.conda#1707cdd636af2ff697b53186572c9f77 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2.conda#bb6e31a0daa64ede76fe8d3fff01c06f https://conda.anaconda.org/conda-forge/linux-64/libcusparse-dev-12.5.10.65-hecca717_2.conda#db94469fbd554c107acc3afd0af5d8ec -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.1-ha770c72_0.conda#f4084e4e6577797150f9b04a4560ceb0 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-26.02.00-cuda12_260204_c212ab9b.conda#702a98df50c3b8be134516647a217fde -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.1-he237659_1.conda#417955234eccd8f252b86a265ccdab7f +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-openmp_hd77311e_4.conda#525e2455ed342f2aef93c59ac5db2e28 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -177,7 +177,7 @@ https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp31 https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 -https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda#71ae752a748962161b4740eaff510258 +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e @@ -186,13 +186,13 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.14.0-ha25ca29_1.con https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.3.4-pyhcf101f3_0.conda#5531bd855da47b70361e2e2207dd1864 +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.4.1-pyhc364b38_0.conda#50e2bf874bbde47e66c2b0c6b62d0026 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.24.3-pyhd8ed1ab_0.conda#9dbb20eec24beb026291c20a35ce1ff9 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.0-pyhd8ed1ab_0.conda#49a92015e912176999ae81bea11ea778 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.1-ha770c72_0.conda#4afc585cd97ba8a23809406cd8a9eda8 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 @@ -202,24 +202,24 @@ https://conda.anaconda.org/conda-forge/linux-64/libcusolver-dev-11.7.5.82-h67694 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.0-h1d1128b_1.conda#66055700c90b50c0405a4e515bb4fe3c https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.0-hf7376ad_0.conda#213f51bbcce2964ff2ec00d0fdd38541 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/llvmlite-0.44.0-py313hfdae721_2.conda#dd0d7947635c0c524608eab7db55dcc9 -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_0.conda#c14389156310b8ed3520d84f854be1ee +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda#aeb9b9da79fd0258b3db091d1fefcd71 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.590.48-pyhd8ed1ab_0.conda#fda409cefdbd417f9ca4e072c39add77 -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py313h80991f8_0.conda#2d5ee4938cdde91a8967f3eea686c546 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.2-pyhc7ab6ef_0.conda#0c2d37c332453bd66b254bc71311fa30 +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 @@ -248,17 +248,17 @@ https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py313h3dea7bd_0 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-21.1.8-default_h746c552_3.conda#b4277f5a09d458a0306db3147bd0171c +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-h9d11ab5_1.conda#cd398eb8374fb626a710b7a35b7ffa98 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-h9692893_2.conda#c3de1cc30bc11edbc98aed352381449d -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 -https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.2-pyh7a1b43c_0.conda#44dff15b5d850481807888197b254b46 +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.12-h4df99d1_100.conda#3d92938d5b83c49162ade038aab58a59 @@ -266,25 +266,25 @@ https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py313h246eb7 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.4.1-pyhe01879c_0.conda#648e253c455718227c61e26f4a4ce701 -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.2-hb153662_3.conda#c3bb19fc041068029018ab183baa8982 +https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.3-hb153662_0.conda#9ce778ddbd927385bf145224e291e2a1 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 -https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.5.1-cuda12_py313hacc9b55_1.conda#808c80c320dfd77ba5da9f6a35b07503 +https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.6.0-cuda12_py313hacc9b55_0.conda#1986c17fb0b8184289ea7d6fc8ba4b34 https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.5-pyh698daf1_0.conda#a4fb0d4ffdac1cf2cda9318d2f789d20 https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py313h28b6081_0.conda#fe933a91c19fa88788b4204b6ba67ba2 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_1.conda#384a1730ea66a72692e377cb45996d61 -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_hb019b6b_202.conda#20529bf89b9dad005a5ace8bc5408624 +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_hb019b6b_203.conda#5e373fc37a76270b4454c02cb126ab34 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.conda#84cef0ce56c6db53edb3f8b83bdbb364 -https://conda.anaconda.org/conda-forge/linux-64/optree-0.18.0-py313h7037e92_0.conda#33901d2cb4969c6b57eefe767d69fa69 +https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py313h7037e92_0.conda#21f1c403983c8a4e067ba6eec6b878ec https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py313hbfd7664_0.conda#1c8807728f0333228766dee685394e16 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 -https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_105.conda#8c09fac3785696e1c477156192d64b91 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.606-hc9b1074_13.conda#e7b0b55965db0d2b85c9ae1397d14012 +https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-h133b1ee_1.conda#36afc05aac7c7f516749cdd3b5e978d9 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py313h7fc6698_0.conda#41368ea5c4c7c607ac98ecab56833535 @@ -294,25 +294,25 @@ https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hf https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_hb8e8477_202.conda#d0429f5f90f804183a84c3f861a7eaa2 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-hb82b983_4.conda#9861c7820fdb45bc50a2ea60f4ff7952 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_hb8e8477_203.conda#6cfb64f7fc401f2c7c789214237aea24 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-h17e89b9_5.conda#6c4f73c9a7e9b51f3a8e321c3e867bb6 https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-h3e112c1_2_cpu.conda#f5c13f8872a5b4450e95411f7bd18135 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-h711ef25_3_cpu.conda#2c3ae75a99b9d824c0b64a6c2daa533c https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313h85046ba_0.conda#f6161781ceb86e9f5da1b532e4c4453c -https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_202.conda#1efceead0b494f34670136ce6de29e79 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_203.conda#969fd0ea1b469425630712ba3513deff https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_2_cpu.conda#d57c916f0036b8c29f99924e62a29a2b -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_2_cpu.conda#d2b6e411baf659ad8ec33941b75cc767 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_3_cpu.conda#9d22a47a7902caf8736275487cfabd4e +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_3_cpu.conda#7941cce779e45e6803d39408dd20f373 https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_2_cpu.conda#b3b15f7f4a368d9e542ca37e739ff5d1 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_3_cpu.conda#312f95714162590832593173872b9e1d https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py313h98bfbea_0_cpu.conda#d2b771a9050c52941a61a72f2d161c64 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_2_cpu.conda#1213e3cebce15e93ed92105a47178168 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_3_cpu.conda#9d4fcb24972610d1ad53acf6773f92cb https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.02.00-cuda12_260204_a2f5a8b7.conda#361cae27e77618c6ba9f943807471f9f https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.02.00-cuda12_py313_260204_c212ab9b.conda#14933b753ec82f9d5a61d7cb4b5e2e71 https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.02.00-cuda12_py313_260204_a2f5a8b7.conda#c46807878ad576379e7be3acc187d13a -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_2_cpu.conda#b9ba37f40b02eecf9701527650c50b0e +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_3_cpu.conda#1035c10de0713956d0b503eed07825b5 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py313h78bf25f_0.conda#bd299f66ab2d10d1e03d4148397fe263 From ceeffc5d6e3494d4973472e7690ec8bce2f83b4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= <deamarialeon@gmail.com> Date: Mon, 9 Mar 2026 16:12:16 +0100 Subject: [PATCH 268/462] ENH: Display fitted attributes in HTML representation (#33399) --- .../many-modules/33399.enhancement.rst | 10 ++ sklearn/base.py | 40 +++++ sklearn/compose/_column_transformer.py | 45 +++-- .../compose/tests/test_column_transformer.py | 40 ++++- sklearn/tests/test_base.py | 15 ++ sklearn/utils/_repr_html/estimator.py | 46 ++++- sklearn/utils/_repr_html/fitted_attributes.py | 166 +++++++++++++++++ sklearn/utils/_repr_html/params.css | 10 +- .../utils/_repr_html/tests/test_attributes.py | 169 ++++++++++++++++++ .../utils/_repr_html/tests/test_estimator.py | 3 +- 10 files changed, 514 insertions(+), 30 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/many-modules/33399.enhancement.rst create mode 100644 sklearn/utils/_repr_html/fitted_attributes.py create mode 100644 sklearn/utils/_repr_html/tests/test_attributes.py diff --git a/doc/whats_new/upcoming_changes/many-modules/33399.enhancement.rst b/doc/whats_new/upcoming_changes/many-modules/33399.enhancement.rst new file mode 100644 index 0000000000000..433fb535cbe83 --- /dev/null +++ b/doc/whats_new/upcoming_changes/many-modules/33399.enhancement.rst @@ -0,0 +1,10 @@ +- The HTML representation of all scikit-learn estimators + inheriting from :class:`base.BaseEstimator` now includes a table + displaying their fitted :term:`attributes`. These are all the public + estimator attributes that are computed during the call to :term:`fit` + with a name that ends with an underscore. + By :user:`Dea María Léon <DeaMariaLeon>`, + :user:`Jérémie du Boisberranger <jeremiedbb>`, + :user:`Olivier Grisel <ogrisel>`, + :user:`Guillaume Lemaitre <glemaitre>`, + :user:`Antoine Baker <antoinebaker>`. diff --git a/sklearn/base.py b/sklearn/base.py index f8be470dd5f03..36026b9658ba3 100644 --- a/sklearn/base.py +++ b/sklearn/base.py @@ -6,6 +6,7 @@ import copy import functools import inspect +import numbers import platform import re import warnings @@ -21,6 +22,7 @@ from sklearn.utils._param_validation import validate_parameter_constraints from sklearn.utils._repr_html.base import ReprHTMLMixin, _HTMLDocumentationLinkMixin from sklearn.utils._repr_html.estimator import estimator_html_repr +from sklearn.utils._repr_html.fitted_attributes import AttrsDict from sklearn.utils._repr_html.params import ParamsDict from sklearn.utils._set_output import _SetOutputMixin from sklearn.utils._tags import ( @@ -344,6 +346,44 @@ def is_non_default(param_name, param_value): doc_link=doc_link, ) + def _get_fitted_attr_html(self, doc_link=""): + """Get fitted attributes of the estimator.""" + + fitted_attr = {} + for name, value in inspect.getmembers(self): + # We display up to 100 fitted attributes + if len(fitted_attr) > 100: + fitted_attr["..."] = { + "type_name": "...", + "value": "", + } + break + if name.startswith("_") or not name.endswith("_"): + continue + if ( + hasattr(value, "shape") + and hasattr(value, "dtype") + and not isinstance(value, numbers.Number) + ): + # array-like attribute with shape and dtype + fitted_attr[name] = { + "type_name": type(value).__name__, + "shape": value.shape, + "dtype": value.dtype, + "value": value, + } + else: + fitted_attr[name] = { + "type_name": type(value).__name__, + "value": value, + } + + return AttrsDict( + fitted_attrs=fitted_attr, + estimator_class=self.__class__, + doc_link=doc_link, + ) + def set_params(self, **params): """Set the parameters of this estimator. diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index 4aa1f0c6739d2..362821159aa06 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -1224,23 +1224,38 @@ def _hstack(self, Xs, *, n_samples): return np.hstack(Xs) def _sk_visual_block_(self): - if isinstance(self.remainder, str) and self.remainder == "drop": - transformers = self.transformers - elif hasattr(self, "_remainder"): - remainder_columns = self._remainder[2] - if ( - hasattr(self, "feature_names_in_") - and remainder_columns - and not all(isinstance(col, str) for col in remainder_columns) - ): - remainder_columns = self.feature_names_in_[remainder_columns].tolist() - transformers = chain( - self.transformers, [("remainder", self.remainder, remainder_columns)] - ) - else: - transformers = chain(self.transformers, [("remainder", self.remainder, [])]) + # We can find remainder and its column only when it's fitted + if hasattr(self, "transformers_"): + transformers = [ + transformer + for transformer in self.transformers_[:-1] # Exclude remainder + if not (transformer[0] == "remainder" and transformer[1] == "drop") + ] + # Add remainder back to fitted transformers if remainder is not drop + if self.remainder != "drop": + remainder_columns = self._remainder[2] + has_numeric_columns = remainder_columns and not all( + isinstance(col, str) for col in remainder_columns + ) + # Convert indices to column names when feature names are available + if hasattr(self, "feature_names_in_") and has_numeric_columns: + remainder_columns = self.feature_names_in_[ + remainder_columns + ].tolist() + + transformers = chain( + transformers, [("remainder", self.remainder, remainder_columns)] + ) + else: # not fitted + if self.remainder != "drop": + transformers = chain( + self.transformers, [("remainder", self.remainder, [])] + ) + else: + transformers = self.transformers names, transformers, name_details = zip(*transformers) + return _VisualBlock( "parallel", transformers, names=names, name_details=name_details ) diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index f24830417a3ae..63821b57c2d7f 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -1593,7 +1593,11 @@ def test_sk_visual_block_remainder_fitted_pandas(remainder): visual_block = ct._sk_visual_block_() assert visual_block.names == ("ohe", "remainder") assert visual_block.name_details == (["col1", "col2"], ["col3", "col4"]) - assert visual_block.estimators == (ohe, remainder) + assert isinstance(visual_block.estimators[0], OneHotEncoder) + if remainder == "passthrough": + assert visual_block.estimators[1] == "passthrough" + else: + assert isinstance(visual_block.estimators[1], StandardScaler) @pytest.mark.parametrize("remainder", ["passthrough", StandardScaler()]) @@ -1608,7 +1612,39 @@ def test_sk_visual_block_remainder_fitted_numpy(remainder): visual_block = ct._sk_visual_block_() assert visual_block.names == ("scale", "remainder") assert visual_block.name_details == ([0, 2], [1]) - assert visual_block.estimators == (scaler, remainder) + assert isinstance(visual_block.estimators[0], StandardScaler) + if remainder == "passthrough": + assert visual_block.estimators[1] == "passthrough" + else: + assert isinstance(visual_block.estimators[1], StandardScaler) + + +def test_sk_visual_block_remainder_col_names_pandas(): + """Check that the visual block `name_details` matches the `feature_names_in_` + Non-regression test - when remainder_columns logic is removed it should fail + https://github.com/scikit-learn/scikit-learn/pull/31442#discussion_r2841235711 + """ + pd = pytest.importorskip("pandas") + ohe = OneHotEncoder() + ct = ColumnTransformer( + transformers=[("ohe", ohe, ["col1"])], + remainder="passthrough", + ) + df = pd.DataFrame( + { + "col1": ["a", "b", "c"], + "col2": ["z", "z", "z"], + } + ) + # It is not possible to guess the remainder columns when not fitted. + visual_block = ct._sk_visual_block_() + assert visual_block.name_details == (["col1"], []) + + ct.fit(df) + # Once fitted, the remainder columns are the columns seen during fit not + # specified for specific transformers. + visual_block = ct._sk_visual_block_() + assert visual_block.name_details == (["col1"], ["col2"]) @pytest.mark.parametrize("explicit_colname", ["first", "second", 0, 1]) diff --git a/sklearn/tests/test_base.py b/sklearn/tests/test_base.py index f5ff8c25f7356..d84a113ba5447 100644 --- a/sklearn/tests/test_base.py +++ b/sklearn/tests/test_base.py @@ -1006,6 +1006,21 @@ def test_get_params_html(): assert est._get_params_html().non_default == ("empty",) +def test_get_fitted_attr_html(): + """Check the behaviour of the `_get_fitted_attr_html` method.""" + X = np.array([[-1, -1], [-2, -1], [-3, -2]]) + pca = PCA().fit(X) + pca._not_a_fitted_attr = "x" + + fitted_attr_html = pca._get_fitted_attr_html() + assert fitted_attr_html["n_features_in_"] == {"type_name": "int", "value": 2} + assert pca._not_a_fitted_attr not in fitted_attr_html + assert len(fitted_attr_html) == 9 + assert fitted_attr_html["components_"]["type_name"] == ("ndarray") + assert fitted_attr_html["components_"]["shape"] == (2, 2) + assert_allclose(fitted_attr_html["components_"]["value"], pca.components_) + + def make_estimator_with_param(default_value): class DynamicEstimator(BaseEstimator): def __init__(self, param=default_value): diff --git a/sklearn/utils/_repr_html/estimator.py b/sklearn/utils/_repr_html/estimator.py index d8d8df5153d45..be38702cd9174 100644 --- a/sklearn/utils/_repr_html/estimator.py +++ b/sklearn/utils/_repr_html/estimator.py @@ -107,6 +107,7 @@ def _sk_visual_block_(self): def _write_label_html( out, params, + attrs, name, name_details, name_caption=None, @@ -129,6 +130,9 @@ def _write_label_html( If estimator has `get_params` method, this is the HTML representation of the estimator's parameters and their values. When the estimator does not have `get_params`, it is an empty string. + attrs: str + If estimator is fitted, this is the HTML representation of its + fitted attributes. name : str The label for the estimator. It corresponds either to the estimator class name for a simple estimator or in the case of a `Pipeline` and `ColumnTransformer`, @@ -205,7 +209,7 @@ def _write_label_html( f'{label_arrow_class}">{name_caption_div}{links_div}</label>' ) - fmt_str = ( + out.write( f'<input class="sk-toggleable__control sk-hidden--visually ' f'sk-global" id="{est_id}" ' f'type="checkbox" {checked_str}>{label_html}<div ' @@ -213,14 +217,14 @@ def _write_label_html( f'data-param-prefix="{html.escape(param_prefix)}">' ) - if params: - fmt_str = "".join([fmt_str, f"{params}</div>"]) - elif name_details and ("Pipeline" not in name): + out.write(params) + out.write(attrs) + if name_details and ("Pipeline" not in name) and not params: if name == "passthrough" or name_details == "[]": name_details = "" - fmt_str = "".join([fmt_str, f"<pre>{name_details}</pre></div>"]) + out.write(f"<pre>{name_details}</pre>") - out.write(fmt_str) + out.write("</div>") else: out.write(f"<label>{name}</label>") out.write("</div></div>") # outer_class inner_class @@ -312,6 +316,7 @@ def _write_estimator_html( The prefix to prepend to parameter names for nested estimators. For example, in a pipeline this might be "pipeline__stepname__". """ + if first_call: est_block = _get_visual_block(estimator) else: @@ -327,18 +332,30 @@ def _write_estimator_html( dashed_wrapped = first_call or est_block.dash_wrapped dash_cls = " sk-dashed-wrapped" if dashed_wrapped else "" out.write(f'<div class="sk-item{dash_cls}">') - if estimator_label: - if hasattr(estimator, "get_params") and hasattr( - estimator, "_get_params_html" + if ( + hasattr(estimator, "get_params") + and not est_block.names == "passthrough" + and hasattr(estimator, "_get_params_html") ): params = estimator._get_params_html(False, doc_link)._repr_html_inner() else: params = "" + if ( + hasattr(estimator, "_get_fitted_attr_html") + and not est_block.names == "passthrough" + and is_fitted_css_class == "fitted" + ): + fitted_attrs = estimator._get_fitted_attr_html(doc_link) + attrs = fitted_attrs._repr_html_inner() if len(fitted_attrs) > 0 else "" + + else: + attrs = "" _write_label_html( out, params, + attrs, estimator_label, estimator_label_details, doc_link=doc_link, @@ -395,10 +412,21 @@ def _write_estimator_html( params = estimator._get_params_html(doc_link=doc_link)._repr_html_inner() else: params = "" + if ( + hasattr(estimator, "_get_fitted_attr_html") + and not est_block.names == "passthrough" + and is_fitted_css_class == "fitted" + ): + fitted_attrs = estimator._get_fitted_attr_html(doc_link) + attrs = fitted_attrs._repr_html_inner() if len(fitted_attrs) > 0 else "" + + else: + attrs = "" _write_label_html( out, params, + attrs, est_block.names, est_block.name_details, est_block.name_caption, diff --git a/sklearn/utils/_repr_html/fitted_attributes.py b/sklearn/utils/_repr_html/fitted_attributes.py new file mode 100644 index 0000000000000..9941140bd033b --- /dev/null +++ b/sklearn/utils/_repr_html/fitted_attributes.py @@ -0,0 +1,166 @@ +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +import html +import reprlib +from collections import UserDict + +import numpy as np + +from sklearn.utils._repr_html.base import ReprHTMLMixin +from sklearn.utils._repr_html.common import ( + generate_link_to_param_doc, + get_docstring, +) + + +def _read_fitted_attr(value): + if isinstance(value, np.ndarray): + value = np.array2string( + value, precision=2, separator=",", suppress_small=True, threshold=4 + ) + return html.escape(value) + + r = reprlib.Repr() + + for attr in ( + "maxlist", + "maxdict", + "maxtuple", + "maxset", + "maxfrozenset", + "maxdeque", + "maxarray", + ): + setattr(r, attr, 4) + r.maxstring = 9 + + if isinstance(value, float): + value = round(value, 3) + + return html.escape(r.repr(value)) + + +def _fitted_attr_html_repr(fitted_attributes): + """Generate HTML representation of estimator fitted attributes. + + Creates an HTML table with fitted attribute names and values + wrapped in a collapsible details element. When attributes are arrays, + shape and dtype are shown. + """ + + FITTED_ATTR_TEMPLATE = """ + <div class="estimator-table"> + <details> + <summary>Fitted attributes</summary> + <table class="parameters-table"> + <tbody> + <tr> + <th>Name</th> + <th>Type</th> + <th>Value</th> + </tr> + {rows} + </tbody> + </table> + </details> + </div> + """ + FITTED_ATTR_ROW_TEMPLATE = """ + <tr class="default"> + <td class="param">{fitted_attr_display}</td> + <td class="fitted-att-type">{0}</td> + <td>{1}</td> + + + </tr> + """ + + FITTED_ATTR_AVAILABLE_DOC_LINK_TEMPLATE = """ + <a class="param-doc-link" + style="anchor-name: --doc-link-{fitted_attr_name};" + rel="noreferrer" target="_blank" href="{link}"> + {fitted_attr_name} + <span class="param-doc-description" + style="position-anchor: --doc-link-{fitted_attr_name};"> + {fitted_attr_description}</span> + </a> + """ + + rows = [] + + for name, attr_info in fitted_attributes.items(): + link = generate_link_to_param_doc( + fitted_attributes.estimator_class, + name, + fitted_attributes.doc_link, + ) + fitted_attr_description = get_docstring( + fitted_attributes.estimator_class, "Attributes", name + ) + + if fitted_attributes.doc_link and link and fitted_attr_description: + # Create clickable attribute name with documentation link + fitted_attr_display = FITTED_ATTR_AVAILABLE_DOC_LINK_TEMPLATE.format( + link=link, + fitted_attr_name=html.escape(name), + fitted_attr_description=fitted_attr_description, + ) + else: + # Just show the attribute name without link + fitted_attr_display = ( + f'<a class="param-doc-link" style="text-decoration:none;">' + f"{html.escape(name)}</a>" + ) + + if len(attr_info) == 2: + html_row_values = ( + html.escape(str(attr_info["type_name"])), + _read_fitted_attr(attr_info["value"]), # All the attr info comes here + ) + else: # fitted attribute type is array-like + type_name = html.escape(attr_info["type_name"]) + dtype = html.escape(str(attr_info["dtype"])) + shape = html.escape(str(attr_info["shape"])) + + html_row_values = ( + f"{type_name}[{dtype}]{shape}", + _read_fitted_attr(attr_info["value"]), + ) + rows.append( + FITTED_ATTR_ROW_TEMPLATE.format( + *html_row_values, + fitted_attr_display=fitted_attr_display, + ) + ) + + return FITTED_ATTR_TEMPLATE.format(rows="\n".join(rows)) + + +class AttrsDict(ReprHTMLMixin, UserDict): + """Dictionary-like class to store and provide an HTML representation. + + It builds an HTML structure to be used with Jupyter notebooks or similar + environments. + + Parameters + ---------- + fitted_attrs : dict, default=None + Dictionary of fitted attributes and their values. + + estimator_class : type, default=None + The class of the estimator. It allows to find the online documentation + link for each parameter. + + doc_link : str, default="" + The base URL to the online documentation for the estimator class. + Used to generate parameter-specific documentation links in the HTML + representation. If empty, documentation links will not be generated. + """ + + _html_repr = _fitted_attr_html_repr + + def __init__(self, *, fitted_attrs=None, estimator_class=None, doc_link=""): + super().__init__(fitted_attrs or {}) + self.estimator_class = estimator_class + self.doc_link = doc_link diff --git a/sklearn/utils/_repr_html/params.css b/sklearn/utils/_repr_html/params.css index c20acdd8d243c..e7552310f6934 100644 --- a/sklearn/utils/_repr_html/params.css +++ b/sklearn/utils/_repr_html/params.css @@ -31,11 +31,11 @@ background-color: #f6f6f6; } -.estimator-table .parameters-table tr:hover { +.estimator-table .parameters-table tr:hover td { background-color: #e0e0e0; } -.estimator-table table td { +.estimator-table table :is(td, th) { border: 1px solid rgba(106, 105, 104, 0.232); } @@ -59,7 +59,7 @@ background-color: transparent; } -.default td { +.default td, .estimator-table th { color: black; text-align: left !important; } @@ -69,6 +69,10 @@ color: black; } +td.fitted-att-type { + white-space: preserve nowrap; +} + /* Styles for parameter documentation links We need styling for visited so jupyter doesn't overwrite it diff --git a/sklearn/utils/_repr_html/tests/test_attributes.py b/sklearn/utils/_repr_html/tests/test_attributes.py new file mode 100644 index 0000000000000..bdfc54a713805 --- /dev/null +++ b/sklearn/utils/_repr_html/tests/test_attributes.py @@ -0,0 +1,169 @@ +import re + +import numpy as np +import pytest + +from sklearn import config_context +from sklearn.utils._repr_html.fitted_attributes import AttrsDict, _fitted_attr_html_repr + +fitted_attrs = AttrsDict( + fitted_attrs={ + "a": {"type_name": "int", "value": 6}, + "b": { + "type_name": "ndarray", + "shape": (1,), + "dtype": np.dtype("float64"), + "value": 8, + }, + } +) + + +def test_numpy_fitted_attr(): + html_fitted_attr_out = _fitted_attr_html_repr(fitted_attrs) + + expected_html_fitted_attr = ( + r'<div class="estimator-table">' + r"\s*<details>" + r"\s*<summary>Fitted attributes</summary>" + r'\s*<table class="parameters-table">' + r"\s*<tbody>" + r"\s*<tr>" + r"\s*<th>Name</th>" + r"\s*<th>Type</th>" + r"\s*<th>Value</th>" + r"\s*</tr>" + r'\s*<tr class="default">' + r'\s*<td class="param">' + r'\s*<a class="param-doc-link" style="text-decoration:none;">a</a>' + r"\s*</td>" + r'\s*<td class="fitted-att-type">int</td>' + r"\s*<td>6</td>" + r"\s*</tr>" + r'\s*<tr class="default">' + r'\s*<td class="param">' + r'\s*<a class="param-doc-link" style="text-decoration:none;">b</a>' + r"\s*</td>" + r'\s*<td class="fitted-att-type">ndarray\[float64\]\(1,\)</td>' + r"\s*<td>8</td>" + r"\s*</tr>" + r"\s*</tbody>" + r"\s*</table>" + r"\s*</details>" + r"\s*</div>" + ) + assert re.search(expected_html_fitted_attr, html_fitted_attr_out, flags=re.DOTALL) + + +def test_fitted_attrs_dict_repr_html_error(): + out = fitted_attrs._repr_html_() + assert "<summary>Fitted attributes</summary>" in out + assert '<td class="fitted-att-type">int</td>' in out + assert '<td class="fitted-att-type">ndarray[float64](1,)</td>' in out + + with config_context(display="text"): + msg = "_repr_html_ is only defined when" + with pytest.raises(AttributeError, match=msg): + fitted_attrs._repr_html_() + + +def test_fitted_attrs_dict_repr_mimebundle(): + out = fitted_attrs._repr_mimebundle_() + + assert "text/plain" in out + assert "text/html" in out + assert "<summary>Fitted attributes</summary>" in out["text/html"] + plain_text = ( + "{'a': {'type_name': 'int', 'value': 6}, " + "'b': {'type_name': 'ndarray', 'shape': (1,), " + "'dtype': dtype('float64'), 'value': 8}}" + ) + assert out["text/plain"] == plain_text + with config_context(display="text"): + out = fitted_attrs._repr_mimebundle_() + assert "text/plain" in out + assert "text/html" not in out + + +def test_fitted_attr_html_repr(): + out = _fitted_attr_html_repr(fitted_attrs) + assert "<summary>Fitted attributes</summary>" in out + assert '<table class="parameters-table">' in out + + +def test_pandas_column_names(): + pd = pytest.importorskip("pandas") + fitted_attrs_with_pandas_cols = AttrsDict( + fitted_attrs={ + "myabc_": { + "type_name": "DataFrame", + "shape": (3, 3), + "dtype": np.dtype("int64"), + "value": pd.DataFrame({"A": [0, 2, 4], "B": [3, 4, 5], "C": [3, 4, 4]}), + } + } + ) + html_fitted_attr_out = _fitted_attr_html_repr(fitted_attrs_with_pandas_cols) + expected_html_fitted_attr = ( + r'<div class="estimator-table">' + r"\s*<details>" + r"\s*<summary>Fitted attributes</summary>" + r'\s*<table class="parameters-table">' + r"\s*<tbody>" + r"\s*<tr>" + r"\s*<th>Name</th>" + r"\s*<th>Type</th>" + r"\s*<th>Value</th>" + r"\s*</tr>" + r"\s*<tr class=\"default\">" + r"\s*<td class=\"param\">" + r'\s*<a class="param-doc-link" style="text-decoration:none;">myabc_</a>' + r"\s*</td>" + r'\s*<td class="fitted-att-type">DataFrame\[int64\]\(3,\s*3\)</td>' + r"\s*<td>\s*A\s*B\s*C\s*0\s*\.\.\.\s*4\s*2\s*4\s*5\s*4\s*</td>" + r"\s*</tr>" + r"\s*</tbody>" + r"\s*</table>" + r"\s*</details>" + r"\s*</div>" + ) + assert re.search(expected_html_fitted_attr, html_fitted_attr_out, flags=re.DOTALL) + + +def test_pandas_series_fitted_attr(): + pd = pytest.importorskip("pandas") + fitted_attrs_with_series = AttrsDict( + fitted_attrs={ + "new_": { + "type_name": "Series", + "shape": (3,), + "dtype": np.dtype("int64"), + "value": pd.Series({"a": 1, "b": 2, "c": 3}), + } + } + ) + html_fitted_attr_out = _fitted_attr_html_repr(fitted_attrs_with_series) + expected_html_fitted_attr = ( + r'<div class="estimator-table">' + r"\s*<details>" + r"\s*<summary>Fitted attributes</summary>" + r'\s*<table class="parameters-table">' + r"\s*<tbody>" + r"\s*<tr>" + r"\s*<th>Name</th>" + r"\s*<th>Type</th>" + r"\s*<th>Value</th>" + r"\s*</tr>" + r'\s*<tr class="default">' + r'\s*<td class="param">' + r'\s*<a class="param-doc-link" style="text-decoration:none;">new_</a>' + r"\s*</td>" + r'\s*<td class="fitted-att-type">Series\[int64\]\(3,\)</td>' + r"\s*<td>a\s*1\s*b\s*2...3\s*dtype:\s*int64</td>" + r"\s*</tr>" + r"\s*</tbody>" + r"\s*</table>" + r"\s*</details>" + r"\s*</div>" + ) + assert re.search(expected_html_fitted_attr, html_fitted_attr_out, flags=re.DOTALL) diff --git a/sklearn/utils/_repr_html/tests/test_estimator.py b/sklearn/utils/_repr_html/tests/test_estimator.py index 290a8cfaa504f..d2dff4ec7bb9a 100644 --- a/sklearn/utils/_repr_html/tests/test_estimator.py +++ b/sklearn/utils/_repr_html/tests/test_estimator.py @@ -48,10 +48,11 @@ def test_write_label_html(checked): # Test checking logic and labeling name = "LogisticRegression" params = "" + attrs = "" tool_tip = "hello-world" with closing(StringIO()) as out: - _write_label_html(out, params, name, tool_tip, checked=checked) + _write_label_html(out, params, attrs, name, tool_tip, checked=checked) html_label = out.getvalue() p = ( From 66e8bd1f4c5cdac4d7b23369de60d137f5b5153a Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Tue, 10 Mar 2026 10:44:38 +0100 Subject: [PATCH 269/462] FIX Fix typo in power_iteration_normalizer's constraints for TruncatedSVD (#33492) --- .../sklearn.decomposition/33492.fix.rst | 3 +++ sklearn/decomposition/_truncated_svd.py | 2 +- .../decomposition/tests/test_truncated_svd.py | 19 ++++++++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.decomposition/33492.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.decomposition/33492.fix.rst b/doc/whats_new/upcoming_changes/sklearn.decomposition/33492.fix.rst new file mode 100644 index 0000000000000..c368f41bfd073 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.decomposition/33492.fix.rst @@ -0,0 +1,3 @@ +- Fixed a typo (from `"OR"` to `"QR"`) in the list of allowed values for + `power_iteration_normalizer` in :class:`decomposition.TruncatedSVD`. + By :user:`Olivier Grisel <ogrisel>`. diff --git a/sklearn/decomposition/_truncated_svd.py b/sklearn/decomposition/_truncated_svd.py index afef1eaa7164f..e707f0d911cbb 100644 --- a/sklearn/decomposition/_truncated_svd.py +++ b/sklearn/decomposition/_truncated_svd.py @@ -163,7 +163,7 @@ class to data once, then keep the instance around to do transformations. "algorithm": [StrOptions({"arpack", "randomized"})], "n_iter": [Interval(Integral, 0, None, closed="left")], "n_oversamples": [Interval(Integral, 1, None, closed="left")], - "power_iteration_normalizer": [StrOptions({"auto", "OR", "LU", "none"})], + "power_iteration_normalizer": [StrOptions({"auto", "QR", "LU", "none"})], "random_state": ["random_state"], "tol": [Interval(Real, 0, None, closed="left")], } diff --git a/sklearn/decomposition/tests/test_truncated_svd.py b/sklearn/decomposition/tests/test_truncated_svd.py index 07b35c873ee3e..373e6da8a8170 100644 --- a/sklearn/decomposition/tests/test_truncated_svd.py +++ b/sklearn/decomposition/tests/test_truncated_svd.py @@ -198,14 +198,27 @@ def test_truncated_svd_eq_pca(X_sparse): @pytest.mark.parametrize( - "algorithm, tol", [("randomized", 0.0), ("arpack", 1e-6), ("arpack", 0.0)] + "algorithm, tol, normalizer", + [ + ("randomized", 0.0, "auto"), + ("randomized", 0.0, "QR"), + ("randomized", 0.0, "LU"), + ("randomized", 0.0, "none"), + ("arpack", 1e-6, "auto"), + ("arpack", 0.0, "auto"), + ], ) @pytest.mark.parametrize("kind", ("dense", "sparse")) -def test_fit_transform(X_sparse, algorithm, tol, kind): +def test_fit_transform(X_sparse, algorithm, tol, kind, normalizer): # fit_transform(X) should equal fit(X).transform(X) X = X_sparse if kind == "sparse" else X_sparse.toarray() svd = TruncatedSVD( - n_components=5, n_iter=7, random_state=42, algorithm=algorithm, tol=tol + n_components=5, + n_iter=7, + random_state=42, + algorithm=algorithm, + power_iteration_normalizer=normalizer, + tol=tol, ) X_transformed_1 = svd.fit_transform(X) X_transformed_2 = svd.fit(X).transform(X) From ecd7f6cef6dc4c410b21c48ea59cb94210865782 Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Tue, 10 Mar 2026 18:10:10 +0100 Subject: [PATCH 270/462] MNT Deprecate `shuffle` and `random_state` params from `TargetEncoder` (#33453) --- .../sklearn.preprocessing/33453.api.rst | 5 ++ .../plot_gradient_boosting_categorical.py | 5 +- .../plot_target_encoder_cross_val.py | 5 +- .../plot_release_highlights_1_3_0.py | 3 +- sklearn/preprocessing/_target_encoder.py | 40 +++++++++++--- .../tests/test_target_encoder.py | 52 +++++++++++++------ 6 files changed, 85 insertions(+), 25 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.preprocessing/33453.api.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.preprocessing/33453.api.rst b/doc/whats_new/upcoming_changes/sklearn.preprocessing/33453.api.rst new file mode 100644 index 0000000000000..f8bb059d00416 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.preprocessing/33453.api.rst @@ -0,0 +1,5 @@ +- The `shuffle` and the `random_state` parameters are deprecated on + :class:`~preprocessing.TargetEncoder` and will be removed in version 1.11. Pass a + cross-validation generator as `cv` argument to specify the shuffling behaviour + instead. + By :user:`Stefanie Senger <StefanieSenger>`. diff --git a/examples/ensemble/plot_gradient_boosting_categorical.py b/examples/ensemble/plot_gradient_boosting_categorical.py index 5e6957b0945b4..c67aa716ea8f7 100644 --- a/examples/ensemble/plot_gradient_boosting_categorical.py +++ b/examples/ensemble/plot_gradient_boosting_categorical.py @@ -160,11 +160,14 @@ # held-out part. This way, each sample is encoded using statistics from data it # was not part of, preventing information leakage from the target. +from sklearn.model_selection import KFold from sklearn.preprocessing import TargetEncoder target_encoder = make_column_transformer( ( - TargetEncoder(target_type="continuous", random_state=42), + TargetEncoder( + target_type="continuous", cv=KFold(shuffle=True, random_state=42) + ), make_column_selector(dtype_include="category"), ), remainder="passthrough", diff --git a/examples/preprocessing/plot_target_encoder_cross_val.py b/examples/preprocessing/plot_target_encoder_cross_val.py index d44ee2c6ba021..06635abd0d2e4 100644 --- a/examples/preprocessing/plot_target_encoder_cross_val.py +++ b/examples/preprocessing/plot_target_encoder_cross_val.py @@ -111,10 +111,13 @@ # Next, we create a pipeline with the target encoder and ridge model. The pipeline # uses :meth:`TargetEncoder.fit_transform` which uses :term:`cross fitting`. We # see that the model fits the data well and generalizes to the test set: +from sklearn.model_selection import KFold from sklearn.pipeline import make_pipeline from sklearn.preprocessing import TargetEncoder -model_with_cf = make_pipeline(TargetEncoder(random_state=0), ridge) +model_with_cf = make_pipeline( + TargetEncoder(cv=KFold(shuffle=True, random_state=0)), ridge +) model_with_cf.fit(X_train, y_train) print("Model with CF on train set: ", model_with_cf.score(X_train, y_train)) print("Model with CF on test set: ", model_with_cf.score(X_test, y_test)) diff --git a/examples/release_highlights/plot_release_highlights_1_3_0.py b/examples/release_highlights/plot_release_highlights_1_3_0.py index fe352c2eb1746..f05abe874c4c3 100644 --- a/examples/release_highlights/plot_release_highlights_1_3_0.py +++ b/examples/release_highlights/plot_release_highlights_1_3_0.py @@ -73,12 +73,13 @@ # More details in the :ref:`User Guide <target_encoder>`. import numpy as np +from sklearn.model_selection import KFold from sklearn.preprocessing import TargetEncoder X = np.array([["cat"] * 30 + ["dog"] * 20 + ["snake"] * 38], dtype=object).T y = [90.3] * 30 + [20.4] * 20 + [21.2] * 38 -enc = TargetEncoder(random_state=0) +enc = TargetEncoder(cv=KFold(shuffle=True, random_state=0)) X_trans = enc.fit_transform(X, y) enc.encodings_ diff --git a/sklearn/preprocessing/_target_encoder.py b/sklearn/preprocessing/_target_encoder.py index c5a927d9ddca6..c83ac38b3091a 100644 --- a/sklearn/preprocessing/_target_encoder.py +++ b/sklearn/preprocessing/_target_encoder.py @@ -1,6 +1,7 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause +import warnings from numbers import Real import numpy as np @@ -130,6 +131,10 @@ class TargetEncoder(OneToOneFeatureMixin, _BaseEncoder): applies if `cv` is an int or `None`. If `cv` is a cross-validation generator or an iterable, `shuffle` is ignored. + .. deprecated:: 1.9 + `shuffle` is deprecated and will be removed in 1.11. Pass a cross-validation + generator as `cv` argument to specify the shuffling instead. + random_state : int, RandomState instance or None, default=None When `shuffle` is True, `random_state` affects the ordering of the indices, which controls the randomness of each fold. Otherwise, this @@ -137,6 +142,11 @@ class TargetEncoder(OneToOneFeatureMixin, _BaseEncoder): Pass an int for reproducible output across multiple function calls. See :term:`Glossary <random_state>`. + .. deprecated:: 1.9 + `random_state` is deprecated and will be removed in 1.11. Pass a + cross-validation generator as `cv` argument to specify the random state of + the shuffling instead. + Attributes ---------- encodings_ : list of shape (n_features,) or (n_features * n_classes) of \ @@ -221,18 +231,19 @@ class TargetEncoder(OneToOneFeatureMixin, _BaseEncoder): "target_type": [StrOptions({"auto", "continuous", "binary", "multiclass"})], "smooth": [StrOptions({"auto"}), Interval(Real, 0, None, closed="left")], "cv": ["cv_object"], - "shuffle": ["boolean"], - "random_state": ["random_state"], + "shuffle": ["boolean", StrOptions({"deprecated"})], + "random_state": ["random_state", StrOptions({"deprecated"})], } + # TODO(1.11) remove `shuffle` and `random_state` params, which had been deprecated def __init__( self, categories="auto", target_type="auto", smooth="auto", cv=5, - shuffle=True, - random_state=None, + shuffle="deprecated", + random_state="deprecated", ): self.categories = categories self.smooth = smooth @@ -325,12 +336,29 @@ def fit_transform(self, X, y, **params): X_ordinal, X_known_mask, y_encoded, n_categories = self._fit_encodings_all(X, y) + # TODO(1.11): remove code block + if self.shuffle != "deprecated" or self.random_state != "deprecated": + warnings.warn( + "`TargetEncoder.shuffle` and `TargetEncoder.random_state` are " + "deprecated in version 1.9 and will be removed in version 1.11. Pass a " + "cross-validation generator as `cv` argument to specify the shuffling " + "behaviour instead.", + FutureWarning, + ) + shuffle = True if self.shuffle == "deprecated" else self.shuffle + cv_kwargs = {"shuffle": shuffle} + if self.random_state != "deprecated": + cv_kwargs["random_state"] = self.random_state + + # TODO(1.11): pass shuffle=True to keep backwards compatibility for default + # inputs (will be ignored in `check_cv` if a cv object is passed); + # `random_state` already defaults to `None` in `check_cv` and doesn't need to + # be passed here cv = check_cv( self.cv, y, classifier=self.target_type_ != "continuous", - shuffle=self.shuffle, - random_state=self.random_state, + **cv_kwargs, ) if _routing_enabled(): diff --git a/sklearn/preprocessing/tests/test_target_encoder.py b/sklearn/preprocessing/tests/test_target_encoder.py index 6965df1779080..427dececda9df 100644 --- a/sklearn/preprocessing/tests/test_target_encoder.py +++ b/sklearn/preprocessing/tests/test_target_encoder.py @@ -23,6 +23,7 @@ TargetEncoder, ) from sklearn.utils.fixes import parse_version +from sklearn.utils.multiclass import type_of_target def _encode_target(X_ordinal, y_numeric, n_categories, smooth): @@ -130,8 +131,7 @@ def test_encoding(categories, unknown_value, global_random_seed, smooth, target_ target_encoder = TargetEncoder( smooth=smooth, categories=categories, - cv=n_splits, - random_state=global_random_seed, + cv=cv, ) X_fit_transform = target_encoder.fit_transform(X_train, y_train) @@ -220,8 +220,7 @@ def test_encoding_multiclass( target_encoder = TargetEncoder( smooth=smooth, - cv=n_splits, - random_state=global_random_seed, + cv=cv, ) X_fit_transform = target_encoder.fit_transform(X_train, y_train) @@ -366,9 +365,10 @@ def test_feature_names_out_set_output(y, feature_names): X_df = pd.DataFrame({"A": ["a", "b"] * 10, "B": [1, 2] * 10}) - enc_default = TargetEncoder(cv=2, smooth=3.0, random_state=0) + cv = StratifiedKFold(n_splits=2, random_state=0, shuffle=True) + enc_default = TargetEncoder(cv=cv, smooth=3.0) enc_default.set_output(transform="default") - enc_pandas = TargetEncoder(cv=2, smooth=3.0, random_state=0) + enc_pandas = TargetEncoder(cv=cv, smooth=3.0) enc_pandas.set_output(transform="pandas") X_default = enc_default.fit_transform(X_df, y) @@ -452,7 +452,7 @@ def test_multiple_features_quick(to_pandas, smooth, target_type): dtype=np.float64, ) - enc = TargetEncoder(smooth=smooth, cv=2, random_state=0) + enc = TargetEncoder(smooth=smooth, cv=cv) X_fit_transform = enc.fit_transform(X_train, y_train) assert_allclose(X_fit_transform, expected_X_fit_transform) @@ -479,7 +479,11 @@ def test_constant_target_and_feature(y, y_mean, smooth): X = np.array([[1] * 20]).T n_samples = X.shape[0] - enc = TargetEncoder(cv=2, smooth=smooth, random_state=0) + if type_of_target(y) == "continuous": + cv = KFold(n_splits=2, random_state=0, shuffle=True) + else: + cv = StratifiedKFold(n_splits=2, random_state=0, shuffle=True) + enc = TargetEncoder(cv=cv, smooth=smooth) X_trans = enc.fit_transform(X, y) assert_allclose(X_trans, np.repeat([[y_mean]], n_samples, axis=0)) assert enc.encodings_[0][0] == pytest.approx(y_mean) @@ -504,10 +508,12 @@ def test_fit_transform_not_associated_with_y_if_ordinal_categorical_is_not( y_train = y_train[y_sorted_indices] X_train = X_train[y_sorted_indices] - target_encoder = TargetEncoder(shuffle=True, random_state=global_random_seed) + target_encoder = TargetEncoder( + cv=KFold(n_splits=2, random_state=global_random_seed, shuffle=True) + ) X_encoded_train_shuffled = target_encoder.fit_transform(X_train, y_train) - target_encoder = TargetEncoder(shuffle=False) + target_encoder = TargetEncoder(cv=KFold(n_splits=2, shuffle=False)) X_encoded_train_no_shuffled = target_encoder.fit_transform(X_train, y_train) # Check that no information about y_train has leaked into X_train: @@ -541,7 +547,7 @@ def test_smooth_zero(): X = np.array([[0, 0, 0, 0, 0, 1, 1, 1, 1, 1]]).T y = np.array([2.1, 4.3, 1.2, 3.1, 1.0, 9.0, 10.3, 14.2, 13.3, 15.0]) - enc = TargetEncoder(smooth=0.0, shuffle=False, cv=2) + enc = TargetEncoder(smooth=0.0, cv=KFold(n_splits=2, shuffle=False)) X_trans = enc.fit_transform(X, y) # With cv = 2, category 0 does not exist in the second half, thus @@ -578,7 +584,10 @@ def test_invariance_of_encoding_under_label_permutation(smooth, global_random_se X_train_permuted = permutated_labels[X_train.astype(np.int32)] X_test_permuted = permutated_labels[X_test.astype(np.int32)] - target_encoder = TargetEncoder(smooth=smooth, random_state=global_random_seed) + target_encoder = TargetEncoder( + smooth=smooth, + cv=KFold(n_splits=2, shuffle=True, random_state=global_random_seed), + ) X_train_encoded = target_encoder.fit_transform(X_train, y_train) X_test_encoded = target_encoder.transform(X_test) @@ -660,8 +669,9 @@ def test_target_encoding_for_linear_regression(smooth, global_random_seed): # Now do the same with target encoding using the internal CV mechanism # implemented when using fit_transform. + cv = KFold(shuffle=True, random_state=rng) model_with_cv = make_pipeline( - TargetEncoder(smooth=smooth, random_state=rng), linear_regression + TargetEncoder(smooth=smooth, cv=cv), linear_regression ).fit(X_train, y_train) # This model should be able to fit the data well and also generalise to the @@ -682,9 +692,7 @@ def test_target_encoding_for_linear_regression(smooth, global_random_seed): # Let's now disable the internal cross-validation by calling fit and then # transform separately on the training set: - target_encoder = TargetEncoder(smooth=smooth, random_state=rng).fit( - X_train, y_train - ) + target_encoder = TargetEncoder(smooth=smooth, cv=cv).fit(X_train, y_train) X_enc_no_cv_train = target_encoder.transform(X_train) X_enc_no_cv_test = target_encoder.transform(X_test) model_no_cv = linear_regression.fit(X_enc_no_cv_train, y_train) @@ -752,3 +760,15 @@ def test_target_encoder_raises_cv_overlap(global_random_seed): msg = "Validation indices from `cv` must cover each sample index exactly once" with pytest.raises(ValueError, match=msg): encoder.fit_transform(X, y) + + +# TODO(1.11): remove after deprecation +def test_target_encoder_shuffle_random_state_deprecated(): + X, y = make_regression(n_samples=100, n_features=3, random_state=0) + msg = "`TargetEncoder.shuffle` and `TargetEncoder.random_state` are deprecated" + with pytest.warns(FutureWarning, match=msg): + encoder = TargetEncoder(shuffle=False) + encoder.fit_transform(X, y) + with pytest.warns(FutureWarning, match=msg): + encoder = TargetEncoder(random_state=0) + encoder.fit_transform(X, y) From f5cce5ca6e270de2011eb0ae595a0a8b1dff019a Mon Sep 17 00:00:00 2001 From: Lucas Oliveira <lucas.o@live.com> Date: Wed, 11 Mar 2026 02:43:44 -0300 Subject: [PATCH 271/462] Fix wrong chance_level plot in PrecisionRecallDisplay when using Pytorch data (#33405) Co-authored-by: Anne Beyer <anne.beyer@mailbox.org> Co-authored-by: Tim Head <betatim@gmail.com> --- .../sklearn.metrics/33405.fix.rst | 4 +++ .../metrics/_plot/precision_recall_curve.py | 9 +++-- .../tests/test_precision_recall_display.py | 35 +++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/33405.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/33405.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/33405.fix.rst new file mode 100644 index 0000000000000..4de356a5fc557 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.metrics/33405.fix.rst @@ -0,0 +1,4 @@ +- :meth:`metrics.PrecisionRecallDisplay.from_estimator` and + :meth:`metrics.PrecisionRecallDisplay.from_predictions` now + correctly plot chance level line when `y_true` is a pytorch tensor. + By :user:`Lucas Oliveira <lucolivi>`. \ No newline at end of file diff --git a/sklearn/metrics/_plot/precision_recall_curve.py b/sklearn/metrics/_plot/precision_recall_curve.py index 9302a073d38e3..dd94cdb9584f3 100644 --- a/sklearn/metrics/_plot/precision_recall_curve.py +++ b/sklearn/metrics/_plot/precision_recall_curve.py @@ -1,12 +1,10 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause -from collections import Counter - import numpy as np from sklearn.metrics._ranking import average_precision_score, precision_recall_curve -from sklearn.utils import _safe_indexing +from sklearn.utils import _safe_indexing, check_array from sklearn.utils._plotting import ( _BinaryClassifierCurveDisplayMixin, _check_param_lengths, @@ -697,6 +695,8 @@ def from_predictions( <...> >>> plt.show() """ + + y_true = check_array(y_true, ensure_2d=False, dtype=None) y_score = _deprecate_y_pred_parameter(y_score, y_pred, "1.8") pos_label, name = cls._validate_from_predictions_params( y_true, y_score, sample_weight=sample_weight, pos_label=pos_label, name=name @@ -713,8 +713,7 @@ def from_predictions( y_true, y_score, pos_label=pos_label, sample_weight=sample_weight ) - class_count = Counter(y_true) - prevalence_pos_label = class_count[pos_label] / sum(class_count.values()) + prevalence_pos_label = (y_true == pos_label).sum() / len(y_true) viz = cls( precision=precision, diff --git a/sklearn/metrics/_plot/tests/test_precision_recall_display.py b/sklearn/metrics/_plot/tests/test_precision_recall_display.py index 6db603dbdd8cf..86f9c0abb1bcb 100644 --- a/sklearn/metrics/_plot/tests/test_precision_recall_display.py +++ b/sklearn/metrics/_plot/tests/test_precision_recall_display.py @@ -691,3 +691,38 @@ def test_y_score_and_y_pred_specified_error(pyplot): with pytest.warns(FutureWarning, match="y_pred was deprecated in 1.8"): PrecisionRecallDisplay.from_predictions(y_true, y_pred=y_score) + + +@pytest.mark.parametrize("array_lib", ["torch", "numpy", "list"]) +@pytest.mark.parametrize( + "y_true, pos_label, expected_prevalence_pos_label", + [ + ([1, 0, 0, 0, 0], None, 0.2), + ([1, 1, 0, 0, 0], 1, 0.4), + ([1, 1, 0, 1, 0], 0, 0.4), + ([1, 1, 0, 1, 1], None, 0.8), + ], +) +def test_correct_prevalence_pos_label_with_array_types( + pyplot, array_lib, y_true, pos_label, expected_prevalence_pos_label +): + """ + Non-regression test for issue #33342 + Checks whether the prevalence_pos_label is calculated correctly when using + different array types. This used to fail for pytorch arrays. + """ + + torch = pytest.importorskip("torch") + + if array_lib == "torch": + y_true = torch.tensor(y_true) + elif array_lib == "numpy": + y_true = np.array(y_true) + + y_score = [0.08, 0.15, 0.16, 0.23, 0.42] + + display = PrecisionRecallDisplay.from_predictions( + y_true, y_score, pos_label=pos_label, plot_chance_level=True + ) + + assert display.prevalence_pos_label == expected_prevalence_pos_label From 0169f83950d594166d02eba34866ec5edda78c99 Mon Sep 17 00:00:00 2001 From: Dan Schult <dschult@colgate.edu> Date: Wed, 11 Mar 2026 02:04:06 -0400 Subject: [PATCH 272/462] Enable config setting `sparse_interface` to control sparray and spmatrix creation (#31177) Co-authored-by: Adrin Jalali <adrin.jalali@gmail.com> --- asv_benchmarks/benchmarks/datasets.py | 13 +- benchmarks/bench_feature_expansions.py | 4 +- benchmarks/bench_plot_randomized_svd.py | 2 +- benchmarks/bench_random_projections.py | 2 +- doc/modules/impute.rst | 4 +- doc/modules/multiclass.rst | 8 +- .../many-modules/31177.major-feature.rst | 9 + .../plot_tomography_l1_reconstruction.py | 4 +- .../wikipedia_principal_eigenvector.py | 2 +- .../plot_lasso_dense_vs_sparse_data.py | 4 +- .../approximate_nearest_neighbors.py | 4 +- sklearn/_config.py | 26 +++ sklearn/cluster/_agglomerative.py | 5 +- sklearn/cluster/_bicluster.py | 6 +- sklearn/cluster/_spectral.py | 4 +- sklearn/cluster/tests/test_hierarchical.py | 1 + sklearn/cluster/tests/test_k_means.py | 11 +- sklearn/cluster/tests/test_spectral.py | 1 + .../compose/tests/test_column_transformer.py | 6 +- sklearn/conftest.py | 124 ++++++++++++++ sklearn/datasets/_arff_parser.py | 5 +- sklearn/datasets/_rcv1.py | 4 +- sklearn/datasets/_samples_generator.py | 25 ++- sklearn/datasets/_svmlight_format_io.py | 5 +- .../datasets/tests/test_samples_generator.py | 29 ++-- sklearn/decomposition/_incremental_pca.py | 2 +- sklearn/decomposition/_nmf.py | 5 +- sklearn/decomposition/_truncated_svd.py | 4 +- sklearn/decomposition/tests/test_pca.py | 62 ++----- .../decomposition/tests/test_truncated_svd.py | 4 +- sklearn/ensemble/_gb.py | 32 ++-- .../ensemble/tests/test_weight_boosting.py | 4 +- .../_scipy/sparse/csgraph/_laplacian.py | 6 +- .../feature_extraction/_dict_vectorizer.py | 6 +- sklearn/feature_extraction/_hash.py | 6 +- sklearn/feature_extraction/image.py | 18 +- .../tests/test_feature_hasher.py | 9 +- sklearn/feature_extraction/tests/test_text.py | 24 ++- sklearn/feature_extraction/text.py | 28 ++-- sklearn/feature_selection/_base.py | 7 +- sklearn/impute/_base.py | 18 +- sklearn/impute/tests/test_impute.py | 9 +- sklearn/kernel_approximation.py | 26 ++- sklearn/linear_model/_base.py | 8 +- sklearn/linear_model/_coordinate_descent.py | 3 +- sklearn/linear_model/_linear_loss.py | 13 +- sklearn/linear_model/_quantile.py | 6 +- sklearn/linear_model/tests/test_base.py | 5 +- .../tests/test_coordinate_descent.py | 14 +- sklearn/linear_model/tests/test_sgd.py | 28 ++-- .../tests/test_sparse_coordinate_descent.py | 9 +- sklearn/manifold/_isomap.py | 2 + sklearn/manifold/_locally_linear.py | 23 ++- sklearn/manifold/_spectral_embedding.py | 17 +- sklearn/manifold/_t_sne.py | 8 +- .../manifold/tests/test_spectral_embedding.py | 6 +- sklearn/metrics/_classification.py | 9 +- .../_datasets_pair.pyx.tp | 14 +- .../_middle_term_computer.pyx.tp | 10 +- sklearn/metrics/_ranking.py | 6 +- sklearn/metrics/cluster/_supervised.py | 11 +- sklearn/metrics/pairwise.py | 9 +- sklearn/multiclass.py | 2 +- sklearn/multioutput.py | 3 +- sklearn/neighbors/_base.py | 17 +- sklearn/preprocessing/_data.py | 22 +-- sklearn/preprocessing/_encoders.py | 17 +- sklearn/preprocessing/_label.py | 18 +- sklearn/preprocessing/_polynomial.py | 30 ++-- sklearn/preprocessing/tests/test_data.py | 5 +- sklearn/random_projection.py | 15 +- sklearn/semi_supervised/_label_propagation.py | 20 ++- sklearn/svm/_base.py | 33 ++-- sklearn/svm/_libsvm_sparse.pyx | 5 +- sklearn/tests/test_base.py | 7 +- sklearn/tests/test_common.py | 1 + sklearn/tests/test_config.py | 3 + sklearn/tests/test_docstrings.py | 1 + sklearn/tree/_tree.pyx | 20 ++- sklearn/utils/__init__.py | 2 + sklearn/utils/_indexing.py | 22 ++- sklearn/utils/_mask.py | 9 +- sklearn/utils/_param_validation.py | 6 +- sklearn/utils/_sparse.py | 39 +++++ sklearn/utils/extmath.py | 8 +- sklearn/utils/fixes.py | 154 +++++++++++++++++- sklearn/utils/graph.py | 2 +- sklearn/utils/random.py | 4 +- sklearn/utils/sparsefuncs.py | 110 ++++++------- sklearn/utils/sparsefuncs_fast.pyx | 12 +- sklearn/utils/tests/test_estimator_checks.py | 10 ++ sklearn/utils/tests/test_extmath.py | 7 +- sklearn/utils/tests/test_fixes.py | 44 ++++- sklearn/utils/tests/test_param_validation.py | 3 +- sklearn/utils/tests/test_sparse.py | 78 +++++++++ sklearn/utils/tests/test_sparsefuncs.py | 33 ++-- sklearn/utils/tests/test_testing.py | 6 +- sklearn/utils/tests/test_validation.py | 70 +++++--- sklearn/utils/validation.py | 14 +- 99 files changed, 1123 insertions(+), 508 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/many-modules/31177.major-feature.rst create mode 100644 sklearn/utils/_sparse.py create mode 100644 sklearn/utils/tests/test_sparse.py diff --git a/asv_benchmarks/benchmarks/datasets.py b/asv_benchmarks/benchmarks/datasets.py index bbf5029062448..3bbfd143ba51b 100644 --- a/asv_benchmarks/benchmarks/datasets.py +++ b/asv_benchmarks/benchmarks/datasets.py @@ -1,7 +1,6 @@ from pathlib import Path import numpy as np -import scipy.sparse as sp from joblib import Memory from sklearn.datasets import ( @@ -17,6 +16,7 @@ from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.model_selection import train_test_split from sklearn.preprocessing import MaxAbsScaler, StandardScaler +from sklearn.utils.fixes import _sparse_random_array # memory location for caching datasets M = Memory(location=str(Path(__file__).resolve().parent / "cache")) @@ -100,12 +100,12 @@ def _synth_regression_dataset(n_samples=100000, n_features=100, dtype=np.float32 def _synth_regression_sparse_dataset( n_samples=10000, n_features=10000, density=0.01, dtype=np.float32 ): - X = sp.random( - m=n_samples, n=n_features, density=density, format="csr", random_state=0 + X = _sparse_random_array( + (n_samples, n_features), density=density, format="csr", random_state=0 ) X.data = np.random.RandomState(0).randn(X.getnnz()) X = X.astype(dtype, copy=False) - coefs = sp.random(m=n_features, n=1, density=0.5, random_state=0) + coefs = _sparse_random_array((n_features, 1), density=0.5, random_state=0) coefs.data = np.random.RandomState(0).randn(coefs.getnnz()) y = X.dot(coefs.toarray()).reshape(-1) y += 0.2 * y.std() * np.random.randn(n_samples) @@ -155,9 +155,8 @@ def _random_dataset( X = np.random.RandomState(0).random_sample((n_samples, n_features)) X = X.astype(dtype, copy=False) else: - X = sp.random( - n_samples, - n_features, + X = _sparse_random_array( + (n_samples, n_features), density=0.05, format="csr", dtype=dtype, diff --git a/benchmarks/bench_feature_expansions.py b/benchmarks/bench_feature_expansions.py index b9d9efbdea4f1..e3d972c891233 100644 --- a/benchmarks/bench_feature_expansions.py +++ b/benchmarks/bench_feature_expansions.py @@ -2,9 +2,9 @@ import matplotlib.pyplot as plt import numpy as np -import scipy.sparse as sparse from sklearn.preprocessing import PolynomialFeatures +from sklearn.utils.fixes import _sparse_random_array degree = 2 trials = 3 @@ -21,7 +21,7 @@ for density in densities: for dim_index, dim in enumerate(dimensionalities): print(trial, density, dim) - X_csr = sparse.random(num_rows, dim, density).tocsr() + X_csr = _sparse_random_array((num_rows, dim), density=density, format="csr") X_dense = X_csr.toarray() # CSR t0 = time() diff --git a/benchmarks/bench_plot_randomized_svd.py b/benchmarks/bench_plot_randomized_svd.py index e955be64cdee3..7e5f4cdf01466 100644 --- a/benchmarks/bench_plot_randomized_svd.py +++ b/benchmarks/bench_plot_randomized_svd.py @@ -188,7 +188,7 @@ def get_data(dataset_name): data = np.repeat(data, 10) row = np.random.uniform(0, small_size, sparsity) col = np.random.uniform(0, small_size, sparsity) - X = sp.sparse.csr_matrix((data, (row, col)), shape=(size, small_size)) + X = sp.sparse.csr_array((data, (row, col)), shape=(size, small_size)) del data del row del col diff --git a/benchmarks/bench_random_projections.py b/benchmarks/bench_random_projections.py index 6551de690994b..8ec4b264be76c 100644 --- a/benchmarks/bench_random_projections.py +++ b/benchmarks/bench_random_projections.py @@ -70,7 +70,7 @@ def bench_scikit_transformer(X, transformer): # Gaussian distributed values def make_sparse_random_data(n_samples, n_features, n_nonzeros, random_state=None): rng = np.random.RandomState(random_state) - data_coo = sp.coo_matrix( + data_coo = sp.coo_array( ( rng.randn(n_nonzeros), ( diff --git a/doc/modules/impute.rst b/doc/modules/impute.rst index 59367b647dd58..9a9e05d830e26 100644 --- a/doc/modules/impute.rst +++ b/doc/modules/impute.rst @@ -56,11 +56,11 @@ that contain the missing values:: The :class:`SimpleImputer` class also supports sparse matrices:: >>> import scipy.sparse as sp - >>> X = sp.csc_matrix([[1, 2], [0, -1], [8, 4]]) + >>> X = sp.csc_array([[1, 2], [0, -1], [8, 4]]) >>> imp = SimpleImputer(missing_values=-1, strategy='mean') >>> imp.fit(X) SimpleImputer(missing_values=-1) - >>> X_test = sp.csc_matrix([[-1, 2], [6, -1], [7, 6]]) + >>> X_test = sp.csc_array([[-1, 2], [6, -1], [7, 6]]) >>> print(imp.transform(X_test).toarray()) [[3. 2.] [6. 3.] diff --git a/doc/modules/multiclass.rst b/doc/modules/multiclass.rst index f2e5182faab4b..4f735e9c2a70c 100644 --- a/doc/modules/multiclass.rst +++ b/doc/modules/multiclass.rst @@ -169,9 +169,9 @@ Valid :term:`multiclass` representations for [1 0 0] [0 1 0]] >>> from scipy import sparse - >>> y_sparse = sparse.csr_matrix(y_dense) + >>> y_sparse = sparse.csr_array(y_dense) >>> print(y_sparse) - <Compressed Sparse Row sparse matrix of dtype 'int64' + <Compressed Sparse Row sparse array of dtype 'int64' with 4 stored elements and shape (4, 3)> Coords Values (0, 0) 1 @@ -379,9 +379,9 @@ refer to :ref:`preprocessing_targets`. An example of the same ``y`` in sparse matrix form: - >>> y_sparse = sparse.csr_matrix(y) + >>> y_sparse = sparse.csr_array(y) >>> print(y_sparse) - <Compressed Sparse Row sparse matrix of dtype 'int64' + <Compressed Sparse Row sparse array of dtype 'int64' with 4 stored elements and shape (3, 4)> Coords Values (0, 0) 1 diff --git a/doc/whats_new/upcoming_changes/many-modules/31177.major-feature.rst b/doc/whats_new/upcoming_changes/many-modules/31177.major-feature.rst new file mode 100644 index 0000000000000..18e84470e1ef4 --- /dev/null +++ b/doc/whats_new/upcoming_changes/many-modules/31177.major-feature.rst @@ -0,0 +1,9 @@ +- Introduced a new config key: "sparse_interface" to control whether functions + return sparse objects using SciPy sparse matrix or SciPy sparse array. + Use `sklearn.set_config(sparse_interface="sparray")` to have sklearn + return sparse arrays. See more at `the SciPy Sparse Migration Guide. + <https://docs.scipy.org/doc/scipy/reference/sparse.migration_to_sparray.html>`_ + The scikit-learn config "sparse_interface" initially defaults + to sparse matrix ("spmatrix"). The plan is to have the default change to + sparse array ("sparray") in a few releases. + By :user:`Dan Schult <dschult>` diff --git a/examples/applications/plot_tomography_l1_reconstruction.py b/examples/applications/plot_tomography_l1_reconstruction.py index 02d4594b90518..7be4947ea8a18 100644 --- a/examples/applications/plot_tomography_l1_reconstruction.py +++ b/examples/applications/plot_tomography_l1_reconstruction.py @@ -89,7 +89,9 @@ def build_projection_operator(l_x, n_dir): weights += list(w[mask]) camera_inds += list(inds[mask] + i * l_x) data_inds += list(data_unravel_indices[mask]) - proj_operator = sparse.coo_matrix((weights, (camera_inds, data_inds))) + camera_inds = np.array(camera_inds, dtype=np.int32) # lasso needs int32 inds + data_inds = np.array(data_inds, dtype=np.int32) + proj_operator = sparse.coo_array((weights, (camera_inds, data_inds))) return proj_operator diff --git a/examples/applications/wikipedia_principal_eigenvector.py b/examples/applications/wikipedia_principal_eigenvector.py index 2ccd028b9a00d..b59cf8eb6c058 100644 --- a/examples/applications/wikipedia_principal_eigenvector.py +++ b/examples/applications/wikipedia_principal_eigenvector.py @@ -146,7 +146,7 @@ def get_adjacency_matrix(redirects_filename, page_links_filename, limit=None): break print("Computing the adjacency matrix") - X = sparse.lil_matrix((len(index_map), len(index_map)), dtype=np.float32) + X = sparse.lil_array((len(index_map), len(index_map)), dtype=np.float32) for i, j in links: X[i, j] = 1.0 del links diff --git a/examples/linear_model/plot_lasso_dense_vs_sparse_data.py b/examples/linear_model/plot_lasso_dense_vs_sparse_data.py index 920994da1ffb5..e0763448bd59e 100644 --- a/examples/linear_model/plot_lasso_dense_vs_sparse_data.py +++ b/examples/linear_model/plot_lasso_dense_vs_sparse_data.py @@ -32,7 +32,7 @@ X, y = make_regression(n_samples=200, n_features=5000, random_state=0) # create a copy of X in sparse format -X_sp = sparse.coo_matrix(X) +X_sp = sparse.coo_array(X) alpha = 1 sparse_lasso = Lasso(alpha=alpha, fit_intercept=False, max_iter=1000) @@ -64,7 +64,7 @@ # make Xs sparse by replacing the values lower than 2.5 with 0s Xs[Xs < 2.5] = 0.0 # create a copy of Xs in sparse format -Xs_sp = sparse.coo_matrix(Xs) +Xs_sp = sparse.coo_array(Xs) Xs_sp = Xs_sp.tocsc() # compute the proportion of non-zero coefficient in the data matrix diff --git a/examples/neighbors/approximate_nearest_neighbors.py b/examples/neighbors/approximate_nearest_neighbors.py index eaacaf25f03d6..fa54f563c0936 100644 --- a/examples/neighbors/approximate_nearest_neighbors.py +++ b/examples/neighbors/approximate_nearest_neighbors.py @@ -39,7 +39,7 @@ # `nmslib`, as well as a loading function. import joblib import numpy as np -from scipy.sparse import csr_matrix +from scipy.sparse import csr_array from sklearn.base import BaseEstimator, TransformerMixin from sklearn.datasets import fetch_openml @@ -93,7 +93,7 @@ def transform(self, X): indices, distances = np.vstack(indices), np.vstack(distances) indptr = np.arange(0, n_samples_transform * n_neighbors + 1, n_neighbors) - kneighbors_graph = csr_matrix( + kneighbors_graph = csr_array( (distances.ravel(), indices.ravel(), indptr), shape=(n_samples_transform, self.n_samples_fit_), ) diff --git a/sklearn/_config.py b/sklearn/_config.py index 217386c81c80e..e2b02275c33a5 100644 --- a/sklearn/_config.py +++ b/sklearn/_config.py @@ -20,6 +20,7 @@ "transform_output": "default", "enable_metadata_routing": False, "skip_parameter_validation": False, + "sparse_interface": "spmatrix", } _threadlocal = threading.local() @@ -71,6 +72,7 @@ def set_config( transform_output=None, enable_metadata_routing=None, skip_parameter_validation=None, + sparse_interface=None, ): """Set global scikit-learn configuration. @@ -193,6 +195,16 @@ def set_config( .. versionadded:: 1.3 + sparse_interface : str, default="spmatrix" + + The sparse interface used for every sparse object that scikit-learn produces, + e.g., function returns, estimator attributes, estimator properties, etc. + + - `"sparray"`: Return sparse as SciPy sparse array + - `"spmatrix"`: Return sparse as SciPy sparse matrix + + .. versionadded:: 1.9 + See Also -------- config_context : Context manager for global scikit-learn configuration. @@ -228,6 +240,8 @@ def set_config( local_config["enable_metadata_routing"] = enable_metadata_routing if skip_parameter_validation is not None: local_config["skip_parameter_validation"] = skip_parameter_validation + if sparse_interface is not None: + local_config["sparse_interface"] = sparse_interface @contextmanager @@ -243,6 +257,7 @@ def config_context( transform_output=None, enable_metadata_routing=None, skip_parameter_validation=None, + sparse_interface=None, ): """Context manager to temporarily change the global scikit-learn configuration. @@ -360,6 +375,16 @@ def config_context( .. versionadded:: 1.3 + sparse_interface : str, default="spmatrix" + + The sparse interface used for every sparse object that scikit-learn produces, + e.g., function returns, estimator attributes, estimator properties, etc. + + - `"sparray"`: Return sparse as SciPy sparse array + - `"spmatrix"`: Return sparse as SciPy sparse matrix + + .. versionadded:: 1.8 + Yields ------ None. @@ -399,6 +424,7 @@ def config_context( transform_output=transform_output, enable_metadata_routing=enable_metadata_routing, skip_parameter_validation=skip_parameter_validation, + sparse_interface=sparse_interface, ) try: diff --git a/sklearn/cluster/_agglomerative.py b/sklearn/cluster/_agglomerative.py index 776cb8ea2a712..50d1acd37847e 100644 --- a/sklearn/cluster/_agglomerative.py +++ b/sklearn/cluster/_agglomerative.py @@ -38,6 +38,7 @@ StrOptions, validate_params, ) +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils.graph import _fix_connected_components from sklearn.utils.validation import check_memory, validate_data @@ -92,7 +93,7 @@ def _fix_connectivity(X, connectivity, affinity): # Convert connectivity matrix to LIL if not sparse.issparse(connectivity): - connectivity = sparse.lil_matrix(connectivity) + connectivity = sparse.lil_array(connectivity) # `connectivity` is a sparse matrix at this point if connectivity.format != "lil": @@ -118,7 +119,7 @@ def _fix_connectivity(X, connectivity, affinity): mode="connectivity", ) - return connectivity, n_connected_components + return _align_api_if_sparse(connectivity), n_connected_components def _single_linkage_tree( diff --git a/sklearn/cluster/_bicluster.py b/sklearn/cluster/_bicluster.py index 83ad3fef2519a..38af90e513e8a 100644 --- a/sklearn/cluster/_bicluster.py +++ b/sklearn/cluster/_bicluster.py @@ -8,7 +8,7 @@ import numpy as np from scipy.linalg import norm -from scipy.sparse import dia_matrix, issparse +from scipy.sparse import dia_array, issparse from scipy.sparse.linalg import eigsh, svds from sklearn.base import BaseEstimator, BiclusterMixin, _fit_context @@ -34,8 +34,8 @@ def _scale_normalize(X): col_diag = np.where(np.isnan(col_diag), 0, col_diag) if issparse(X): n_rows, n_cols = X.shape - r = dia_matrix((row_diag, [0]), shape=(n_rows, n_rows)) - c = dia_matrix((col_diag, [0]), shape=(n_cols, n_cols)) + r = dia_array((row_diag, [0]), shape=(n_rows, n_rows)) + c = dia_array((col_diag, [0]), shape=(n_cols, n_cols)) an = r @ X @ c else: an = row_diag[:, np.newaxis] * X * col_diag diff --git a/sklearn/cluster/_spectral.py b/sklearn/cluster/_spectral.py index 43fdc39c4dccd..877c849a10ef7 100644 --- a/sklearn/cluster/_spectral.py +++ b/sklearn/cluster/_spectral.py @@ -8,7 +8,7 @@ import numpy as np from scipy.linalg import LinAlgError, qr, svd -from scipy.sparse import csc_matrix +from scipy.sparse import csc_array from sklearn.base import BaseEstimator, ClusterMixin, _fit_context from sklearn.cluster._kmeans import k_means @@ -160,7 +160,7 @@ def discretize( t_discrete = np.dot(vectors, rotation) labels = t_discrete.argmax(axis=1) - vectors_discrete = csc_matrix( + vectors_discrete = csc_array( (np.ones(len(labels)), (np.arange(0, n_samples), labels)), shape=(n_samples, n_components), ) diff --git a/sklearn/cluster/tests/test_hierarchical.py b/sklearn/cluster/tests/test_hierarchical.py index 222d4f6cd9264..a4f19abdca9ad 100644 --- a/sklearn/cluster/tests/test_hierarchical.py +++ b/sklearn/cluster/tests/test_hierarchical.py @@ -177,6 +177,7 @@ def test_agglomerative_clustering_distances( assert not hasattr(clustering, "distances_") +@pytest.mark.no_check_spmatrix # pickle breaks check_spmatrix @pytest.mark.parametrize("lil_container", LIL_CONTAINERS) def test_agglomerative_clustering(global_random_seed, lil_container): # Check that we obtain the correct number of clusters with diff --git a/sklearn/cluster/tests/test_k_means.py b/sklearn/cluster/tests/test_k_means.py index da1a2a0f13765..bea412b5cdf55 100644 --- a/sklearn/cluster/tests/test_k_means.py +++ b/sklearn/cluster/tests/test_k_means.py @@ -6,7 +6,6 @@ import numpy as np import pytest -from scipy import sparse as sp from threadpoolctl import threadpool_info from sklearn.base import clone @@ -32,7 +31,7 @@ create_memmap_backed_data, ) from sklearn.utils.extmath import row_norms -from sklearn.utils.fixes import CSR_CONTAINERS +from sklearn.utils.fixes import CSR_CONTAINERS, _sparse_random_array from sklearn.utils.parallel import _get_threadpool_controller # non centered, sparse centers to check the @@ -1043,8 +1042,8 @@ def test_euclidean_distance(dtype, squared, global_random_seed): # Check that the _euclidean_(dense/sparse)_dense helpers produce correct # results rng = np.random.RandomState(global_random_seed) - a_sparse = sp.random( - 1, 100, density=0.5, format="csr", random_state=rng, dtype=dtype + a_sparse = _sparse_random_array( + (1, 100), density=0.5, format="csr", rng=rng, dtype=dtype ) a_dense = a_sparse.toarray().reshape(-1) b = rng.randn(100).astype(dtype, copy=False) @@ -1068,8 +1067,8 @@ def test_euclidean_distance(dtype, squared, global_random_seed): def test_inertia(dtype, global_random_seed): # Check that the _inertia_(dense/sparse) helpers produce correct results. rng = np.random.RandomState(global_random_seed) - X_sparse = sp.random( - 100, 10, density=0.5, format="csr", random_state=rng, dtype=dtype + X_sparse = _sparse_random_array( + (100, 10), density=0.5, format="csr", rng=rng, dtype=dtype ) X_dense = X_sparse.toarray() sample_weight = rng.randn(100).astype(dtype, copy=False) diff --git a/sklearn/cluster/tests/test_spectral.py b/sklearn/cluster/tests/test_spectral.py index 9888afed16f17..8aa17be33c590 100644 --- a/sklearn/cluster/tests/test_spectral.py +++ b/sklearn/cluster/tests/test_spectral.py @@ -36,6 +36,7 @@ ) +@pytest.mark.no_check_spmatrix # pickle breaks check_spmatrix @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) @pytest.mark.parametrize("eigen_solver", ("arpack", "lobpcg")) @pytest.mark.parametrize("assign_labels", ("kmeans", "discretize", "cluster_qr")) diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index 63821b57c2d7f..6f4cbd6bb2ed5 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -40,7 +40,7 @@ assert_almost_equal, assert_array_equal, ) -from sklearn.utils.fixes import CSR_CONTAINERS, parse_version +from sklearn.utils.fixes import CSR_CONTAINERS, _sparse_eye_array, parse_version class Trans(TransformerMixin, BaseEstimator): @@ -74,7 +74,7 @@ def fit(self, X, y=None): def transform(self, X, y=None): n_samples = len(X) - return self.csr_container(sparse.eye(n_samples, n_samples)) + return self.csr_container(_sparse_eye_array(n_samples)) class TransNo2D(BaseEstimator): @@ -490,7 +490,7 @@ def test_column_transformer_output_indices_df(): @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) def test_column_transformer_sparse_array(csr_container): - X_sparse = csr_container(sparse.eye(3, 2)) + X_sparse = csr_container(_sparse_eye_array(3, 2)) # no distinction between 1D and 2D X_res_first = X_sparse[:, [0]] diff --git a/sklearn/conftest.py b/sklearn/conftest.py index 0d7cd01b60258..a4490844547e1 100644 --- a/sklearn/conftest.py +++ b/sklearn/conftest.py @@ -271,6 +271,111 @@ def pyplot(): pyplot.close("all") +def munge_scipy_to_check_spmatrix_usage(): + import scipy + + def flag_this_call(*args, **kwds): + raise ValueError("Old spmatrix function called. Use e.g. block or random.") + + scipy.sparse._construct.bmat = flag_this_call + scipy.sparse._construct.rand = flag_this_call + scipy.sparse._construct.rand = flag_this_call + + class _strict_mul_mixin: + def __mul__(self, other): + if not scipy.sparse._sputils.isscalarlike(other): + raise ValueError("Operator * used here! Change to @?") + return super().__mul__(other) + + def __rmul__(self, other): + if not scipy.sparse._sputils.isscalarlike(other): + raise ValueError("Operator * used here! Change to @?") + return super().__rmul__(other) + + def __imul__(self, other): + if not scipy.sparse._sputils.isscalarlike(other): + raise ValueError("Operator * used here! Change to @?") + return super().__imul__(other) + + def __pow__(self, *args, **kwargs): + raise ValueError("spmatrix ** used here! Use sparse.linalg.matrix_power?") + + @property + def A(self): + raise TypeError("spmatrix A property is not allowed! Use .toarray()") + + @property + def H(self): + raise TypeError("spmatrix H property is not allowed! Use .conjugate().T") + + def asfptype(self): + raise TypeError("spmatrix asfptype is not allowed! rewrite needed") + + def get_shape(self): + raise TypeError("spmatrix get_shape is not allowed! Use .shape") + + def getformat(self): + raise TypeError("spmatrix getformat is not allowed! Use .shape") + + def getmaxprint(self): + raise TypeError("spmatrix getmaxprint is not allowed! Use .shape") + + def getnnz(self): + raise TypeError("spmatrix getnnz is not allowed! Use .shape") + + def getH(self): + raise TypeError("spmatrix getH is not allowed! Use .shape") + + def getrow(self): + raise TypeError("spmatrix getrow is not allowed! Use .shape") + + def getcol(self): + raise TypeError("spmatrix getcol is not allowed! Use .shape") + + class _strict_coo_matrix(_strict_mul_mixin, scipy.sparse.coo_matrix): + pass + + class _strict_bsr_matrix(_strict_mul_mixin, scipy.sparse.bsr_matrix): + pass + + class _strict_csr_matrix(_strict_mul_mixin, scipy.sparse.csr_matrix): + pass + + class _strict_csc_matrix(_strict_mul_mixin, scipy.sparse.csc_matrix): + pass + + class _strict_dok_matrix(_strict_mul_mixin, scipy.sparse.dok_matrix): + pass + + class _strict_lil_matrix(_strict_mul_mixin, scipy.sparse.lil_matrix): + pass + + class _strict_dia_matrix(_strict_mul_mixin, scipy.sparse.dia_matrix): + pass + + scipy.sparse.coo_matrix = scipy.sparse._coo.coo_matrix = _strict_coo_matrix + scipy.sparse.bsr_matrix = scipy.sparse._bsr.bsr_matrix = _strict_bsr_matrix + scipy.sparse.csr_matrix = scipy.sparse._csr.csr_matrix = _strict_csr_matrix + scipy.sparse.csc_matrix = scipy.sparse._csc.csc_matrix = _strict_csc_matrix + scipy.sparse.dok_matrix = scipy.sparse._dok.dok_matrix = _strict_dok_matrix + scipy.sparse.lil_matrix = scipy.sparse._lil.lil_matrix = _strict_lil_matrix + scipy.sparse.dia_matrix = scipy.sparse._dia.dia_matrix = _strict_dia_matrix + + scipy.sparse._construct.bsr_matrix = _strict_bsr_matrix + scipy.sparse._construct.coo_matrix = _strict_coo_matrix + scipy.sparse._construct.csc_matrix = _strict_csc_matrix + scipy.sparse._construct.csr_matrix = _strict_csr_matrix + scipy.sparse._construct.dia_matrix = _strict_dia_matrix + + scipy.sparse._matrix.bsr_matrix = _strict_bsr_matrix + scipy.sparse._matrix.coo_matrix = _strict_coo_matrix + scipy.sparse._matrix.csc_matrix = _strict_csc_matrix + scipy.sparse._matrix.csr_matrix = _strict_csr_matrix + scipy.sparse._matrix.dia_matrix = _strict_dia_matrix + scipy.sparse._matrix.dok_matrix = _strict_dok_matrix + scipy.sparse._matrix.lil_matrix = _strict_lil_matrix + + def pytest_generate_tests(metafunc): """Parametrization of global_random_seed fixture @@ -319,6 +424,17 @@ def pytest_generate_tests(metafunc): def pytest_addoption(parser, pluginmanager): if not PARALLEL_RUN_AVAILABLE: parser.addini("thread_unsafe_fixtures", "list of stuff") + parser.addoption( + "--check_spmatrix", + action="store_true", + default=False, + help="raise for spmatrix usage that breaks sparray", + ) + + +def pytest_runtest_setup(item): + if "no_check_spmatrix" in item.keywords and item.config.option.check_spmatrix: + pytest.skip("skip due to check_spmatrix scipy patch breaking this test") def pytest_configure(config): @@ -345,6 +461,14 @@ def pytest_configure(config): for line in get_pytest_filterwarning_lines(): config.addinivalue_line("filterwarnings", line) + if config.option.check_spmatrix: + # Note: this patches scipy.sparse to raise upon outdated spmatrix usage + # If you run into this with new PR code to sklearn, make sure it: + # - converts spmatrix input to sparray + # - uses the sparray interface for manipulating the sparse object + # - uses align_api_if_sparse(X) just before returning a sparse object + munge_scipy_to_check_spmatrix_usage() + if not PARALLEL_RUN_AVAILABLE: config.addinivalue_line( "markers", diff --git a/sklearn/datasets/_arff_parser.py b/sklearn/datasets/_arff_parser.py index 311dc6d8db993..2df375e410c8b 100644 --- a/sklearn/datasets/_arff_parser.py +++ b/sklearn/datasets/_arff_parser.py @@ -16,6 +16,7 @@ from sklearn.externals._arff import ArffSparseDataType from sklearn.utils._chunking import chunk_generator, get_chunk_n_rows from sklearn.utils._optional_dependencies import check_pandas_support +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils.fixes import pd_fillna @@ -262,12 +263,12 @@ def _io_to_generator(gzip_file): arff_data_X = _split_sparse_columns(arff_data, feature_indices_to_select) num_obs = max(arff_data[1]) + 1 X_shape = (num_obs, len(feature_indices_to_select)) - X = sp.sparse.coo_matrix( + X = sp.sparse.coo_array( (arff_data_X[0], (arff_data_X[1], arff_data_X[2])), shape=X_shape, dtype=np.float64, ) - X = X.tocsr() + X = _align_api_if_sparse(X.tocsr()) y = _sparse_data_to_array(arff_data, target_indices_to_select) else: # This should never happen diff --git a/sklearn/datasets/_rcv1.py b/sklearn/datasets/_rcv1.py index c5be518a1d711..cc173f97791e8 100644 --- a/sklearn/datasets/_rcv1.py +++ b/sklearn/datasets/_rcv1.py @@ -29,6 +29,7 @@ from sklearn.utils import Bunch from sklearn.utils import shuffle as shuffle_ from sklearn.utils._param_validation import Interval, StrOptions, validate_params +from sklearn.utils._sparse import _align_api_if_sparse # The original vectorized data can be found at: # http://www.ai.mit.edu/projects/jmlr/papers/volume5/lewis04a/a13-vector-files/lyrl2004_vectors_test_pt0.dat.gz @@ -285,7 +286,7 @@ def fetch_rcv1( # reorder categories in lexicographic order order = np.argsort(categories) categories = categories[order] - y = sp.csr_matrix(y[:, order]) + y = _align_api_if_sparse(sp.csr_array(y[:, order])) joblib.dump(y, sample_topics_path, compress=9) joblib.dump(categories, topics_path, compress=9) @@ -314,6 +315,7 @@ def fetch_rcv1( fdescr = load_descr("rcv1.rst") + X = _align_api_if_sparse(X) if return_X_y: return X, y diff --git a/sklearn/datasets/_samples_generator.py b/sklearn/datasets/_samples_generator.py index 96eb154439ebb..98e7826bea2d5 100644 --- a/sklearn/datasets/_samples_generator.py +++ b/sklearn/datasets/_samples_generator.py @@ -18,6 +18,12 @@ from sklearn.utils import Bunch, check_array, check_random_state from sklearn.utils import shuffle as util_shuffle from sklearn.utils._param_validation import Interval, StrOptions, validate_params +from sklearn.utils._sparse import _align_api_if_sparse +from sklearn.utils.fixes import ( + _sparse_diags_array, + _sparse_eye_array, + _sparse_random_array, +) from sklearn.utils.random import sample_without_replacement @@ -549,10 +555,12 @@ def sample_example(): X_indptr.append(len(X_indices)) Y.append(y) X_data = np.ones(len(X_indices), dtype=np.float64) - X = sp.csr_matrix((X_data, X_indices, X_indptr), shape=(n_samples, n_features)) + X = sp.csr_array((X_data, X_indices, X_indptr), shape=(n_samples, n_features)) X.sum_duplicates() if not sparse: X = X.toarray() + else: + X = _align_api_if_sparse(X) # return_indicator can be True due to backward compatibility if return_indicator in (True, "sparse", "dense"): @@ -1817,13 +1825,12 @@ def make_sparse_spd_matrix( """ random_state = check_random_state(random_state) - chol = -sp.eye(n_dim) - aux = sp.random( - m=n_dim, - n=n_dim, + chol = -_sparse_eye_array(n_dim) + aux = _sparse_random_array( + shape=(n_dim, n_dim), density=1 - alpha, - data_rvs=lambda x: random_state.uniform( - low=smallest_coef, high=largest_coef, size=x + data_sampler=lambda size: random_state.uniform( + low=smallest_coef, high=largest_coef, size=size ), random_state=random_state, ) @@ -1839,13 +1846,13 @@ def make_sparse_spd_matrix( if norm_diag: # Form the diagonal vector into a row matrix - d = sp.diags(1.0 / np.sqrt(prec.diagonal())) + d = _sparse_diags_array(1.0 / np.sqrt(prec.diagonal())) prec = d @ prec @ d if sparse_format is None: return prec.toarray() else: - return prec.asformat(sparse_format) + return _align_api_if_sparse(prec.asformat(sparse_format)) @validate_params( diff --git a/sklearn/datasets/_svmlight_format_io.py b/sklearn/datasets/_svmlight_format_io.py index 13e5d650dc2cc..5c26e711a054a 100644 --- a/sklearn/datasets/_svmlight_format_io.py +++ b/sklearn/datasets/_svmlight_format_io.py @@ -32,6 +32,7 @@ StrOptions, validate_params, ) +from sklearn.utils._sparse import _align_api_if_sparse @validate_params( @@ -409,9 +410,9 @@ def get_data(): result = [] for data, indices, indptr, y, query_values in r: shape = (indptr.shape[0] - 1, n_features) - X = sp.csr_matrix((data, indices, indptr), shape) + X = sp.csr_array((data, indices, indptr), shape) X.sort_indices() - result += X, y + result += _align_api_if_sparse(X), y if query_id: result.append(query_values) diff --git a/sklearn/datasets/tests/test_samples_generator.py b/sklearn/datasets/tests/test_samples_generator.py index 81e8183c6722e..2abb218dc7467 100644 --- a/sklearn/datasets/tests/test_samples_generator.py +++ b/sklearn/datasets/tests/test_samples_generator.py @@ -322,19 +322,22 @@ def test_make_multilabel_classification_return_indicator(): assert_almost_equal(p_w_c.sum(axis=0), [1] * 3) -def test_make_multilabel_classification_return_indicator_sparse(): - for allow_unlabeled, min_length in zip((True, False), (0, 1)): - X, Y = make_multilabel_classification( - n_samples=25, - n_features=20, - n_classes=3, - random_state=0, - return_indicator="sparse", - allow_unlabeled=allow_unlabeled, - ) - assert X.shape == (25, 20), "X shape mismatch" - assert Y.shape == (25, 3), "Y shape mismatch" - assert sp.issparse(Y) +@pytest.mark.parametrize("allow_unlabeled", [True, False]) +@pytest.mark.parametrize("sparse_feature", [True, False]) +def test_make_multilabel_classification_return_sparse(allow_unlabeled, sparse_feature): + X, Y = make_multilabel_classification( + n_samples=25, + n_features=20, + n_classes=3, + random_state=0, + sparse=sparse_feature, + return_indicator="sparse", + allow_unlabeled=allow_unlabeled, + ) + assert X.shape == (25, 20), "X shape mismatch" + assert Y.shape == (25, 3), "Y shape mismatch" + assert sp.issparse(Y) + assert sp.issparse(X) if sparse_feature else not sp.issparse(X) def test_make_hastie_10_2(): diff --git a/sklearn/decomposition/_incremental_pca.py b/sklearn/decomposition/_incremental_pca.py index 3988b7fc97573..a9342cda2d869 100644 --- a/sklearn/decomposition/_incremental_pca.py +++ b/sklearn/decomposition/_incremental_pca.py @@ -177,7 +177,7 @@ class IncrementalPCA(_BasePCA): >>> transformer.partial_fit(X[:100, :]) IncrementalPCA(batch_size=200, n_components=7) >>> # or let the fit function itself divide the data into batches - >>> X_sparse = sparse.csr_matrix(X) + >>> X_sparse = sparse.csr_array(X) >>> X_transformed = transformer.fit_transform(X_sparse) >>> X_transformed.shape (1797, 7) diff --git a/sklearn/decomposition/_nmf.py b/sklearn/decomposition/_nmf.py index 25efec3d564ad..df271a02987ae 100644 --- a/sklearn/decomposition/_nmf.py +++ b/sklearn/decomposition/_nmf.py @@ -25,6 +25,7 @@ from sklearn.exceptions import ConvergenceWarning from sklearn.utils import check_array, check_random_state, gen_batches from sklearn.utils._param_validation import Interval, StrOptions, validate_params +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils.extmath import _randomized_svd, safe_sparse_dot, squared_norm from sklearn.utils.validation import check_is_fitted, check_non_negative, validate_data @@ -196,8 +197,8 @@ def _special_sparse_dot(W, H, X): axis=1 ) - WH = sp.coo_matrix((dot_vals, (ii, jj)), shape=X.shape) - return WH.tocsr() + WH = sp.coo_array((dot_vals, (ii, jj)), shape=X.shape) + return _align_api_if_sparse(WH.tocsr()) else: return np.dot(W, H) diff --git a/sklearn/decomposition/_truncated_svd.py b/sklearn/decomposition/_truncated_svd.py index e707f0d911cbb..c6decd460a898 100644 --- a/sklearn/decomposition/_truncated_svd.py +++ b/sklearn/decomposition/_truncated_svd.py @@ -141,12 +141,12 @@ class to data once, then keep the instance around to do transformations. Examples -------- >>> from sklearn.decomposition import TruncatedSVD - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> import numpy as np >>> np.random.seed(0) >>> X_dense = np.random.rand(100, 100) >>> X_dense[:, 2 * np.arange(50)] = 0 - >>> X = csr_matrix(X_dense) + >>> X = csr_array(X_dense) >>> svd = TruncatedSVD(n_components=5, n_iter=7, random_state=42) >>> svd.fit(X) TruncatedSVD(n_components=5, n_iter=7, random_state=42) diff --git a/sklearn/decomposition/tests/test_pca.py b/sklearn/decomposition/tests/test_pca.py index 588ca9fa6c677..23aa40cb63cf7 100644 --- a/sklearn/decomposition/tests/test_pca.py +++ b/sklearn/decomposition/tests/test_pca.py @@ -4,7 +4,6 @@ import numpy as np import pytest -import scipy as sp from numpy.testing import assert_array_equal from sklearn import config_context, datasets @@ -24,7 +23,7 @@ from sklearn.utils.estimator_checks import ( check_array_api_input_and_values, ) -from sklearn.utils.fixes import CSC_CONTAINERS, CSR_CONTAINERS +from sklearn.utils.fixes import CSC_CONTAINERS, CSR_CONTAINERS, _sparse_random_array iris = datasets.load_iris() PCA_SOLVERS = ["full", "covariance_eigh", "arpack", "randomized", "auto"] @@ -87,17 +86,12 @@ def test_pca_sparse( atol = 1e-12 transform_atol = 1e-10 - random_state = np.random.default_rng(global_random_seed) + rng = np.random.default_rng(global_random_seed) X = sparse_container( - sp.sparse.random( - SPARSE_M, - SPARSE_N, - random_state=random_state, - density=density, - ) + _sparse_random_array((SPARSE_M, SPARSE_N), rng=rng, density=density) ) # Scale the data + vary the column means - scale_vector = random_state.random(X.shape[1]) * scale + scale_vector = rng.random(X.shape[1]) * scale X = X.multiply(scale_vector) pca = PCA( @@ -120,12 +114,7 @@ def test_pca_sparse( # Test transform X2 = sparse_container( - sp.sparse.random( - SPARSE_M, - SPARSE_N, - random_state=random_state, - density=density, - ) + _sparse_random_array((SPARSE_M, SPARSE_N), rng=rng, density=density) ) X2d = X2.toarray() @@ -135,23 +124,10 @@ def test_pca_sparse( @pytest.mark.parametrize("sparse_container", CSR_CONTAINERS + CSC_CONTAINERS) def test_pca_sparse_fit_transform(global_random_seed, sparse_container): - random_state = np.random.default_rng(global_random_seed) - X = sparse_container( - sp.sparse.random( - SPARSE_M, - SPARSE_N, - random_state=random_state, - density=0.01, - ) - ) - X2 = sparse_container( - sp.sparse.random( - SPARSE_M, - SPARSE_N, - random_state=random_state, - density=0.01, - ) - ) + rng = np.random.default_rng(global_random_seed) + shp = (SPARSE_M, SPARSE_N) + X = sparse_container(_sparse_random_array(shp, rng=rng, density=0.01)) + X2 = sparse_container(_sparse_random_array(shp, rng=rng, density=0.01)) pca_fit = PCA(n_components=10, svd_solver="arpack", random_state=global_random_seed) pca_fit_transform = PCA( @@ -170,14 +146,8 @@ def test_pca_sparse_fit_transform(global_random_seed, sparse_container): @pytest.mark.parametrize("svd_solver", ["randomized", "full"]) @pytest.mark.parametrize("sparse_container", CSR_CONTAINERS + CSC_CONTAINERS) def test_sparse_pca_solver_error(global_random_seed, svd_solver, sparse_container): - random_state = np.random.RandomState(global_random_seed) - X = sparse_container( - sp.sparse.random( - SPARSE_M, - SPARSE_N, - random_state=random_state, - ) - ) + rng = np.random.RandomState(global_random_seed) + X = sparse_container(_sparse_random_array((SPARSE_M, SPARSE_N), rng=rng)) pca = PCA(n_components=30, svd_solver=svd_solver) error_msg_pattern = ( 'PCA only support sparse inputs with the "arpack" and "covariance_eigh"' @@ -192,14 +162,8 @@ def test_sparse_pca_auto_arpack_singluar_values_consistency( global_random_seed, sparse_container ): """Check that "auto" and "arpack" solvers are equivalent for sparse inputs.""" - random_state = np.random.RandomState(global_random_seed) - X = sparse_container( - sp.sparse.random( - SPARSE_M, - SPARSE_N, - random_state=random_state, - ) - ) + rng = np.random.RandomState(global_random_seed) + X = sparse_container(_sparse_random_array((SPARSE_M, SPARSE_N), rng=rng)) pca_arpack = PCA(n_components=10, svd_solver="arpack").fit(X) pca_auto = PCA(n_components=10, svd_solver="auto").fit(X) assert_allclose(pca_arpack.singular_values_, pca_auto.singular_values_, rtol=5e-3) diff --git a/sklearn/decomposition/tests/test_truncated_svd.py b/sklearn/decomposition/tests/test_truncated_svd.py index 373e6da8a8170..ef982abde2992 100644 --- a/sklearn/decomposition/tests/test_truncated_svd.py +++ b/sklearn/decomposition/tests/test_truncated_svd.py @@ -2,11 +2,11 @@ import numpy as np import pytest -import scipy.sparse as sp from sklearn.decomposition import PCA, TruncatedSVD from sklearn.utils import check_random_state from sklearn.utils._testing import assert_allclose, assert_array_less +from sklearn.utils.fixes import _sparse_random_array SVD_SOLVERS = ["arpack", "randomized"] @@ -15,7 +15,7 @@ def X_sparse(): # Make an X that looks somewhat like a small tf-idf matrix. rng = check_random_state(42) - X = sp.random(60, 55, density=0.2, format="csr", random_state=rng) + X = _sparse_random_array((60, 55), density=0.2, format="csr", rng=rng) X.data[:] = 1 + np.log(X.data) return X diff --git a/sklearn/ensemble/_gb.py b/sklearn/ensemble/_gb.py index 9ec8030899d18..0ab11c3dd7d32 100644 --- a/sklearn/ensemble/_gb.py +++ b/sklearn/ensemble/_gb.py @@ -26,7 +26,7 @@ from time import time import numpy as np -from scipy.sparse import csc_matrix, csr_matrix, issparse +from scipy.sparse import csc_array, csr_array, issparse from sklearn._loss.loss import ( _LOSSES, @@ -631,7 +631,7 @@ def fit(self, X, y, sample_weight=None, monitor=None): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. y : array-like of shape (n_samples,) Target values (strings or integers in classification, real numbers @@ -857,8 +857,8 @@ def _fit_stages( verbose_reporter = VerboseReporter(verbose=self.verbose) verbose_reporter.init(self, begin_at_stage) - X_csc = csc_matrix(X) if issparse(X) else None - X_csr = csr_matrix(X) if issparse(X) else None + X_csc = csc_array(X) if issparse(X) else None + X_csr = csr_array(X) if issparse(X) else None if self.n_iter_no_change is not None: loss_history = np.full(self.n_iter_no_change, np.inf) @@ -996,7 +996,7 @@ def _staged_raw_predict(self, X, check_input=True): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. check_input : bool, default=True If False, the input arrays X will not be checked. @@ -1111,7 +1111,7 @@ def apply(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, its dtype will be converted to ``dtype=np.float32``. If a sparse matrix is provided, it will - be converted to a sparse ``csr_matrix``. + be converted to a sparse ``csr_array``. Returns ------- @@ -1584,7 +1584,7 @@ def decision_function(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. Returns ------- @@ -1614,7 +1614,7 @@ def staged_decision_function(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. Yields ------ @@ -1635,7 +1635,7 @@ def predict(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. Returns ------- @@ -1660,7 +1660,7 @@ def staged_predict(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. Yields ------ @@ -1684,7 +1684,7 @@ def predict_proba(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. Returns ------- @@ -1708,7 +1708,7 @@ def predict_log_proba(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. Returns ------- @@ -1735,7 +1735,7 @@ def staged_predict_proba(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. Yields ------ @@ -2155,7 +2155,7 @@ def predict(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. Returns ------- @@ -2179,7 +2179,7 @@ def staged_predict(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, it will be converted to ``dtype=np.float32`` and if a sparse matrix is provided - to a sparse ``csr_matrix``. + to a sparse ``csr_array``. Yields ------ @@ -2199,7 +2199,7 @@ def apply(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The input samples. Internally, its dtype will be converted to ``dtype=np.float32``. If a sparse matrix is provided, it will - be converted to a sparse ``csr_matrix``. + be converted to a sparse ``csr_array``. Returns ------- diff --git a/sklearn/ensemble/tests/test_weight_boosting.py b/sklearn/ensemble/tests/test_weight_boosting.py index 618560f0971c0..0e1250fe19ec2 100644 --- a/sklearn/ensemble/tests/test_weight_boosting.py +++ b/sklearn/ensemble/tests/test_weight_boosting.py @@ -367,7 +367,7 @@ def fit(self, X, y, sample_weight=None): # Verify sparsity of data is maintained during training types = [i.data_type_ for i in sparse_classifier.estimators_] - assert all([t == expected_internal_type for t in types]) + assert all(issubclass(t, expected_internal_type) for t in types) @pytest.mark.parametrize( @@ -427,7 +427,7 @@ def fit(self, X, y, sample_weight=None): types = [i.data_type_ for i in sparse_regressor.estimators_] - assert all([t == expected_internal_type for t in types]) + assert all(issubclass(t, expected_internal_type) for t in types) def test_sample_weight_adaboost_regressor(): diff --git a/sklearn/externals/_scipy/sparse/csgraph/_laplacian.py b/sklearn/externals/_scipy/sparse/csgraph/_laplacian.py index 34c816628ee73..ade61f3f10d43 100644 --- a/sklearn/externals/_scipy/sparse/csgraph/_laplacian.py +++ b/sklearn/externals/_scipy/sparse/csgraph/_laplacian.py @@ -283,19 +283,19 @@ def laplacian( Our final example illustrates the latter for a noisy directed linear graph. - >>> from scipy.sparse import diags, random + >>> from scipy.sparse import diags_array, random_array >>> from scipy.sparse.linalg import lobpcg Create a directed linear graph with ``N=35`` vertices using a sparse adjacency matrix ``G``: >>> N = 35 - >>> G = diags(np.ones(N-1), 1, format="csr") + >>> G = diags_array((np.ones(N-1), 1), format="csr") Fix a random seed ``rng`` and add a random sparse noise to the graph ``G``: >>> rng = np.random.default_rng() - >>> G += 1e-2 * random(N, N, density=0.1, random_state=rng) + >>> G += 1e-2 * random_array((N, N), density=0.1, random_state=rng) Set initial approximations for eigenvectors: diff --git a/sklearn/feature_extraction/_dict_vectorizer.py b/sklearn/feature_extraction/_dict_vectorizer.py index f862a03bb1d97..ce16566aafc9e 100644 --- a/sklearn/feature_extraction/_dict_vectorizer.py +++ b/sklearn/feature_extraction/_dict_vectorizer.py @@ -10,7 +10,7 @@ import scipy.sparse as sp from sklearn.base import BaseEstimator, TransformerMixin, _fit_context -from sklearn.utils import check_array, metadata_routing +from sklearn.utils import _align_api_if_sparse, check_array, metadata_routing from sklearn.utils.validation import check_is_fitted @@ -267,7 +267,7 @@ def _transform(self, X, fitting): indices = np.frombuffer(indices, dtype=np.intc) shape = (len(indptr) - 1, len(vocab)) - result_matrix = sp.csr_matrix( + result_matrix = sp.csr_array( (values, indices, indptr), shape=shape, dtype=dtype ) @@ -289,7 +289,7 @@ def _transform(self, X, fitting): self.feature_names_ = feature_names self.vocabulary_ = vocab - return result_matrix + return _align_api_if_sparse(result_matrix) @_fit_context(prefer_skip_nested_validation=True) def fit_transform(self, X, y=None): diff --git a/sklearn/feature_extraction/_hash.py b/sklearn/feature_extraction/_hash.py index 814bf912a42fc..a11c3db59c94f 100644 --- a/sklearn/feature_extraction/_hash.py +++ b/sklearn/feature_extraction/_hash.py @@ -9,7 +9,7 @@ from sklearn.base import BaseEstimator, TransformerMixin, _fit_context from sklearn.feature_extraction._hashing_fast import transform as _hashing_transform -from sklearn.utils import metadata_routing +from sklearn.utils import _align_api_if_sparse, metadata_routing from sklearn.utils._param_validation import Interval, StrOptions @@ -188,14 +188,14 @@ def transform(self, raw_X): if n_samples == 0: raise ValueError("Cannot vectorize empty sequence.") - X = sp.csr_matrix( + X = sp.csr_array( (values, indices, indptr), dtype=self.dtype, shape=(n_samples, self.n_features), ) X.sum_duplicates() # also sorts the indices - return X + return _align_api_if_sparse(X) def __sklearn_tags__(self): tags = super().__sklearn_tags__() diff --git a/sklearn/feature_extraction/image.py b/sklearn/feature_extraction/image.py index 020620adf6cfc..32c2765cd841a 100644 --- a/sklearn/feature_extraction/image.py +++ b/sklearn/feature_extraction/image.py @@ -11,7 +11,7 @@ from scipy import sparse from sklearn.base import BaseEstimator, TransformerMixin, _fit_context -from sklearn.utils import check_array, check_random_state +from sklearn.utils import _align_api_if_sparse, check_array, check_random_state from sklearn.utils._param_validation import ( Hidden, Interval, @@ -94,7 +94,7 @@ def _mask_edges_weights(mask, edges, weights=None): def _to_graph( - n_x, n_y, n_z, mask=None, img=None, return_as=sparse.coo_matrix, dtype=None + n_x, n_y, n_z, mask=None, img=None, return_as=sparse.coo_array, dtype=None ): """Auxiliary function for img_to_graph and grid_to_graph""" edges = _make_edges_3d(n_x, n_y, n_z) @@ -127,7 +127,7 @@ def _to_graph( diag_idx = np.arange(n_voxels) i_idx = np.hstack((edges[0], edges[1])) j_idx = np.hstack((edges[1], edges[0])) - graph = sparse.coo_matrix( + graph = sparse.coo_array( ( np.hstack((weights, weights, diag)), (np.hstack((i_idx, diag_idx)), np.hstack((j_idx, diag_idx))), @@ -137,7 +137,7 @@ def _to_graph( ) if return_as is np.ndarray: return graph.toarray() - return return_as(graph) + return _align_api_if_sparse(return_as(graph)) @validate_params( @@ -149,7 +149,7 @@ def _to_graph( }, prefer_skip_nested_validation=True, ) -def img_to_graph(img, *, mask=None, return_as=sparse.coo_matrix, dtype=None): +def img_to_graph(img, *, mask=None, return_as=sparse.coo_array, dtype=None): """Graph of the pixel-to-pixel gradient connections. Edges are weighted with the gradient values. @@ -165,7 +165,7 @@ def img_to_graph(img, *, mask=None, return_as=sparse.coo_matrix, dtype=None): An optional mask of the image, to consider only part of the pixels. return_as : np.ndarray or a sparse matrix class, \ - default=sparse.coo_matrix + default=sparse.coo_array The class to use to build the returned adjacency matrix. dtype : dtype, default=None The data of the returned sparse matrix. By default it is the @@ -203,9 +203,7 @@ def img_to_graph(img, *, mask=None, return_as=sparse.coo_matrix, dtype=None): }, prefer_skip_nested_validation=True, ) -def grid_to_graph( - n_x, n_y, n_z=1, *, mask=None, return_as=sparse.coo_matrix, dtype=int -): +def grid_to_graph(n_x, n_y, n_z=1, *, mask=None, return_as=sparse.coo_array, dtype=int): """Graph of the pixel-to-pixel connections. Edges exist if 2 voxels are connected. @@ -224,7 +222,7 @@ def grid_to_graph( An optional mask of the image, to consider only part of the pixels. return_as : np.ndarray or a sparse matrix class, \ - default=sparse.coo_matrix + default=sparse.coo_array The class to use to build the returned adjacency matrix. dtype : dtype, default=int The data of the returned sparse matrix. By default it is int. diff --git a/sklearn/feature_extraction/tests/test_feature_hasher.py b/sklearn/feature_extraction/tests/test_feature_hasher.py index d19abcc772ae6..ff09db8615a29 100644 --- a/sklearn/feature_extraction/tests/test_feature_hasher.py +++ b/sklearn/feature_extraction/tests/test_feature_hasher.py @@ -4,6 +4,7 @@ from sklearn.feature_extraction import FeatureHasher from sklearn.feature_extraction._hashing_fast import transform as _hashing_transform +from sklearn.utils.fixes import SCIPY_VERSION_BELOW_1_12 def test_feature_hasher_dicts(): @@ -37,8 +38,12 @@ def test_feature_hasher_strings(): assert X.shape[0] == len(raw_X) assert X.shape[1] == n_features - assert X[0].sum() == 4 - assert X[1].sum() == 3 + if SCIPY_VERSION_BELOW_1_12: + assert X[[0], :].sum() == 4 + assert X[[1], :].sum() == 3 + else: + assert X[0].sum() == 4 + assert X[1].sum() == 3 assert X.nnz == 6 diff --git a/sklearn/feature_extraction/tests/test_text.py b/sklearn/feature_extraction/tests/test_text.py index f584049282ac7..1749d1a183012 100644 --- a/sklearn/feature_extraction/tests/test_text.py +++ b/sklearn/feature_extraction/tests/test_text.py @@ -27,6 +27,7 @@ from sklearn.model_selection import GridSearchCV, cross_val_score, train_test_split from sklearn.pipeline import Pipeline from sklearn.svm import LinearSVC +from sklearn.utils import _align_api_if_sparse from sklearn.utils._testing import ( assert_allclose_dense_sparse, assert_almost_equal, @@ -657,9 +658,9 @@ def test_hashing_vectorizer(): assert np.max(X.data) > 0 assert np.max(X.data) < 1 - # Check that the rows are normalized - for i in range(X.shape[0]): - assert_almost_equal(np.linalg.norm(X[0].data, 2), 1.0) + # Check that the rows are normalized (l2 norm) + for row in X: + assert_almost_equal(np.linalg.norm(row.data, 2), 1.0) # Check vectorization with some non-default parameters v = HashingVectorizer(ngram_range=(1, 2), norm="l1") @@ -676,9 +677,9 @@ def test_hashing_vectorizer(): assert np.min(X.data) > -1 assert np.max(X.data) < 1 - # Check that the rows are normalized - for i in range(X.shape[0]): - assert_almost_equal(np.linalg.norm(X[0].data, 1), 1.0) + # Check that the rows are normalized (l1 norm) + for row in X: + assert_almost_equal(np.linalg.norm(row.data, 1), 1.0) def test_feature_names(): @@ -1612,7 +1613,16 @@ def test_tfidf_transformer_copy(csr_container): assert X_transform is not X_csr X_transform = transformer.transform(X_csr, copy=False) - assert X_transform is X_csr + # allow for config["sparse_interface"] to change output type + # there should be no data copied, but the `id` will change. + if _align_api_if_sparse(X_csr) is X_csr: + assert X_transform is X_csr + else: + assert X_transform is not X_csr + assert X_transform.indptr is X_csr.indptr + assert X_transform.indices.base is X_csr.indices.base + assert X_transform.data.base is X_csr.data.base + with pytest.raises(AssertionError): assert_allclose_dense_sparse(X_csr, X_csr_original) diff --git a/sklearn/feature_extraction/text.py b/sklearn/feature_extraction/text.py index b6da01063db1c..0c1d18b83dddd 100644 --- a/sklearn/feature_extraction/text.py +++ b/sklearn/feature_extraction/text.py @@ -28,7 +28,8 @@ from sklearn.preprocessing import normalize from sklearn.utils import metadata_routing from sklearn.utils._param_validation import HasMethods, Interval, RealNotInt, StrOptions -from sklearn.utils.fixes import _IS_32BIT +from sklearn.utils._sparse import _align_api_if_sparse +from sklearn.utils.fixes import _IS_32BIT, SCIPY_VERSION_BELOW_1_12 from sklearn.utils.validation import ( FLOAT_DTYPES, check_array, @@ -889,7 +890,7 @@ def transform(self, X): X.data.fill(1) if self.norm is not None: X = normalize(X, norm=self.norm, copy=False) - return X + return _align_api_if_sparse(X) def fit_transform(self, X, y=None): """Transform a sequence of documents to a document-term matrix. @@ -939,7 +940,7 @@ class CountVectorizer(_VectorizerMixin, BaseEstimator): r"""Convert a collection of text documents to a matrix of token counts. This implementation produces a sparse representation of the counts using - scipy.sparse.csr_matrix. + scipy.sparse.csr_array. If you do not provide an a-priori dictionary and you do not use an analyzer that does some kind of feature selection then the number of features will @@ -1310,13 +1311,13 @@ def _count_vocab(self, raw_documents, fixed_vocab): indptr = np.asarray(indptr, dtype=indices_dtype) values = np.frombuffer(values, dtype=np.intc) - X = sp.csr_matrix( + X = sp.csr_array( (values, j_indices, indptr), shape=(len(indptr) - 1, len(vocabulary)), dtype=self.dtype, ) X.sort_indices() - return vocabulary, X + return vocabulary, _align_api_if_sparse(X) def fit(self, raw_documents, y=None): """Learn a vocabulary dictionary of all tokens in the raw documents. @@ -1403,7 +1404,7 @@ def fit_transform(self, raw_documents, y=None): X = self._sort_features(X, vocabulary) self.vocabulary_ = vocabulary - return X + return _align_api_if_sparse(X) def transform(self, raw_documents): """Transform documents to document-term matrix. @@ -1431,7 +1432,7 @@ def transform(self, raw_documents): _, X = self._count_vocab(raw_documents, fixed_vocab=True) if self.binary: X.data.fill(1) - return X + return _align_api_if_sparse(X) def inverse_transform(self, X): """Return terms per document with nonzero entries in X. @@ -1456,8 +1457,13 @@ def inverse_transform(self, X): inverse_vocabulary = terms[np.argsort(indices)] if sp.issparse(X): + if SCIPY_VERSION_BELOW_1_12: + return [ + inverse_vocabulary[X[[i], :].nonzero()[-1]].ravel() + for i in range(n_samples) + ] return [ - inverse_vocabulary[X[i, :].nonzero()[1]].ravel() + inverse_vocabulary[X[i, :].nonzero()[-1]].ravel() for i in range(n_samples) ] else: @@ -1665,7 +1671,7 @@ def fit(self, X, y=None): self, X, accept_sparse=("csr", "csc"), accept_large_sparse=not _IS_32BIT ) if not sp.issparse(X): - X = sp.csr_matrix(X) + X = sp.csr_array(X) dtype = X.dtype if X.dtype in (np.float64, np.float32) else np.float64 if self.use_idf: @@ -1716,7 +1722,7 @@ def transform(self, X, copy=True): reset=False, ) if not sp.issparse(X): - X = sp.csr_matrix(X, dtype=X.dtype) + X = sp.csr_array(X, dtype=X.dtype) if self.sublinear_tf: np.log(X.data, X.data) @@ -1730,7 +1736,7 @@ def transform(self, X, copy=True): if self.norm is not None: X = normalize(X, norm=self.norm, copy=False) - return X + return _align_api_if_sparse(X) def __sklearn_tags__(self): tags = super().__sklearn_tags__() diff --git a/sklearn/feature_selection/_base.py b/sklearn/feature_selection/_base.py index 05b52ba5ade1b..462d90aa165c5 100644 --- a/sklearn/feature_selection/_base.py +++ b/sklearn/feature_selection/_base.py @@ -8,12 +8,13 @@ from operator import attrgetter import numpy as np -from scipy.sparse import csc_matrix, issparse +from scipy.sparse import csc_array, issparse from sklearn.base import TransformerMixin from sklearn.utils import _safe_indexing, check_array, safe_sqr from sklearn.utils._dataframe import is_pandas_df from sklearn.utils._set_output import _get_output_config +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils._tags import get_tags from sklearn.utils.validation import ( _check_feature_names_in, @@ -153,12 +154,12 @@ def inverse_transform(self, X): it = self.inverse_transform(np.diff(X.indptr).reshape(1, -1)) col_nonzeros = it.ravel() indptr = np.concatenate([[0], np.cumsum(col_nonzeros)]) - Xt = csc_matrix( + Xt = csc_array( (X.data, X.indices, indptr), shape=(X.shape[0], len(indptr) - 1), dtype=X.dtype, ) - return Xt + return _align_api_if_sparse(Xt) support = self.get_support() X = check_array(X, dtype=None) diff --git a/sklearn/impute/_base.py b/sklearn/impute/_base.py index c1c480de1f387..6d10812abc3fd 100644 --- a/sklearn/impute/_base.py +++ b/sklearn/impute/_base.py @@ -15,7 +15,8 @@ from sklearn.utils._mask import _get_mask from sklearn.utils._missing import is_pandas_na, is_scalar_nan from sklearn.utils._param_validation import MissingValues, StrOptions -from sklearn.utils.fixes import _mode +from sklearn.utils._sparse import _align_api_if_sparse +from sklearn.utils.fixes import SCIPY_VERSION_BELOW_1_12, _mode from sklearn.utils.sparsefuncs import _get_median from sklearn.utils.validation import ( FLOAT_DTYPES, @@ -152,7 +153,7 @@ def _concatenate_indicator(self, X_imputed, X_indicator): "implementation." ) - return hstack((X_imputed, X_indicator)) + return _align_api_if_sparse(hstack((X_imputed, X_indicator))) def _concatenate_indicator_feature_names_out(self, names, input_features): if not self.add_indicator: @@ -483,9 +484,14 @@ def _sparse_fit(self, X, strategy, missing_values, fill_value): statistics.fill(fill_value) if not self.keep_empty_features: - for i in range(missing_mask.shape[1]): - if all(missing_mask[:, i].data): - statistics[i] = np.nan + if SCIPY_VERSION_BELOW_1_12: + for i in range(missing_mask.shape[1]): + if all(missing_mask[:, [i]].data): + statistics[i] = np.nan + else: + for i in range(missing_mask.shape[1]): + if all(missing_mask[:, i].data): + statistics[i] = np.nan else: for i in range(X.shape[1]): @@ -929,7 +935,7 @@ def _get_missing_features_info(self, X): n_missing = imputer_mask.sum(axis=0) if self.sparse is True: - imputer_mask = sp.csc_matrix(imputer_mask) + imputer_mask = _align_api_if_sparse(sp.csc_array(imputer_mask)) if self.features == "all": features_indices = np.arange(X.shape[1]) diff --git a/sklearn/impute/tests/test_impute.py b/sklearn/impute/tests/test_impute.py index 013fd7eb8a810..6605b1cd76cef 100644 --- a/sklearn/impute/tests/test_impute.py +++ b/sklearn/impute/tests/test_impute.py @@ -34,6 +34,7 @@ CSC_CONTAINERS, CSR_CONTAINERS, LIL_CONTAINERS, + SCIPY_VERSION_BELOW_1_12, ) @@ -1789,9 +1790,11 @@ def test_simple_imputer_keep_empty_features(strategy, array_type, keep_empty_fea X_imputed = getattr(imputer, method)(X) if keep_empty_features: assert X_imputed.shape == X.shape - constant_feature = ( - X_imputed[:, 0].toarray() if array_type == "sparse" else X_imputed[:, 0] - ) + if SCIPY_VERSION_BELOW_1_12 and array_type == "sparse": + constant_feature = X_imputed[:, [0]].toarray() + else: + col0 = X_imputed[:, 0] + constant_feature = col0.toarray() if array_type == "sparse" else col0 assert_array_equal(constant_feature, 0) else: assert X_imputed.shape == (X.shape[0], X.shape[1] - 1) diff --git a/sklearn/kernel_approximation.py b/sklearn/kernel_approximation.py index 21672d28ced5c..88d886355e00f 100644 --- a/sklearn/kernel_approximation.py +++ b/sklearn/kernel_approximation.py @@ -22,7 +22,7 @@ _find_floating_dtype_allow_sparse, pairwise_kernels, ) -from sklearn.utils import check_random_state +from sklearn.utils import _align_api_if_sparse, check_random_state from sklearn.utils._array_api import ( _find_matching_floating_dtype, get_namespace_and_device, @@ -811,8 +811,10 @@ def _transform_sparse(X, sample_steps, sample_interval): indptr = X.indptr.copy() data_step = np.sqrt(X.data * sample_interval) - X_step = sp.csr_matrix( - (data_step, indices, indptr), shape=X.shape, dtype=X.dtype, copy=False + X_step = _align_api_if_sparse( + sp.csr_array( + (data_step, indices, indptr), shape=X.shape, dtype=X.dtype, copy=False + ) ) X_new = [X_step] @@ -823,14 +825,24 @@ def _transform_sparse(X, sample_steps, sample_interval): factor_nz = np.sqrt(step_nz / np.cosh(np.pi * j * sample_interval)) data_step = factor_nz * np.cos(j * log_step_nz) - X_step = sp.csr_matrix( - (data_step, indices, indptr), shape=X.shape, dtype=X.dtype, copy=False + X_step = _align_api_if_sparse( + sp.csr_array( + (data_step, indices, indptr), + shape=X.shape, + dtype=X.dtype, + copy=False, + ) ) X_new.append(X_step) data_step = factor_nz * np.sin(j * log_step_nz) - X_step = sp.csr_matrix( - (data_step, indices, indptr), shape=X.shape, dtype=X.dtype, copy=False + X_step = _align_api_if_sparse( + sp.csr_array( + (data_step, indices, indptr), + shape=X.shape, + dtype=X.dtype, + copy=False, + ) ) X_new.append(X_step) diff --git a/sklearn/linear_model/_base.py b/sklearn/linear_model/_base.py index a4878203ce883..7f57bb6293a40 100644 --- a/sklearn/linear_model/_base.py +++ b/sklearn/linear_model/_base.py @@ -21,7 +21,7 @@ RegressorMixin, _fit_context, ) -from sklearn.utils import check_array, check_random_state +from sklearn.utils import _align_api_if_sparse, check_array, check_random_state from sklearn.utils._array_api import ( _asarray_with_order, _average, @@ -250,7 +250,7 @@ def _rescale_data(X, y, sample_weight, inplace=False): sample_weight_sqrt = xp.sqrt(sample_weight) if sp.issparse(X) or sp.issparse(y): - sw_matrix = sparse.dia_matrix( + sw_matrix = sparse.dia_array( (sample_weight_sqrt, 0), shape=(n_samples, n_samples) ) @@ -275,7 +275,7 @@ def _rescale_data(X, y, sample_weight, inplace=False): y = y * sample_weight_sqrt else: y = y * sample_weight_sqrt[:, None] - return X, y, sample_weight_sqrt + return _align_api_if_sparse(X), _align_api_if_sparse(y), sample_weight_sqrt class LinearModel(BaseEstimator, metaclass=ABCMeta): @@ -479,7 +479,7 @@ def sparsify(self): """ msg = "Estimator, %(name)s, must be fitted before sparsifying." check_is_fitted(self, msg=msg) - self.coef_ = sp.csr_matrix(self.coef_) + self.coef_ = _align_api_if_sparse(sp.csr_array(self.coef_)) return self diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index 5c49722ee2638..992510b24d938 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -31,6 +31,7 @@ StrOptions, validate_params, ) +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils.extmath import safe_sparse_dot from sklearn.utils.metadata_routing import _routing_enabled, process_routing from sklearn.utils.parallel import Parallel, delayed @@ -1183,7 +1184,7 @@ def fit(self, X, y, sample_weight=None, check_input=True): @property def sparse_coef_(self): """Sparse representation of the fitted `coef_`.""" - return sparse.csr_matrix(self.coef_) + return _align_api_if_sparse(sparse.csr_array(np.atleast_2d(self.coef_))) def _decision_function(self, X): """Decision function of the linear model. diff --git a/sklearn/linear_model/_linear_loss.py b/sklearn/linear_model/_linear_loss.py index a53c8b89ec58b..96d7f8d92286e 100644 --- a/sklearn/linear_model/_linear_loss.py +++ b/sklearn/linear_model/_linear_loss.py @@ -13,6 +13,7 @@ get_namespace, get_namespace_and_device, ) +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils.extmath import safe_sparse_dot, squared_norm @@ -29,10 +30,12 @@ def sandwich_dot(X, W): # which (might) detect the symmetry and use BLAS SYRK under the hood. n_samples = X.shape[0] if sparse.issparse(X): - return safe_sparse_dot( - X.T, - sparse.dia_matrix((W, 0), shape=(n_samples, n_samples)) @ X, - dense_output=True, + return _align_api_if_sparse( + safe_sparse_dot( + X.T, + sparse.dia_array((W, 0), shape=(n_samples, n_samples)) @ X, + dense_output=True, + ) ) else: # np.einsum may use less memory but the following, using BLAS matrix @@ -758,7 +761,7 @@ def gradient_hessian_product( hessian_sum = hess_pointwise.sum() if sparse.issparse(X): hX = ( - sparse.dia_matrix((hess_pointwise, 0), shape=(n_samples, n_samples)) + sparse.dia_array((hess_pointwise, 0), shape=(n_samples, n_samples)) @ X ) else: diff --git a/sklearn/linear_model/_quantile.py b/sklearn/linear_model/_quantile.py index aba8c3e642ac1..6272dc275ad07 100644 --- a/sklearn/linear_model/_quantile.py +++ b/sklearn/linear_model/_quantile.py @@ -13,7 +13,7 @@ from sklearn.linear_model._base import LinearModel from sklearn.utils import _safe_indexing from sklearn.utils._param_validation import Interval, StrOptions -from sklearn.utils.fixes import parse_version, sp_version +from sklearn.utils.fixes import _sparse_eye_array, parse_version, sp_version from sklearn.utils.validation import _check_sample_weight, validate_data @@ -240,9 +240,9 @@ def fit(self, X, y, sample_weight=None): # even for optimization problems parametrized using dense numpy arrays. # Therefore, we work with CSC matrices as early as possible to limit # unnecessary repeated memory copies. - eye = sparse.eye(n_indices, dtype=X.dtype, format="csc") + eye = _sparse_eye_array(n_indices, dtype=X.dtype, format="csc") if self.fit_intercept: - ones = sparse.csc_matrix(np.ones(shape=(n_indices, 1), dtype=X.dtype)) + ones = sparse.csc_array(np.ones(shape=(n_indices, 1), dtype=X.dtype)) A_eq = sparse.hstack([ones, X, -ones, -X, eye, -eye], format="csc") else: A_eq = sparse.hstack([X, -X, eye, -eye], format="csc") diff --git a/sklearn/linear_model/tests/test_base.py b/sklearn/linear_model/tests/test_base.py index 8d02124975783..2e1d7270abd13 100644 --- a/sklearn/linear_model/tests/test_base.py +++ b/sklearn/linear_model/tests/test_base.py @@ -27,6 +27,7 @@ CSC_CONTAINERS, CSR_CONTAINERS, LIL_CONTAINERS, + _sparse_eye_array, ) rtol = 1e-6 @@ -100,7 +101,7 @@ def test_linear_regression_sample_weights( def test_raises_value_error_if_positive_and_sparse(): error_msg = "Sparse data was passed for X, but dense data is required." # X must not be sparse if positive == True - X = sparse.eye(10) + X = _sparse_eye_array(10) y = np.ones(10) reg = LinearRegression(positive=True) @@ -150,7 +151,7 @@ def test_linear_regression_sparse(global_random_seed): # Test that linear regression also works with sparse data rng = np.random.RandomState(global_random_seed) n = 100 - X = sparse.eye(n, n) + X = _sparse_eye_array(n, n) beta = rng.rand(n) y = X @ beta diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index 34fcb0c687f86..fbb9d5db1d492 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -87,7 +87,8 @@ def test_set_order_sparse(order, input_order, coo_container): assert sparse.issparse(y2) and y2.format == format -def test_cython_solver_equivalence(): +@pytest.mark.parametrize("sparse_csc_type", [sparse.csc_array, sparse.csc_matrix]) +def test_cython_solver_equivalence(sparse_csc_type): """Test that all 3 Cython solvers for 1-d targets give same results.""" X, y = make_regression() X_mean = X.mean(axis=0) @@ -137,7 +138,7 @@ def zc(): assert_allclose(coef_2, coef_1) # Sparse - Xs = sparse.csc_matrix(X) + Xs = sparse_csc_type(X) for do_screening in [True, False]: coef_3 = zc() cd_fast.sparse_enet_coordinate_descent( @@ -837,11 +838,12 @@ def test_elasticnet_precompute_gram(): assert_allclose(clf1.coef_, clf2.coef_) +@pytest.mark.parametrize("sparse_csr_type", [sparse.csr_array, sparse.csr_matrix]) @pytest.mark.parametrize("sparse_X", [True, False]) -def test_warm_start_convergence(sparse_X): +def test_warm_start_convergence(sparse_X, sparse_csr_type): X, y, _, _ = build_dataset() if sparse_X: - X = sparse.csr_matrix(X) + X = sparse_csr_type(X) model = ElasticNet(alpha=1e-3, tol=1e-3).fit(X, y) n_iter_reference = model.n_iter_ @@ -1490,7 +1492,7 @@ def test_enet_cv_sample_weight_consistency( assert_allclose(reg.intercept_, intercept) -@pytest.mark.parametrize("X_is_sparse", [False, True]) +@pytest.mark.parametrize("X_is_sparse", [False, sparse.csc_array, sparse.csc_matrix]) @pytest.mark.parametrize("fit_intercept", [False, True]) @pytest.mark.parametrize("positive", [False, True]) @pytest.mark.parametrize("sample_weight", [np.array([1, 10, 1, 10]), None]) @@ -1501,7 +1503,7 @@ def test_enet_alpha_max(X_is_sparse, fit_intercept, positive, sample_weight): params = dict(fit_intercept=fit_intercept, positive=positive) if X_is_sparse: - X = sparse.csc_matrix(X) + X = X_is_sparse(X) # Test alpha_max makes coefs zero. reg = ElasticNetCV(alphas=1, cv=2, eps=1, **params) reg.fit(X, y, sample_weight=sample_weight) diff --git a/sklearn/linear_model/tests/test_sgd.py b/sklearn/linear_model/tests/test_sgd.py index 23cb2441143f7..4dc0aaf3e4f1f 100644 --- a/sklearn/linear_model/tests/test_sgd.py +++ b/sklearn/linear_model/tests/test_sgd.py @@ -24,12 +24,14 @@ from sklearn.preprocessing import LabelEncoder, MinMaxScaler, StandardScaler, scale from sklearn.svm import OneClassSVM from sklearn.utils import get_tags +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils._testing import ( assert_allclose, assert_almost_equal, assert_array_almost_equal, assert_array_equal, ) +from sklearn.utils.fixes import _sparse_random_array def _update_kwargs(kwargs): @@ -44,48 +46,49 @@ def _update_kwargs(kwargs): class _SparseSGDClassifier(linear_model.SGDClassifier): def fit(self, X, y, *args, **kw): - X = sp.csr_matrix(X) + X = _align_api_if_sparse(sp.csr_array(X)) return super().fit(X, y, *args, **kw) def partial_fit(self, X, y, *args, **kw): - X = sp.csr_matrix(X) + X = _align_api_if_sparse(sp.csr_array(X)) return super().partial_fit(X, y, *args, **kw) def decision_function(self, X): - X = sp.csr_matrix(X) + X = _align_api_if_sparse(sp.csr_array(X)) return super().decision_function(X) def predict_proba(self, X): - X = sp.csr_matrix(X) + X = _align_api_if_sparse(sp.csr_array(X)) return super().predict_proba(X) class _SparseSGDRegressor(linear_model.SGDRegressor): def fit(self, X, y, *args, **kw): - X = sp.csr_matrix(X) + X = _align_api_if_sparse(sp.csr_array(X)) return linear_model.SGDRegressor.fit(self, X, y, *args, **kw) def partial_fit(self, X, y, *args, **kw): - X = sp.csr_matrix(X) + X = _align_api_if_sparse(sp.csr_array(X)) return linear_model.SGDRegressor.partial_fit(self, X, y, *args, **kw) def decision_function(self, X, *args, **kw): # XXX untested as of v0.22 - X = sp.csr_matrix(X) - return linear_model.SGDRegressor.decision_function(self, X, *args, **kw) + return linear_model.SGDRegressor.decision_function( + self, _align_api_if_sparse(X), *args, **kw + ) class _SparseSGDOneClassSVM(linear_model.SGDOneClassSVM): def fit(self, X, *args, **kw): - X = sp.csr_matrix(X) + X = _align_api_if_sparse(sp.csr_array(X)) return linear_model.SGDOneClassSVM.fit(self, X, *args, **kw) def partial_fit(self, X, *args, **kw): - X = sp.csr_matrix(X) + X = _align_api_if_sparse(sp.csr_array(X)) return linear_model.SGDOneClassSVM.partial_fit(self, X, *args, **kw) def decision_function(self, X, *args, **kw): - X = sp.csr_matrix(X) + X = _align_api_if_sparse(sp.csr_array(X)) return linear_model.SGDOneClassSVM.decision_function(self, X, *args, **kw) @@ -881,6 +884,7 @@ def test_sgd_proba(klass): assert_array_almost_equal(p[0], [1 / 3.0] * 3) +@pytest.mark.no_check_spmatrix # pickle breaks check_spmatrix @pytest.mark.parametrize("klass", [SGDClassifier, SparseSGDClassifier]) def test_sgd_l1(klass): # Test L1 regularization @@ -2129,7 +2133,7 @@ def test_SGDClassifier_fit_for_all_backends(backend): # Create a classification problem with 50000 features and 20 classes. Using # loky or multiprocessing this make the clf.coef_ exceed the threshold # above which memmaping is used in joblib and loky (1MB as of 2018/11/1). - X = sp.random(500, 2000, density=0.02, format="csr", random_state=random_state) + X = _sparse_random_array((500, 2000), density=0.02, format="csr", rng=random_state) y = random_state.choice(20, 500) # Begin by fitting a SGD classifier sequentially diff --git a/sklearn/linear_model/tests/test_sparse_coordinate_descent.py b/sklearn/linear_model/tests/test_sparse_coordinate_descent.py index 6e928f2fedad2..0e34e8b2db4c3 100644 --- a/sklearn/linear_model/tests/test_sparse_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_sparse_coordinate_descent.py @@ -12,7 +12,12 @@ create_memmap_backed_data, ignore_warnings, ) -from sklearn.utils.fixes import COO_CONTAINERS, CSC_CONTAINERS, LIL_CONTAINERS +from sklearn.utils.fixes import ( + COO_CONTAINERS, + CSC_CONTAINERS, + LIL_CONTAINERS, + _sparse_random_array, +) def test_sparse_coef(): @@ -390,7 +395,7 @@ def test_sparse_read_only_buffer(copy_X): rng = np.random.RandomState(0) clf = ElasticNet(alpha=0.1, copy_X=copy_X, random_state=rng) - X = sp.random(100, 20, format="csc", random_state=rng) + X = _sparse_random_array((100, 20), format="csc", rng=rng) # Make X.data read-only X.data = create_memmap_backed_data(X.data) diff --git a/sklearn/manifold/_isomap.py b/sklearn/manifold/_isomap.py index 07ef626ab8101..727a163fb6292 100644 --- a/sklearn/manifold/_isomap.py +++ b/sklearn/manifold/_isomap.py @@ -21,6 +21,7 @@ from sklearn.neighbors import NearestNeighbors, kneighbors_graph, radius_neighbors_graph from sklearn.preprocessing import KernelCenterer from sklearn.utils._param_validation import Interval, StrOptions +from sklearn.utils.fixes import _ensure_sparse_index_int32 from sklearn.utils.graph import _fix_connected_components from sklearn.utils.validation import check_is_fitted @@ -297,6 +298,7 @@ def _fit_transform(self, X): **self.nbrs_.effective_metric_params_, ) + _ensure_sparse_index_int32(nbg) self.dist_matrix_ = shortest_path(nbg, method=self.path_method, directed=False) if self.nbrs_._fit_X.dtype == np.float32: diff --git a/sklearn/manifold/_locally_linear.py b/sklearn/manifold/_locally_linear.py index 02b5257f0244a..d7b33fcff8fa5 100644 --- a/sklearn/manifold/_locally_linear.py +++ b/sklearn/manifold/_locally_linear.py @@ -7,7 +7,7 @@ import numpy as np from scipy.linalg import eigh, qr, solve, svd -from scipy.sparse import csr_matrix, eye, lil_matrix +from scipy.sparse import csr_array, lil_array from scipy.sparse.linalg import eigsh from sklearn.base import ( @@ -21,6 +21,8 @@ from sklearn.utils import check_array, check_random_state from sklearn.utils._arpack import _init_arpack_v0 from sklearn.utils._param_validation import Interval, StrOptions, validate_params +from sklearn.utils._sparse import _align_api_if_sparse +from sklearn.utils.fixes import SCIPY_VERSION_BELOW_1_15, _sparse_eye_array from sklearn.utils.validation import FLOAT_DTYPES, check_is_fitted, validate_data @@ -117,7 +119,8 @@ def barycenter_kneighbors_graph(X, n_neighbors, reg=1e-3, n_jobs=None): ind = knn.kneighbors(X, return_distance=False)[:, 1:] data = barycenter_weights(X, X, ind, reg=reg) indptr = np.arange(0, n_samples * n_neighbors + 1, n_neighbors) - return csr_matrix((data.ravel(), ind.ravel(), indptr), shape=(n_samples, n_samples)) + csr = csr_array((data.ravel(), ind.ravel(), indptr), shape=(n_samples, n_samples)) + return _align_api_if_sparse(csr) def null_space( @@ -228,7 +231,7 @@ def _locally_linear_embedding( ) M_sparse = eigen_solver != "dense" - M_container_constructor = lil_matrix if M_sparse else np.zeros + M_container_constructor = lil_array if M_sparse else np.zeros if method == "standard": W = barycenter_kneighbors_graph( @@ -238,8 +241,8 @@ def _locally_linear_embedding( # we'll compute M = (I-W)'(I-W) # depending on the solver, we'll do this differently if M_sparse: - M = eye(*W.shape, format=W.format) - W - M = M.T @ M + M = _sparse_eye_array(*W.shape, format=W.format, dtype=W.dtype) - W + M = M.T @ M # M = (I - W)' (I - W) = W' W - W' - W + I else: M = (W.T @ W - W.T - W).toarray() M.flat[:: M.shape[0] + 1] += 1 # M = W' W - W' - W + I @@ -394,8 +397,12 @@ def _locally_linear_embedding( nbrs_x, nbrs_y = np.meshgrid(neighbors[i], neighbors[i]) M[nbrs_x, nbrs_y] += np.dot(Wi, Wi.T) Wi_sum1 = Wi.sum(1) - M[i, neighbors[i]] -= Wi_sum1 - M[neighbors[i], [i]] -= Wi_sum1 + if SCIPY_VERSION_BELOW_1_15: + M[[i], neighbors[i]] -= Wi_sum1 + M[neighbors[i], [i]] -= Wi_sum1 + else: + M[i, neighbors[i]] -= Wi_sum1 + M[neighbors[i], i] -= Wi_sum1 M[i, i] += s_i elif method == "ltsa": @@ -431,7 +438,7 @@ def _locally_linear_embedding( M[neighbors[i], neighbors[i]] += np.ones(shape=n_neighbors) if M_sparse: - M = M.tocsr() + M = _align_api_if_sparse(M.tocsr()) return null_space( M, diff --git a/sklearn/manifold/_spectral_embedding.py b/sklearn/manifold/_spectral_embedding.py index 39310232269e8..e4faf7213ec2f 100644 --- a/sklearn/manifold/_spectral_embedding.py +++ b/sklearn/manifold/_spectral_embedding.py @@ -19,8 +19,8 @@ from sklearn.utils._arpack import _init_arpack_v0 from sklearn.utils._param_validation import Interval, StrOptions, validate_params from sklearn.utils.extmath import _deterministic_vector_sign_flip +from sklearn.utils.fixes import _sparse_eye_array, parse_version, sp_version from sklearn.utils.fixes import laplacian as csgraph_laplacian -from sklearn.utils.fixes import parse_version, sp_version from sklearn.utils.validation import validate_data @@ -306,11 +306,12 @@ def _spectral_embedding( if eigen_solver == "amg": try: - from pyamg import smoothed_aggregation_solver + from pyamg import aggregation, smoothed_aggregation_solver except ImportError as e: raise ValueError( "The eigen_solver was set to 'amg', but pyamg is not available." ) from e + pyamg_supports_sparray = hasattr(aggregation.aggregation, "csr_array") if eigen_solver is None: eigen_solver = "arpack" @@ -396,12 +397,16 @@ def _spectral_embedding( # Shift the Laplacian so its diagononal is not all ones. The shift # does change the eigenpairs however, so we'll feed the shifted # matrix to the solver and afterward set it back to the original. - diag_shift = 1e-5 * sparse.eye(laplacian.shape[0]) + diag_shift = 1e-5 * _sparse_eye_array(laplacian.shape[0]) laplacian += diag_shift if hasattr(sparse, "csr_array") and isinstance(laplacian, sparse.csr_array): - # `pyamg` does not work with `csr_array` and we need to convert it to a - # `csr_matrix` object. - laplacian = sparse.csr_matrix(laplacian) + # old version `pyamg` may not work with `csr_array` and new version + # may not work with `csr_matrix`. But we need to convert to CSR. + if pyamg_supports_sparray: + laplacian = sparse.csr_array(laplacian) + else: + laplacian = sparse.csr_matrix(laplacian) + ml = smoothed_aggregation_solver(check_array(laplacian, accept_sparse="csr")) laplacian -= diag_shift diff --git a/sklearn/manifold/_t_sne.py b/sklearn/manifold/_t_sne.py index 2527fbc0959fb..ccab7aad234f6 100644 --- a/sklearn/manifold/_t_sne.py +++ b/sklearn/manifold/_t_sne.py @@ -11,7 +11,7 @@ import numpy as np from scipy import linalg -from scipy.sparse import csr_matrix, issparse +from scipy.sparse import csr_array, issparse from scipy.spatial.distance import pdist, squareform from sklearn.base import ( @@ -27,7 +27,7 @@ from sklearn.manifold import _barnes_hut_tsne, _utils # type: ignore[attr-defined] from sklearn.metrics.pairwise import _VALID_METRICS, pairwise_distances from sklearn.neighbors import NearestNeighbors -from sklearn.utils import check_random_state +from sklearn.utils import _align_api_if_sparse, check_random_state from sklearn.utils._openmp_helpers import _openmp_effective_n_threads from sklearn.utils._param_validation import Interval, StrOptions, validate_params from sklearn.utils.validation import _num_samples, check_non_negative, validate_data @@ -108,7 +108,7 @@ def _joint_probabilities_nn(distances, desired_perplexity, verbose): assert np.all(np.isfinite(conditional_P)), "All probabilities should be finite" # Symmetrize the joint probability distribution using sparse operations - P = csr_matrix( + P = csr_array( (conditional_P.ravel(), distances.indices, distances.indptr), shape=(n_samples, n_samples), ) @@ -122,7 +122,7 @@ def _joint_probabilities_nn(distances, desired_perplexity, verbose): if verbose >= 2: duration = time() - t0 print("[t-SNE] Computed conditional probabilities in {:.3f}s".format(duration)) - return P + return _align_api_if_sparse(P) def _kl_divergence( diff --git a/sklearn/manifold/tests/test_spectral_embedding.py b/sklearn/manifold/tests/test_spectral_embedding.py index 4c4115734a404..612f5829a9d72 100644 --- a/sklearn/manifold/tests/test_spectral_embedding.py +++ b/sklearn/manifold/tests/test_spectral_embedding.py @@ -23,6 +23,8 @@ COO_CONTAINERS, CSC_CONTAINERS, CSR_CONTAINERS, + _sparse_diags_array, + _sparse_random_array, parse_version, sp_version, ) @@ -311,9 +313,9 @@ def test_spectral_embedding_amg_solver(dtype, coo_container, seed=36): def test_spectral_embedding_amg_solver_failure(dtype, seed=36): # Non-regression test for amg solver failure (issue #13393 on github) num_nodes = 100 - X = sparse.rand(num_nodes, num_nodes, density=0.1, random_state=seed) + X = _sparse_random_array((num_nodes, num_nodes), density=0.1, random_state=seed) X = X.astype(dtype) - upper = sparse.triu(X) - sparse.diags(X.diagonal()) + upper = sparse.triu(X) - _sparse_diags_array(X.diagonal()) sym_matrix = upper + upper.T embedding = spectral_embedding( sym_matrix, n_components=10, eigen_solver="amg", random_state=0 diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index a4ff45ae3e2e1..8a0ad68343574 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -16,11 +16,12 @@ from numbers import Integral, Real import numpy as np -from scipy.sparse import coo_matrix, csr_matrix, issparse +from scipy.sparse import coo_array, csr_array, issparse from sklearn.exceptions import UndefinedMetricWarning from sklearn.preprocessing import LabelBinarizer, LabelEncoder from sklearn.utils import ( + _align_api_if_sparse, assert_all_finite, check_array, check_consistent_length, @@ -173,8 +174,8 @@ def _check_targets(y_true, y_pred, sample_weight=None): # they are passed as a dense arrays? This is not possible for array # API inputs in general hence we only do it for NumPy inputs. But even # for NumPy the usefulness is questionable. - y_true = csr_matrix(y_true) - y_pred = csr_matrix(y_pred) + y_true = _align_api_if_sparse(csr_array(y_true)) + y_pred = _align_api_if_sparse(csr_array(y_pred)) y_type = "multilabel-indicator" return y_type, y_true, y_pred, sample_weight @@ -600,7 +601,7 @@ def confusion_matrix( else: dtype = np.float32 if str(device_).startswith("mps") else np.float64 - cm = coo_matrix( + cm = coo_array( (sample_weight, (y_true, y_pred)), shape=(n_labels, n_labels), dtype=dtype, diff --git a/sklearn/metrics/_pairwise_distances_reduction/_datasets_pair.pyx.tp b/sklearn/metrics/_pairwise_distances_reduction/_datasets_pair.pyx.tp index f5615b49fb01a..93c772cfce5ca 100644 --- a/sklearn/metrics/_pairwise_distances_reduction/_datasets_pair.pyx.tp +++ b/sklearn/metrics/_pairwise_distances_reduction/_datasets_pair.pyx.tp @@ -17,7 +17,7 @@ from cython cimport final from sklearn.utils._typedefs cimport float64_t, float32_t, intp_t -from scipy.sparse import issparse, csr_matrix +from scipy.sparse import issparse, csr_matrix, csr_array {{for name_suffix, DistanceMetric, INPUT_DTYPE_t, INPUT_DTYPE in implementation_specific_values}} @@ -124,8 +124,8 @@ cdef class DatasetsPair{{name_suffix}}: return DenseSparseDatasetsPair{{name_suffix}}(X, Y, distance_metric) @classmethod - def unpack_csr_matrix(cls, X: csr_matrix): - """Ensure that the CSR matrix is indexed with np.int32.""" + def unpack_csr(cls, X: csr_matrix | csr_array): + """Ensure that the CSR sparse is indexed with np.int32.""" X_data = np.asarray(X.data, dtype={{INPUT_DTYPE}}) X_indices = np.asarray(X.indices, dtype=np.int32) X_indptr = np.asarray(X.indptr, dtype=np.int32) @@ -223,8 +223,8 @@ cdef class SparseSparseDatasetsPair{{name_suffix}}(DatasetsPair{{name_suffix}}): def __init__(self, X, Y, {{DistanceMetric}} distance_metric): super().__init__(distance_metric, n_features=X.shape[1]) - self.X_data, self.X_indices, self.X_indptr = self.unpack_csr_matrix(X) - self.Y_data, self.Y_indices, self.Y_indptr = self.unpack_csr_matrix(Y) + self.X_data, self.X_indices, self.X_indptr = self.unpack_csr(X) + self.Y_data, self.Y_indices, self.Y_indptr = self.unpack_csr(Y) @final cdef intp_t n_samples_X(self) noexcept nogil: @@ -269,7 +269,7 @@ cdef class SparseDenseDatasetsPair{{name_suffix}}(DatasetsPair{{name_suffix}}): Parameters ---------- - X: sparse matrix of shape (n_samples_X, n_features) + X: sparse matrix/array of shape (n_samples_X, n_features) Rows represent vectors. Must be in CSR format. Y: ndarray of shape (n_samples_Y, n_features) @@ -283,7 +283,7 @@ cdef class SparseDenseDatasetsPair{{name_suffix}}(DatasetsPair{{name_suffix}}): def __init__(self, X, Y, {{DistanceMetric}} distance_metric): super().__init__(distance_metric, n_features=X.shape[1]) - self.X_data, self.X_indices, self.X_indptr = self.unpack_csr_matrix(X) + self.X_data, self.X_indices, self.X_indptr = self.unpack_csr(X) # We support the sparse-dense case by using the sparse-sparse interfaces # of `DistanceMetric` (namely `DistanceMetric.{dist_csr,rdist_csr}`) to diff --git a/sklearn/metrics/_pairwise_distances_reduction/_middle_term_computer.pyx.tp b/sklearn/metrics/_pairwise_distances_reduction/_middle_term_computer.pyx.tp index 48216f27f4261..ea62db24c788c 100644 --- a/sklearn/metrics/_pairwise_distances_reduction/_middle_term_computer.pyx.tp +++ b/sklearn/metrics/_pairwise_distances_reduction/_middle_term_computer.pyx.tp @@ -27,7 +27,7 @@ from sklearn.utils._cython_blas cimport ( from sklearn.utils._typedefs cimport float64_t, float32_t, int32_t, intp_t import numpy as np -from scipy.sparse import issparse, csr_matrix +from scipy.sparse import issparse, csr_matrix, csr_array cdef void _middle_term_sparse_sparse_64( @@ -197,7 +197,7 @@ cdef class MiddleTermComputer{{name_suffix}}: ) @classmethod - def unpack_csr_matrix(cls, X: csr_matrix): + def unpack_csr(cls, X: csr_matrix | csr_array): """Ensure that the CSR matrix is indexed with np.int32.""" X_data = np.asarray(X.data, dtype=np.float64) X_indices = np.asarray(X.indices, dtype=np.int32) @@ -471,8 +471,8 @@ cdef class SparseSparseMiddleTermComputer{{name_suffix}}(MiddleTermComputer{{nam n_features, chunk_size, ) - self.X_data, self.X_indices, self.X_indptr = self.unpack_csr_matrix(X) - self.Y_data, self.Y_indices, self.Y_indptr = self.unpack_csr_matrix(Y) + self.X_data, self.X_indices, self.X_indptr = self.unpack_csr(X) + self.Y_data, self.Y_indices, self.Y_indptr = self.unpack_csr(Y) cdef void _parallel_on_X_pre_compute_and_reduce_distances_on_chunks( self, @@ -559,7 +559,7 @@ cdef class SparseDenseMiddleTermComputer{{name_suffix}}(MiddleTermComputer{{name n_features, chunk_size, ) - self.X_data, self.X_indices, self.X_indptr = self.unpack_csr_matrix(X) + self.X_data, self.X_indices, self.X_indptr = self.unpack_csr(X) self.Y = Y self.c_ordered_middle_term = c_ordered_middle_term diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index a1d0a69acb60c..3149d6d3d5308 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -16,7 +16,7 @@ import numpy as np from scipy.integrate import trapezoid -from scipy.sparse import csr_matrix, issparse +from scipy.sparse import csr_array, issparse from scipy.stats import rankdata from sklearn.exceptions import UndefinedMetricWarning @@ -1441,7 +1441,7 @@ def label_ranking_average_precision_score(y_true, y_score, *, sample_weight=None raise ValueError("{0} format is not supported".format(y_type)) if not issparse(y_true): - y_true = csr_matrix(y_true) + y_true = csr_array(y_true) y_score = -y_score @@ -1623,7 +1623,7 @@ def label_ranking_loss(y_true, y_score, *, sample_weight=None): n_samples, n_labels = y_true.shape - y_true = csr_matrix(y_true) + y_true = csr_array(y_true) loss = np.zeros(n_samples) for i, (start, stop) in enumerate(zip(y_true.indptr, y_true.indptr[1:])): diff --git a/sklearn/metrics/cluster/_supervised.py b/sklearn/metrics/cluster/_supervised.py index 409cd74e4e007..03ce5e72aa8c3 100644 --- a/sklearn/metrics/cluster/_supervised.py +++ b/sklearn/metrics/cluster/_supervised.py @@ -17,7 +17,7 @@ from sklearn.metrics.cluster._expected_mutual_info_fast import ( expected_mutual_information, ) -from sklearn.utils import deprecated +from sklearn.utils import _align_api_if_sparse, deprecated from sklearn.utils._array_api import ( _max_precision_float_dtype, get_namespace_and_device, @@ -139,11 +139,11 @@ def contingency_matrix( ------- contingency : {array-like, sparse}, shape=[n_classes_true, n_classes_pred] Matrix :math:`C` such that :math:`C_{i, j}` is the number of samples in - true class :math:`i` and in predicted class :math:`j`. If - ``eps is None``, the dtype of this array will be integer unless set + true class :math:`i` and in predicted class :math:`j`. + If ``eps is None``, the dtype of this array will be integer unless set otherwise with the ``dtype`` argument. If ``eps`` is given, the dtype will be float. - Will be a ``sklearn.sparse.csr_matrix`` if ``sparse=True``. + If ``sparse=True`` will be a sparse CSR contingency. Examples -------- @@ -166,12 +166,13 @@ def contingency_matrix( # Using coo_matrix to accelerate simple histogram calculation, # i.e. bins are consecutive integers # Currently, coo_matrix is faster than histogram2d for simple cases - contingency = sp.coo_matrix( + contingency = sp.coo_array( (np.ones(class_idx.shape[0]), (class_idx, cluster_idx)), shape=(n_classes, n_clusters), dtype=dtype, ) if sparse: + contingency = _align_api_if_sparse(contingency) contingency = contingency.tocsr() contingency.sum_duplicates() else: diff --git a/sklearn/metrics/pairwise.py b/sklearn/metrics/pairwise.py index bdc338d3d0948..e4d98a9f8616a 100644 --- a/sklearn/metrics/pairwise.py +++ b/sklearn/metrics/pairwise.py @@ -11,7 +11,7 @@ import numpy as np from joblib import effective_n_jobs -from scipy.sparse import csr_matrix, issparse +from scipy.sparse import csr_array, issparse from scipy.spatial import distance from sklearn import config_context @@ -40,6 +40,7 @@ StrOptions, validate_params, ) +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils.extmath import row_norms, safe_sparse_dot from sklearn.utils.fixes import parse_version, sp_base_version from sklearn.utils.parallel import Parallel, delayed @@ -1094,8 +1095,8 @@ def manhattan_distances(X, Y=None): n_x, n_y = X.shape[0], Y.shape[0] if issparse(X) or issparse(Y): - X = csr_matrix(X, copy=False) - Y = csr_matrix(Y, copy=False) + X = csr_array(X, copy=False) + Y = csr_array(Y, copy=False) X.sum_duplicates() # this also sorts indices in-place Y.sum_duplicates() D = np.zeros((n_x, n_y)) @@ -1748,7 +1749,7 @@ def cosine_similarity(X, Y=None, dense_output=True): K = safe_sparse_dot(X_normalized, Y_normalized.T, dense_output=dense_output) - return K + return _align_api_if_sparse(K) @validate_params( diff --git a/sklearn/multiclass.py b/sklearn/multiclass.py index 92d8c8a960dd7..4a65fca807764 100644 --- a/sklearn/multiclass.py +++ b/sklearn/multiclass.py @@ -514,7 +514,7 @@ def predict(self, X): indices.extend(np.where(_predict_binary(e, X) > thresh)[0]) indptr.append(len(indices)) data = np.ones(len(indices), dtype=int) - indicator = sp.csc_matrix( + indicator = sp.csc_array( (data, indices, indptr), shape=(n_samples, len(self.estimators_)) ) return self.label_binarizer_.inverse_transform(indicator) diff --git a/sklearn/multioutput.py b/sklearn/multioutput.py index 79f1231520b39..6ab030c5ae02c 100644 --- a/sklearn/multioutput.py +++ b/sklearn/multioutput.py @@ -28,6 +28,7 @@ from sklearn.utils import Bunch, check_random_state, get_tags from sklearn.utils._param_validation import HasMethods, Hidden, StrOptions from sklearn.utils._response import _get_response_values +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils._user_interface import _print_elapsed_time from sklearn.utils.metadata_routing import ( MetadataRouter, @@ -734,7 +735,7 @@ def _get_predictions(self, X, *, output_method): inv_order[self.order_] = np.arange(len(self.order_)) Y_output = Y_output_chain[:, inv_order] - return Y_output + return _align_api_if_sparse(Y_output) @abstractmethod def fit(self, X, Y, **fit_params): diff --git a/sklearn/neighbors/_base.py b/sklearn/neighbors/_base.py index eeee7aa66bfe3..3929594b85077 100644 --- a/sklearn/neighbors/_base.py +++ b/sklearn/neighbors/_base.py @@ -12,7 +12,7 @@ import numpy as np from joblib import effective_n_jobs -from scipy.sparse import csr_matrix, issparse +from scipy.sparse import csr_array, issparse from sklearn.base import BaseEstimator, MultiOutputMixin, is_classifier from sklearn.exceptions import DataConversionWarning, EfficiencyWarning @@ -21,7 +21,7 @@ from sklearn.metrics.pairwise import PAIRWISE_DISTANCE_FUNCTIONS from sklearn.neighbors._ball_tree import BallTree from sklearn.neighbors._kd_tree import KDTree -from sklearn.utils import check_array, gen_even_slices, get_tags +from sklearn.utils import _align_api_if_sparse, check_array, gen_even_slices, get_tags from sklearn.utils._param_validation import Interval, StrOptions, validate_params from sklearn.utils.fixes import parse_version, sp_base_version from sklearn.utils.multiclass import check_classification_targets @@ -222,9 +222,9 @@ def sort_graph_by_row_values(graph, copy=False, warn_when_not_sorted=True): Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from sklearn.neighbors import sort_graph_by_row_values - >>> X = csr_matrix( + >>> X = csr_array( ... [[0., 3., 1.], ... [3., 0., 2.], ... [1., 2., 0.]]) @@ -1013,7 +1013,7 @@ def kneighbors_graph(self, X=None, n_neighbors=None, mode="connectivity"): # check the input only in self.kneighbors - # construct CSR matrix representation of the k-NN graph + # construct CSR representation of the k-NN graph if mode == "connectivity": A_ind = self.kneighbors(X, n_neighbors, return_distance=False) n_queries = A_ind.shape[0] @@ -1034,11 +1034,11 @@ def kneighbors_graph(self, X=None, n_neighbors=None, mode="connectivity"): n_nonzero = n_queries * n_neighbors A_indptr = np.arange(0, n_nonzero + 1, n_neighbors) - kneighbors_graph = csr_matrix( + kneighbors_graph = csr_array( (A_data, A_ind.ravel(), A_indptr), shape=(n_queries, n_samples_fit) ) - return kneighbors_graph + return _align_api_if_sparse(kneighbors_graph) class RadiusNeighborsMixin: @@ -1389,7 +1389,8 @@ def radius_neighbors_graph( A_data = np.ones(len(A_ind)) A_indptr = np.concatenate((np.zeros(1, dtype=int), np.cumsum(n_neighbors))) - return csr_matrix((A_data, A_ind, A_indptr), shape=(n_queries, n_samples_fit)) + csr = csr_array((A_data, A_ind, A_indptr), shape=(n_queries, n_samples_fit)) + return _align_api_if_sparse(csr) def __sklearn_tags__(self): tags = super().__sklearn_tags__() diff --git a/sklearn/preprocessing/_data.py b/sklearn/preprocessing/_data.py index 991b0132e3945..f7dd221150323 100644 --- a/sklearn/preprocessing/_data.py +++ b/sklearn/preprocessing/_data.py @@ -34,6 +34,7 @@ StrOptions, validate_params, ) +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils.extmath import _incremental_mean_and_var, row_norms from sklearn.utils.sparsefuncs import ( incr_mean_variance_axis, @@ -992,7 +993,7 @@ def partial_fit(self, X, y=None, sample_weight=None): "instead. See docstring for motivation and alternatives." ) sparse_constructor = ( - sparse.csr_matrix if X.format == "csr" else sparse.csc_matrix + sparse.csr_array if X.format == "csr" else sparse.csc_array ) if self.with_std: @@ -2629,7 +2630,8 @@ def add_dummy_feature(X, value=1.0): row = np.concatenate((np.arange(n_samples), X.row)) # Prepend the dummy feature n_samples times. data = np.concatenate((np.full(n_samples, value), X.data)) - return sparse.coo_matrix((data, (row, col)), shape) + result = sparse.coo_array((data, (row, col)), shape) + return _align_api_if_sparse(result) elif X.format == "csc": # Shift index pointers since we need to add n_samples elements. indptr = X.indptr + n_samples @@ -2639,10 +2641,10 @@ def add_dummy_feature(X, value=1.0): indices = np.concatenate((np.arange(n_samples), X.indices)) # Prepend the dummy feature n_samples times. data = np.concatenate((np.full(n_samples, value), X.data)) - return sparse.csc_matrix((data, indices, indptr), shape) - else: - klass = X.__class__ - return klass(add_dummy_feature(X.tocoo(), value)) + result = sparse.csc_array((data, indices, indptr), shape) + return _align_api_if_sparse(result) + else: # "csr" format + return _align_api_if_sparse(add_dummy_feature(X.tocoo(), value).tocsr()) else: return np.hstack((np.full((n_samples, 1), value), X)) @@ -2819,7 +2821,7 @@ def _sparse_fit(self, X, random_state): X : sparse matrix of shape (n_samples, n_features) The data used to scale along the features axis. The sparse matrix needs to be nonnegative. If a sparse matrix is provided, - it will be converted into a sparse ``csc_matrix``. + it will be converted into a SciPy sparse CSC matrix. """ n_samples, n_features = X.shape references = self.references_ * 100 @@ -2860,7 +2862,7 @@ def fit(self, X, y=None): X : {array-like, sparse matrix} of shape (n_samples, n_features) The data used to scale along the features axis. If a sparse matrix is provided, it will be converted into a sparse - ``csc_matrix``. Additionally, the sparse matrix needs to be + CSC matrix. Additionally, the sparse matrix needs to be nonnegative if `ignore_implicit_zeros` is False. y : None @@ -3032,7 +3034,7 @@ def transform(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The data used to scale along the features axis. If a sparse matrix is provided, it will be converted into a sparse - ``csc_matrix``. Additionally, the sparse matrix needs to be + CSC matrix. Additionally, the sparse matrix needs to be nonnegative if `ignore_implicit_zeros` is False. Returns @@ -3053,7 +3055,7 @@ def inverse_transform(self, X): X : {array-like, sparse matrix} of shape (n_samples, n_features) The data used to scale along the features axis. If a sparse matrix is provided, it will be converted into a sparse - ``csc_matrix``. Additionally, the sparse matrix needs to be + CSC_matrix. Additionally, the sparse matrix needs to be nonnegative if `ignore_implicit_zeros` is False. Returns diff --git a/sklearn/preprocessing/_encoders.py b/sklearn/preprocessing/_encoders.py index 637f11a65f64a..186056d6715a0 100644 --- a/sklearn/preprocessing/_encoders.py +++ b/sklearn/preprocessing/_encoders.py @@ -14,7 +14,7 @@ TransformerMixin, _fit_context, ) -from sklearn.utils import _safe_indexing, check_array +from sklearn.utils import _align_api_if_sparse, _safe_indexing, check_array from sklearn.utils._encode import _check_unknown, _encode, _get_counts, _unique from sklearn.utils._mask import _get_mask from sklearn.utils._missing import is_scalar_nan @@ -544,8 +544,8 @@ class OneHotEncoder(_BaseEncoder): Support for dropping infrequent categories. sparse_output : bool, default=True - When ``True``, it returns a :class:`scipy.sparse.csr_matrix`, - i.e. a sparse matrix in "Compressed Sparse Row" (CSR) format. + When ``True``, it returns a SciPy sparse matrix/array + in "Compressed Sparse Row" (CSR) format. .. versionadded:: 1.2 `sparse` was renamed to `sparse_output` @@ -1009,8 +1009,7 @@ def transform(self, X): """ Transform X using one-hot encoding. - If `sparse_output=True` (default), it returns an instance of - :class:`scipy.sparse._csr.csr_matrix` (CSR format). + If `sparse_output=True` (default), it returns a SciPy sparse in CSR format. If there are infrequent categories for a feature, set by specifying `max_categories` or `min_frequency`, the infrequent categories are @@ -1082,15 +1081,15 @@ def transform(self, X): np.cumsum(indptr[1:], out=indptr[1:]) data = np.ones(indptr[-1]) - out = sparse.csr_matrix( + out = sparse.csr_array( (data, indices, indptr), shape=(n_samples, feature_indices[-1]), dtype=self.dtype, ) - if not self.sparse_output: - return out.toarray() + if self.sparse_output: + return _align_api_if_sparse(out) else: - return out + return out.toarray() def inverse_transform(self, X): """ diff --git a/sklearn/preprocessing/_label.py b/sklearn/preprocessing/_label.py index 2d9d57df94c55..2851ecf44a909 100644 --- a/sklearn/preprocessing/_label.py +++ b/sklearn/preprocessing/_label.py @@ -11,7 +11,7 @@ import scipy.sparse as sp from sklearn.base import BaseEstimator, TransformerMixin, _fit_context -from sklearn.utils import column_or_1d +from sklearn.utils import _align_api_if_sparse, column_or_1d from sklearn.utils._array_api import ( _convert_to_numpy, _find_matching_floating_dtype, @@ -449,7 +449,7 @@ def inverse_transform(self, Y, threshold=None): ) if self.sparse_input_: - y_inv = sp.csr_matrix(y_inv) + y_inv = _align_api_if_sparse(sp.csr_array(y_inv)) elif sp.issparse(y_inv): y_inv = y_inv.toarray() @@ -598,7 +598,7 @@ def label_binarize(y, *, classes, neg_label=0, pos_label=1, sparse_output=False) if y_type == "binary": if n_classes == 1: if sparse_output: - return sp.csr_matrix((n_samples, 1), dtype=int) + return _align_api_if_sparse(sp.csr_array((n_samples, 1), dtype=int)) else: Y = xp.zeros((n_samples, 1), dtype=int_dtype_) Y += neg_label @@ -634,7 +634,7 @@ def label_binarize(y, *, classes, neg_label=0, pos_label=1, sparse_output=False) data = xp.full_like(indices, pos_label) # Use NumPy to construct the sparse matrix of one-hot labels - Y = sp.csr_matrix( + Y = sp.csr_array( ( _convert_to_numpy(data, xp=xp), _convert_to_numpy(indices, xp=xp), @@ -648,7 +648,7 @@ def label_binarize(y, *, classes, neg_label=0, pos_label=1, sparse_output=False) elif y_type == "multilabel-indicator": if sparse_output: - Y = sp.csr_matrix(y) + Y = sp.csr_array(y) if pos_label != 1: data = xp.full_like(Y.data, pos_label) Y.data = data @@ -687,7 +687,7 @@ def label_binarize(y, *, classes, neg_label=0, pos_label=1, sparse_output=False) else: Y = xp.reshape(Y[:, -1], (-1, 1)) - return Y + return _align_api_if_sparse(Y) def _inverse_binarize_multiclass(y, classes, xp=None): @@ -1011,8 +1011,10 @@ def _transform(self, y, class_mapping): ) data = np.ones(len(indices), dtype=int) - return sp.csr_matrix( - (data, indices, indptr), shape=(len(indptr) - 1, len(class_mapping)) + return _align_api_if_sparse( + sp.csr_array( + (data, indices, indptr), shape=(len(indptr) - 1, len(class_mapping)) + ) ) def inverse_transform(self, yt): diff --git a/sklearn/preprocessing/_polynomial.py b/sklearn/preprocessing/_polynomial.py index de20a037a9b73..4c887ab7f6a4b 100644 --- a/sklearn/preprocessing/_polynomial.py +++ b/sklearn/preprocessing/_polynomial.py @@ -21,7 +21,7 @@ _calc_total_nnz, _csr_polynomial_expansion, ) -from sklearn.utils import check_array +from sklearn.utils import _align_api_if_sparse, check_array from sklearn.utils._array_api import ( _is_numpy_namespace, get_namespace_and_device, @@ -80,10 +80,12 @@ def _create_expansion(X, interaction_only, deg, n_features, cumulative_size=0): interaction_only, deg, ) - return sparse.csr_matrix( - (expanded_data, expanded_indices, expanded_indptr), - shape=(X.indptr.shape[0] - 1, expanded_col), - dtype=X.dtype, + return _align_api_if_sparse( + sparse.csr_array( + (expanded_data, expanded_indices, expanded_indptr), + shape=(X.indptr.shape[0] - 1, expanded_col), + dtype=X.dtype, + ) ) @@ -416,8 +418,7 @@ def transform(self, X): XP : {ndarray, sparse matrix} of shape (n_samples, NP) The matrix of features, where `NP` is the number of polynomial features generated from the combination of inputs. If a sparse - matrix is provided, it will be converted into a sparse - `csr_matrix`. + matrix is provided, it will be converted into CSR format. """ check_is_fitted(self) xp, _, device_ = get_namespace_and_device(X) @@ -438,7 +439,7 @@ def transform(self, X): to_stack = [] if self.include_bias: to_stack.append( - sparse.csr_matrix(np.ones(shape=(n_samples, 1), dtype=X.dtype)) + sparse.csr_array(np.ones(shape=(n_samples, 1), dtype=X.dtype)) ) if self._min_degree <= 1 and self._max_degree > 0: to_stack.append(X) @@ -457,7 +458,7 @@ def transform(self, X): cumulative_size += expanded.shape[1] if len(to_stack) == 0: # edge case: deal with empty matrix - XP = sparse.csr_matrix((n_samples, 0), dtype=X.dtype) + XP = sparse.csr_array((n_samples, 0), dtype=X.dtype) else: XP = sparse.hstack(to_stack, dtype=X.dtype, format="csr") elif sparse.issparse(X) and X.format == "csc" and self._max_degree < 4: @@ -478,7 +479,7 @@ def transform(self, X): out_col = X[:, [col_idx]].multiply(out_col) columns.append(out_col) else: - bias = sparse.csc_matrix(np.ones((X.shape[0], 1))) + bias = sparse.csc_array(np.ones((X.shape[0], 1))) columns.append(bias) XP = sparse.hstack(columns, dtype=X.dtype).tocsc() else: @@ -520,7 +521,7 @@ def transform(self, X): current_col = 0 if self._max_degree == 0: - return XP + return _align_api_if_sparse(XP) # degree 1 term XP[:, current_col : current_col + n_features] = X @@ -573,7 +574,7 @@ def transform(self, X): else: Xout = xp.asarray(XP[:, n_XP - n_Xout :], copy=True) XP = Xout - return XP + return _align_api_if_sparse(XP) def __sklearn_tags__(self): tags = super().__sklearn_tags__() @@ -1118,8 +1119,7 @@ def transform(self, X): XBS_sparse = BSpline.design_matrix(x, spl.t, spl.k) # Note: Without converting to lil_matrix we would get: # scipy.sparse._base.SparseEfficiencyWarning: Changing the sparsity - # structure of a csr_matrix is expensive. lil_matrix is more - # efficient. + # structure of CSC is expensive. LIL is more efficient. if np.any(outside_range_mask): XBS_sparse = XBS_sparse.tolil() XBS_sparse[outside_range_mask, :] = 0 @@ -1241,6 +1241,8 @@ def transform(self, X): if self.sparse_output: XBS = sparse.hstack(output_list, format="csr") + XBS = _align_api_if_sparse(XBS) + if self.include_bias: return XBS else: diff --git a/sklearn/preprocessing/tests/test_data.py b/sklearn/preprocessing/tests/test_data.py index e82fd55a10148..0d0c90e4cb577 100644 --- a/sklearn/preprocessing/tests/test_data.py +++ b/sklearn/preprocessing/tests/test_data.py @@ -64,6 +64,7 @@ CSC_CONTAINERS, CSR_CONTAINERS, LIL_CONTAINERS, + _sparse_random_array, sp_version, ) from sklearn.utils.sparsefuncs import mean_variance_axis @@ -2593,7 +2594,7 @@ def test_power_transformer_box_cox_raise_all_nans_col(): @pytest.mark.parametrize( "X_2", - [sparse.random(10, 1, density=0.8, random_state=0)] + [_sparse_random_array((10, 1), density=0.8, rng=0)] + [ csr_container(np.full((10, 1), fill_value=np.nan)) for csr_container in CSR_CONTAINERS @@ -2602,7 +2603,7 @@ def test_power_transformer_box_cox_raise_all_nans_col(): def test_standard_scaler_sparse_partial_fit_finite_variance(X_2): # non-regression test for: # https://github.com/scikit-learn/scikit-learn/issues/16448 - X_1 = sparse.random(5, 1, density=0.8) + X_1 = _sparse_random_array((5, 1), density=0.8) scaler = StandardScaler(with_mean=False) scaler.fit(X_1).partial_fit(X_2) assert np.isfinite(scaler.var_[0]) diff --git a/sklearn/random_projection.py b/sklearn/random_projection.py index 389d6da127f89..8aeec73c13f9b 100644 --- a/sklearn/random_projection.py +++ b/sklearn/random_projection.py @@ -40,7 +40,7 @@ _fit_context, ) from sklearn.exceptions import DataDimensionalityWarning -from sklearn.utils import check_random_state +from sklearn.utils import _align_api_if_sparse, check_random_state from sklearn.utils._param_validation import Interval, StrOptions, validate_params from sklearn.utils.extmath import safe_sparse_dot from sklearn.utils.random import sample_without_replacement @@ -297,9 +297,10 @@ def _sparse_random_matrix(n_components, n_features, density="auto", random_state data = rng.binomial(1, 0.5, size=np.size(indices)) * 2 - 1 # build the CSR structure by concatenating the rows - components = sp.csr_matrix( + components = sp.csr_array( (data, indices, indptr), shape=(n_components, n_features) ) + components = _align_api_if_sparse(components) return np.sqrt(1 / density) / np.sqrt(n_components) * components @@ -455,10 +456,10 @@ def inverse_transform(self, X): X = check_array(X, dtype=[np.float64, np.float32], accept_sparse=("csr", "csc")) if self.compute_inverse_components: - return X @ self.inverse_components_.T + return _align_api_if_sparse(X @ self.inverse_components_.T) inverse_components = self._compute_inverse_components() - return X @ inverse_components.T + return _align_api_if_sparse(X @ inverse_components.T) def __sklearn_tags__(self): tags = super().__sklearn_tags__() @@ -609,7 +610,7 @@ def transform(self, X): dtype=[np.float64, np.float32], ) - return X @ self.components_.T + return _align_api_if_sparse(X @ self.components_.T) class SparseRandomProjection(BaseRandomProjection): @@ -821,4 +822,6 @@ def transform(self, X): dtype=[np.float64, np.float32], ) - return safe_sparse_dot(X, self.components_.T, dense_output=self.dense_output) + return _align_api_if_sparse( + safe_sparse_dot(X, self.components_.T, dense_output=self.dense_output) + ) diff --git a/sklearn/semi_supervised/_label_propagation.py b/sklearn/semi_supervised/_label_propagation.py index 95dffd212dee0..6986bb1853a13 100644 --- a/sklearn/semi_supervised/_label_propagation.py +++ b/sklearn/semi_supervised/_label_propagation.py @@ -68,6 +68,7 @@ from sklearn.neighbors import NearestNeighbors from sklearn.utils._param_validation import Interval, StrOptions from sklearn.utils.extmath import safe_sparse_dot +from sklearn.utils.fixes import SCIPY_VERSION_BELOW_1_12 from sklearn.utils.fixes import laplacian as csgraph_laplacian from sklearn.utils.multiclass import check_classification_targets from sklearn.utils.validation import check_is_fitted, validate_data @@ -461,14 +462,17 @@ def _build_graph(self): # handle spmatrix (make normalizer 1D) if sparse.isspmatrix(affinity_matrix): normalizer = np.ravel(normalizer) - # TODO: when SciPy 1.12+ is min dependence, replace up to ---- with: - # affinity_matrix /= normalizer[:, np.newaxis] - if sparse.issparse(affinity_matrix): - inv_normalizer = sparse.diags(1.0 / normalizer) - affinity_matrix = inv_normalizer @ affinity_matrix - else: # Dense affinity_matrix - affinity_matrix /= normalizer[:, np.newaxis] - # ---- + + if SCIPY_VERSION_BELOW_1_12: + if sparse.issparse(affinity_matrix): + inv_normalizer = sparse.diags(1.0 / normalizer) + affinity_matrix = inv_normalizer @ affinity_matrix + else: # Dense affinity_matrix + affinity_matrix /= normalizer[:, np.newaxis] + return affinity_matrix + + # same syntax for sparse or dense + affinity_matrix /= normalizer[:, np.newaxis] return affinity_matrix def fit(self, X, y): diff --git a/sklearn/svm/_base.py b/sklearn/svm/_base.py index b4b0ccbb854a3..855658bc3e3f8 100644 --- a/sklearn/svm/_base.py +++ b/sklearn/svm/_base.py @@ -24,7 +24,9 @@ compute_class_weight, ) from sklearn.utils._param_validation import Hidden, Interval, StrOptions +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils.extmath import safe_sparse_dot +from sklearn.utils.fixes import SCIPY_VERSION_BELOW_1_12 from sklearn.utils.metaestimators import available_if from sklearn.utils.multiclass import ( _ovr_decision_function, @@ -64,10 +66,16 @@ def _one_vs_one_coef(dual_coef, n_support, support_vectors): # SVs for class1: sv2 = support_vectors[sv_locs[class2] : sv_locs[class2 + 1], :] - # dual coef for class1 SVs: - alpha1 = dual_coef[class2 - 1, sv_locs[class1] : sv_locs[class1 + 1]] - # dual coef for class2 SVs: - alpha2 = dual_coef[class1, sv_locs[class2] : sv_locs[class2 + 1]] + if SCIPY_VERSION_BELOW_1_12: + # dual coef for class1 SVs: + alpha1 = dual_coef[[class2 - 1], sv_locs[class1] : sv_locs[class1 + 1]] + # dual coef for class2 SVs: + alpha2 = dual_coef[[class1], sv_locs[class2] : sv_locs[class2 + 1]] + else: + # dual coef for class1 SVs: + alpha1 = dual_coef[class2 - 1, sv_locs[class1] : sv_locs[class1 + 1]] + # dual coef for class2 SVs: + alpha2 = dual_coef[class1, sv_locs[class2] : sv_locs[class2 + 1]] # build weight for class1 vs class2 coef.append(safe_sparse_dot(alpha1, sv1) + safe_sparse_dot(alpha2, sv2)) @@ -187,7 +195,7 @@ def fit(self, X, y, sample_weight=None): Notes ----- If X and y are not C-ordered and contiguous arrays of np.float64 and - X is not a scipy.sparse.csr_matrix, X and/or y may be copied. + X is not a sparse CSR format, X and/or y may be copied. If X is a dense array, then the other methods will not support sparse matrices as input. @@ -434,13 +442,16 @@ def _sparse_fit(self, X, y, sample_weight, solver_type, kernel, random_seed): dual_coef_indices = np.tile(np.arange(n_SV), n_class) if not n_SV: - self.dual_coef_ = sp.csr_matrix([]) + self.dual_coef_ = _align_api_if_sparse(sp.csr_array([[]])) else: dual_coef_indptr = np.arange( 0, dual_coef_indices.size + 1, dual_coef_indices.size / n_class ) - self.dual_coef_ = sp.csr_matrix( - (dual_coef_data, dual_coef_indices, dual_coef_indptr), (n_class, n_SV) + self.dual_coef_ = _align_api_if_sparse( + sp.csr_array( + (dual_coef_data, dual_coef_indices, dual_coef_indptr), + (n_class, n_SV), + ) ) def predict(self, X): @@ -498,7 +509,7 @@ def _dense_predict(self, X): ) def _sparse_predict(self, X): - # Precondition: X is a csr_matrix of dtype np.float64. + # Precondition: X is CSR sparse of dtype np.float64. kernel = self.kernel if callable(kernel): kernel = "precomputed" @@ -647,9 +658,9 @@ def _validate_for_predict(self, X): reset=False, ) - if self._sparse and not sp.issparse(X): - X = sp.csr_matrix(X) if self._sparse: + if not sp.issparse(X): + X = _align_api_if_sparse(sp.csr_array(X)) X.sort_indices() if sp.issparse(X) and not self._sparse and not callable(self.kernel): diff --git a/sklearn/svm/_libsvm_sparse.pyx b/sklearn/svm/_libsvm_sparse.pyx index 1e2c35e0f8dc7..df7ddb0d52823 100644 --- a/sklearn/svm/_libsvm_sparse.pyx +++ b/sklearn/svm/_libsvm_sparse.pyx @@ -1,6 +1,7 @@ import numpy as np from scipy import sparse from sklearn.utils._cython_blas cimport _dot +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils._typedefs cimport float64_t, int32_t, intp_t cdef extern from *: @@ -215,9 +216,9 @@ def libsvm_sparse_train (int n_features, model, n_features, ) - support_vectors_ = sparse.csr_matrix( + support_vectors_ = _align_api_if_sparse(sparse.csr_array( (SV_data, SV_indices, SV_indptr), (SV_len, n_features) - ) + )) # copy model.nSV # TODO: do only in classification diff --git a/sklearn/tests/test_base.py b/sklearn/tests/test_base.py index d84a113ba5447..392b7881b2bd7 100644 --- a/sklearn/tests/test_base.py +++ b/sklearn/tests/test_base.py @@ -189,6 +189,10 @@ def test_clone_empty_array(): clf2 = clone(clf) assert_array_equal(clf.empty.data, clf2.empty.data) + clf = MyEstimator(empty=sp.csr_array(np.array([[0]]))) + clf2 = clone(clf) + assert_array_equal(clf.empty.data, clf2.empty.data) + def test_clone_nan(): # Regression test for cloning estimators with default parameter as np.nan @@ -209,7 +213,8 @@ def test_clone_sparse_matrices(): sparse_matrix_classes = [ cls for name in dir(sp) - if name.endswith("_matrix") and type(cls := getattr(sp, name)) is type + if name.endswith("_matrix") or name.endswith("_array") + if type(cls := getattr(sp, name)) is type ] for cls in sparse_matrix_classes: diff --git a/sklearn/tests/test_common.py b/sklearn/tests/test_common.py index 4d57a54c5e6ff..ccff345ddb10e 100644 --- a/sklearn/tests/test_common.py +++ b/sklearn/tests/test_common.py @@ -113,6 +113,7 @@ def test_get_check_estimator_ids(val, expected): assert _get_check_estimator_ids(val) == expected +@pytest.mark.no_check_spmatrix # pickle breaks check_spmatrix @parametrize_with_checks( list(_tested_estimators()), expected_failed_checks=_get_expected_failed_checks ) diff --git a/sklearn/tests/test_config.py b/sklearn/tests/test_config.py index bf35eee623c18..b7beda31c2fd5 100644 --- a/sklearn/tests/test_config.py +++ b/sklearn/tests/test_config.py @@ -21,6 +21,7 @@ def test_config_context(): "transform_output": "default", "enable_metadata_routing": False, "skip_parameter_validation": False, + "sparse_interface": "spmatrix", } # Not using as a context manager affects nothing @@ -39,6 +40,7 @@ def test_config_context(): "transform_output": "default", "enable_metadata_routing": False, "skip_parameter_validation": False, + "sparse_interface": "spmatrix", } assert get_config()["assume_finite"] is False @@ -74,6 +76,7 @@ def test_config_context(): "transform_output": "default", "enable_metadata_routing": False, "skip_parameter_validation": False, + "sparse_interface": "spmatrix", } # No positional arguments diff --git a/sklearn/tests/test_docstrings.py b/sklearn/tests/test_docstrings.py index 47b8052b31998..2b82255bfb2e0 100644 --- a/sklearn/tests/test_docstrings.py +++ b/sklearn/tests/test_docstrings.py @@ -155,6 +155,7 @@ def test_function_docstring(function_name, request): raise ValueError(msg) +@pytest.mark.no_check_spmatrix # no __module__ for check_spmatrix classes @pytest.mark.parametrize("Klass, method", get_all_methods()) def test_docstring(Klass, method, request): base_import_path = Klass.__module__ diff --git a/sklearn/tree/_tree.pyx b/sklearn/tree/_tree.pyx index 7044673189fb6..6facd0cc34b79 100644 --- a/sklearn/tree/_tree.pyx +++ b/sklearn/tree/_tree.pyx @@ -21,7 +21,9 @@ cimport numpy as cnp cnp.import_array() from scipy.sparse import issparse -from scipy.sparse import csr_matrix +from scipy.sparse import csr_array + +from sklearn.utils import _align_api_if_sparse from sklearn.tree._utils cimport safe_realloc from sklearn.tree._utils cimport sizet_ptr_to_ndarray @@ -1002,7 +1004,7 @@ cdef class Tree: """ # Check input if not (issparse(X) and X.format == 'csr'): - raise ValueError("X should be in csr_matrix format, got %s" + raise ValueError("X should be in CSR sparse format, got %s" % type(X)) if X.dtype != DTYPE: @@ -1127,17 +1129,17 @@ cdef class Tree: indices = indices[:indptr[n_samples]] cdef intp_t[:] data = np.ones(shape=len(indices), dtype=np.intp) - out = csr_matrix((data, indices, indptr), - shape=(n_samples, self.node_count)) + out = csr_array((data, indices, indptr), + shape=(n_samples, self.node_count)) - return out + return _align_api_if_sparse(out) cdef inline object _decision_path_sparse_csr(self, object X): """Finds the decision path (=node) for each sample in X.""" # Check input if not (issparse(X) and X.format == "csr"): - raise ValueError("X should be in csr_matrix format, got %s" + raise ValueError("X should be in CSR sparse format, got %s" % type(X)) if X.dtype != DTYPE: @@ -1211,10 +1213,10 @@ cdef class Tree: indices = indices[:indptr[n_samples]] cdef intp_t[:] data = np.ones(shape=len(indices), dtype=np.intp) - out = csr_matrix((data, indices, indptr), - shape=(n_samples, self.node_count)) + out = csr_array((data, indices, indptr), + shape=(n_samples, self.node_count)) - return out + return _align_api_if_sparse(out) cpdef compute_node_depths(self): """Compute the depth of each node in a tree. diff --git a/sklearn/utils/__init__.py b/sklearn/utils/__init__.py index 87f015ddaa267..ffe68252e0189 100644 --- a/sklearn/utils/__init__.py +++ b/sklearn/utils/__init__.py @@ -17,6 +17,7 @@ from sklearn.utils._mask import safe_mask from sklearn.utils._repr_html.base import _HTMLDocumentationLinkMixin # noqa: F401 from sklearn.utils._repr_html.estimator import estimator_html_repr +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils._tags import ( ClassifierTags, InputTags, @@ -53,6 +54,7 @@ "Tags", "TargetTags", "TransformerTags", + "_align_api_if_sparse", "_safe_indexing", "all_estimators", "as_float_array", diff --git a/sklearn/utils/_indexing.py b/sklearn/utils/_indexing.py index 484e716bc1170..6ac7bb01aaa1c 100644 --- a/sklearn/utils/_indexing.py +++ b/sklearn/utils/_indexing.py @@ -23,7 +23,7 @@ ) from sklearn.utils._param_validation import Interval, validate_params from sklearn.utils.extmath import _approximate_mode -from sklearn.utils.fixes import PYARROW_VERSION_BELOW_17 +from sklearn.utils.fixes import PYARROW_VERSION_BELOW_17, SCIPY_VERSION_BELOW_1_12 from sklearn.utils.validation import ( _check_sample_weight, _is_arraylike_not_scalar, @@ -56,8 +56,12 @@ def _array_indexing(array, key, key_dtype, axis): indices = xp.arange(array.shape[axis], device=device_) return xp.take(array, indices[key], axis=axis) - if issparse(array) and key_dtype == "bool": - key = np.asarray(key) + if issparse(array): + if key_dtype == "bool": + key = np.asarray(key) + elif SCIPY_VERSION_BELOW_1_12: + if isinstance(key, numbers.Integral): + key = [key] if isinstance(key, tuple): key = list(key) return array[key, ...] if axis == 0 else array[:, key] @@ -593,8 +597,8 @@ def resample( >>> X = np.array([[1., 0.], [2., 1.], [0., 0.]]) >>> y = np.array([0, 1, 2]) - >>> from scipy.sparse import coo_matrix - >>> X_sparse = coo_matrix(X) + >>> from scipy.sparse import coo_array + >>> X_sparse = coo_array(X) >>> from sklearn.utils import resample >>> X, X_sparse, y = resample(X, X_sparse, y, random_state=0) @@ -604,7 +608,7 @@ def resample( [1., 0.]]) >>> X_sparse - <Compressed Sparse Row sparse matrix of dtype 'float64' + <Compressed Sparse Row sparse array of dtype 'float64' with 4 stored elements and shape (3, 2)> >>> X_sparse.toarray() @@ -751,8 +755,8 @@ def shuffle(*arrays, random_state=None, n_samples=None): >>> X = np.array([[1., 0.], [2., 1.], [0., 0.]]) >>> y = np.array([0, 1, 2]) - >>> from scipy.sparse import coo_matrix - >>> X_sparse = coo_matrix(X) + >>> from scipy.sparse import coo_array + >>> X_sparse = coo_array(X) >>> from sklearn.utils import shuffle >>> X, X_sparse, y = shuffle(X, X_sparse, y, random_state=0) @@ -762,7 +766,7 @@ def shuffle(*arrays, random_state=None, n_samples=None): [1., 0.]]) >>> X_sparse - <Compressed Sparse Row sparse matrix of dtype 'float64' + <Compressed Sparse Row sparse array of dtype 'float64' with 3 stored elements and shape (3, 2)> >>> X_sparse.toarray() diff --git a/sklearn/utils/_mask.py b/sklearn/utils/_mask.py index 83361743ce3e7..d6b44cea76d97 100644 --- a/sklearn/utils/_mask.py +++ b/sklearn/utils/_mask.py @@ -8,6 +8,7 @@ from sklearn.utils._missing import is_scalar_nan from sklearn.utils._param_validation import validate_params +from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils.fixes import _object_dtype_isnan @@ -59,12 +60,12 @@ def _get_mask(X, value_to_mask): Xt = _get_dense_mask(X.data, value_to_mask) - sparse_constructor = sp.csr_matrix if X.format == "csr" else sp.csc_matrix + sparse_constructor = sp.csr_array if X.format == "csr" else sp.csc_array Xt_sparse = sparse_constructor( (Xt, X.indices.copy(), X.indptr.copy()), shape=X.shape, dtype=bool ) - return Xt_sparse + return _align_api_if_sparse(Xt_sparse) @validate_params( @@ -93,8 +94,8 @@ def safe_mask(X, mask): Examples -------- >>> from sklearn.utils import safe_mask - >>> from scipy.sparse import csr_matrix - >>> data = csr_matrix([[1], [2], [3], [4], [5]]) + >>> from scipy.sparse import csr_array + >>> data = csr_array([[1], [2], [3], [4], [5]]) >>> condition = [False, True, True, False, True] >>> mask = safe_mask(data, condition) >>> data[mask].toarray() diff --git a/sklearn/utils/_param_validation.py b/sklearn/utils/_param_validation.py index 24b0846508381..5a8c8733d2c97 100644 --- a/sklearn/utils/_param_validation.py +++ b/sklearn/utils/_param_validation.py @@ -11,7 +11,7 @@ from numbers import Integral, Real import numpy as np -from scipy.sparse import csr_matrix, issparse +from scipy.sparse import csr_array, issparse from sklearn._config import config_context, get_config from sklearn.utils.validation import _is_arraylike_not_scalar @@ -541,7 +541,7 @@ def is_satisfied_by(self, val): return issparse(val) def __str__(self): - return "a sparse matrix" + return "a sparse array or matrix" class _Callables(_Constraint): @@ -844,7 +844,7 @@ def generate_valid_param(constraint): return np.array([1, 2, 3]) if isinstance(constraint, _SparseMatrices): - return csr_matrix([[0, 1], [1, 0]]) + return csr_array([[0, 1], [1, 0]]) if isinstance(constraint, _RandomStates): return np.random.RandomState(42) diff --git a/sklearn/utils/_sparse.py b/sklearn/utils/_sparse.py new file mode 100644 index 0000000000000..8975f2264cdab --- /dev/null +++ b/sklearn/utils/_sparse.py @@ -0,0 +1,39 @@ +"""Control sparse interface based on config""" + +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +import scipy as sp + +from sklearn._config import get_config + + +def _align_api_if_sparse(X): + """ + Convert to sparse interface as set in config. + + Input can be dense or sparse. + If sparse, convert to sparse_interface indicated by get_config. + Otherwise, return X unchanged. + """ + if not sp.sparse.issparse(X): + return X + + config_sparse_interface = get_config()["sparse_interface"] + + # there are only two sparse interfaces: sparray and spmatrix + if config_sparse_interface == "sparray": + if sp.sparse.isspmatrix(X): + # Fundamental code to switch to sparray in any format + return getattr(sp.sparse, X.format + "_array")(X) + return X + elif config_sparse_interface == "spmatrix": + if sp.sparse.isspmatrix(X): + return X + # Fundamental code to switch to spmatrix in any format + return getattr(sp.sparse, X.format + "_matrix")(X) + else: + raise ValueError( + f'Config "sparse_interface" is {config_sparse_interface}. ' + 'It should be either "sparray" or "spmatrix".' + ) diff --git a/sklearn/utils/extmath.py b/sklearn/utils/extmath.py index 34fe2ba09006c..4fddf5c03a801 100644 --- a/sklearn/utils/extmath.py +++ b/sklearn/utils/extmath.py @@ -152,7 +152,7 @@ def density(w): -------- >>> from scipy import sparse >>> from sklearn.utils.extmath import density - >>> X = sparse.random(10, 10, density=0.25, random_state=0) + >>> X = sparse.random_array((10, 10), density=0.25, rng=0) >>> density(X) 0.25 """ @@ -181,9 +181,9 @@ def safe_sparse_dot(a, b, *, dense_output=False): Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from sklearn.utils.extmath import safe_sparse_dot - >>> X = csr_matrix([[1, 2], [3, 4], [5, 6]]) + >>> X = csr_array([[1, 2], [3, 4], [5, 6]]) >>> dot_product = safe_sparse_dot(X, X.T) >>> dot_product.toarray() array([[ 5, 11, 17], @@ -571,7 +571,7 @@ def _randomized_svd( if sparse.issparse(M) and M.format in ("lil", "dok"): warnings.warn( "Calculating SVD of a {} is expensive. " - "csr_matrix is more efficient.".format(type(M).__name__), + "CSR format is more efficient.".format(type(M).__name__), sparse.SparseEfficiencyWarning, ) diff --git a/sklearn/utils/fixes.py b/sklearn/utils/fixes.py index eebc640968a3b..8e856452213da 100644 --- a/sklearn/utils/fixes.py +++ b/sklearn/utils/fixes.py @@ -65,7 +65,17 @@ def _mode(a, axis=0): return mode -# TODO: Remove when SciPy 1.12 is the minimum supported version +# TODO: Remove when Scipy 1.12 is the minimum supported version +# Use git grep to see where this is used and update them too. +SCIPY_VERSION_BELOW_1_12 = sp_base_version < parse_version("1.12.0") + + +# TODO: Remove when Scipy 1.15 is the minimum supported version +# Use git grep to see where this is used and update them too. +SCIPY_VERSION_BELOW_1_15 = sp_base_version < parse_version("1.15.0") + + +# TODO: Remove when Scipy 1.12 is the minimum supported version if sp_base_version >= parse_version("1.12.0"): _sparse_linalg_cg = scipy.sparse.linalg.cg else: @@ -131,13 +141,13 @@ def _min_or_max_axis(X, axis, min_or_max): value = np.compress(mask, value) if axis == 0: - res = scipy.sparse.coo_matrix( + res = scipy.sparse.coo_array( (value, (np.zeros(len(value)), major_index)), dtype=X.dtype, shape=(1, M), ) else: - res = scipy.sparse.coo_matrix( + res = scipy.sparse.coo_array( (value, (major_index, np.zeros(len(value)))), dtype=X.dtype, shape=(M, 1), @@ -393,3 +403,141 @@ def _get_additional_lbfgs_options_dict(key, value): PYARROW_VERSION_BELOW_17 = True except ModuleNotFoundError: # pragma: no cover pass + + +# TODO: Replace when Scipy 1.12 is the minimum supported version +# fixes for transitioning scipy.sparse function names +if not SCIPY_VERSION_BELOW_1_12: + _sparse_eye_array = scipy.sparse.eye_array + _sparse_diags_array = scipy.sparse.diags_array + + def _sparse_random_array( + shape, + *, + density=0.01, + format="coo", + dtype=None, + random_state=None, + rng=None, + data_sampler=None, + ): + X = scipy.sparse.random_array( + shape, + density=density, + format=format, + dtype=dtype, + random_state=rng or random_state, + data_sampler=data_sampler, + ) + _ensure_sparse_index_int32(X) + return X + +else: + + def _sparse_eye_array(m, n=None, *, k=0, dtype=float, format=None): + return scipy.sparse.eye(m, n, k=k, dtype=dtype, format=format) + + def _sparse_diags_array( + diagonals, /, *, offsets=0, shape=None, format=None, dtype=None + ): + return scipy.sparse.diags( + diagonals, offsets=offsets, shape=shape, format=format, dtype=dtype + ) + + def _sparse_random_array( + shape, + *, + density=0.01, + format="coo", + dtype=None, + random_state=None, + rng=None, + data_sampler=None, + ): + return scipy.sparse.random( + *shape, + density=density, + format=format, + dtype=dtype, + random_state=rng or random_state, + data_rvs=data_sampler, + ) + + +# TODO: remove when SciPy 1.15 is minimal supported version +# fix for casting index arrays +def _ensure_sparse_index_int32(A): + """Safely ensure that index arrays are int32.""" + if A.format in ("csc", "csr", "bsr"): + A.indices, A.indptr = _safely_cast_index_arrays(A) + elif A.format == "coo": + if hasattr(A, "coords"): + A.coords = _safely_cast_index_arrays(A) + elif hasattr(A, "indices"): + A.indices = _safely_cast_index_arrays(A) + else: + A.row, A.col = _safely_cast_index_arrays(A) + elif A.format == "dia": + A.offsets = _safely_cast_index_arrays(A) + + +# TODO: remove when SciPy 1.15 is minimal supported version +# (based on scipy.sparse._sputils.py function with same name) +def _safely_cast_index_arrays(A, idx_dtype=np.int32, msg=""): + """Safely cast sparse array indices to `idx_dtype`. + + Check the shape of `A` to determine if it is safe to cast its index + arrays to dtype `idx_dtype`. If any dimension in shape is larger than + fits in the dtype, casting is unsafe so raise ``ValueError``. + If safe, cast the index arrays to `idx_dtype` and return the result + without changing the input `A`. The caller can assign results to `A` + attributes if desired or use the recast index arrays directly. + + Unless downcasting is needed, the original index arrays are returned. + You can test e.g. ``A.indptr is new_indptr`` to see if downcasting occurred. + + See SciPy: scipy.sparse._sputils.py for more info on safely_cast_index_arrays() + """ + max_value = np.iinfo(idx_dtype).max + + if A.format in ("csc", "csr"): + if A.indptr[-1] > max_value: + raise ValueError(f"indptr values too large for {msg}") + # check shape vs dtype + if max(*A.shape) > max_value: + if (A.indices > max_value).any(): + raise ValueError(f"indices values too large for {msg}") + + indices = A.indices.astype(idx_dtype, copy=False) + indptr = A.indptr.astype(idx_dtype, copy=False) + return indices, indptr + + elif A.format == "coo": + coords = getattr(A, "coords", None) + if coords is None: + coords = getattr(A, "indices", None) + if coords is None: + coords = (A.row, A.col) + if max(*A.shape) > max_value: + if any((co > max_value).any() for co in coords): + raise ValueError(f"coords values too large for {msg}") + return tuple(co.astype(idx_dtype, copy=False) for co in coords) + + elif A.format == "dia": + if max(*A.shape) > max_value: + if (A.offsets > max_value).any(): + raise ValueError(f"offsets values too large for {msg}") + offsets = A.offsets.astype(idx_dtype, copy=False) + return offsets + + elif A.format == "bsr": + R, C = A.blocksize + if A.indptr[-1] * R > max_value: + raise ValueError("indptr values too large for {msg}") + if max(*A.shape) > max_value: + if (A.indices * C > max_value).any(): + raise ValueError(f"indices values too large for {msg}") + indices = A.indices.astype(idx_dtype, copy=False) + indptr = A.indptr.astype(idx_dtype, copy=False) + return indices, indptr + # DOK and LIL formats are not associated with index arrays. diff --git a/sklearn/utils/graph.py b/sklearn/utils/graph.py index b28c2883e9499..cd68b4a5ad6ba 100644 --- a/sklearn/utils/graph.py +++ b/sklearn/utils/graph.py @@ -59,7 +59,7 @@ def single_source_shortest_path_length(graph, source, *, cutoff=None): if sparse.issparse(graph): graph = graph.tolil() else: - graph = sparse.lil_matrix(graph) + graph = sparse.lil_array(graph) seen = {} # level (number of hops) when seen in BFS level = 0 # the current level next_level = [source] # dict of nodes to check at next level diff --git a/sklearn/utils/random.py b/sklearn/utils/random.py index 4da8f26894aa6..20ab006d702de 100644 --- a/sklearn/utils/random.py +++ b/sklearn/utils/random.py @@ -10,6 +10,7 @@ from sklearn.utils import check_random_state from sklearn.utils._random import sample_without_replacement +from sklearn.utils._sparse import _align_api_if_sparse __all__ = ["sample_without_replacement"] @@ -98,4 +99,5 @@ def _random_choice_csc(n_samples, classes, class_probability=None, random_state= data.extend(classes[j][classes_j_nonzero][classes_ind]) indptr.append(len(indices)) - return sp.csc_matrix((data, indices, indptr), (n_samples, len(classes)), dtype=int) + csc = sp.csc_array((data, indices, indptr), (n_samples, len(classes)), dtype=int) + return _align_api_if_sparse(csc) diff --git a/sklearn/utils/sparsefuncs.py b/sklearn/utils/sparsefuncs.py index e7c00f9391dae..ce87313ada9b1 100644 --- a/sklearn/utils/sparsefuncs.py +++ b/sklearn/utils/sparsefuncs.py @@ -63,18 +63,18 @@ def inplace_csr_column_scale(X, scale): >>> indices = np.array([0, 1, 2, 2]) >>> data = np.array([8, 1, 2, 5]) >>> scale = np.array([2, 3, 2]) - >>> csr = sparse.csr_matrix((data, indices, indptr)) + >>> csr = sparse.csr_array((data, indices, indptr)) >>> csr.todense() - matrix([[8, 1, 2], - [0, 0, 5], - [0, 0, 0], - [0, 0, 0]]) + array([[8, 1, 2], + [0, 0, 5], + [0, 0, 0], + [0, 0, 0]]) >>> sparsefuncs.inplace_csr_column_scale(csr, scale) >>> csr.todense() - matrix([[16, 3, 4], - [ 0, 0, 10], - [ 0, 0, 0], - [ 0, 0, 0]]) + array([[16, 3, 4], + [ 0, 0, 10], + [ 0, 0, 0], + [ 0, 0, 0]]) """ assert scale.shape[0] == X.shape[1] X.data *= scale.take(X.indices, mode="clip") @@ -143,12 +143,12 @@ def mean_variance_axis(X, axis, weights=None, return_sum_weights=False): >>> indices = np.array([0, 1, 2, 2]) >>> data = np.array([8, 1, 2, 5]) >>> scale = np.array([2, 3, 2]) - >>> csr = sparse.csr_matrix((data, indices, indptr)) + >>> csr = sparse.csr_array((data, indices, indptr)) >>> csr.todense() - matrix([[8, 1, 2], - [0, 0, 5], - [0, 0, 0], - [0, 0, 0]]) + array([[8, 1, 2], + [0, 0, 5], + [0, 0, 0], + [0, 0, 0]]) >>> sparsefuncs.mean_variance_axis(csr, axis=0) (array([2. , 0.25, 1.75]), array([12. , 0.1875, 4.1875])) """ @@ -245,12 +245,12 @@ def incr_mean_variance_axis(X, *, axis, last_mean, last_var, last_n, weights=Non >>> indices = np.array([0, 1, 2, 2]) >>> data = np.array([8, 1, 2, 5]) >>> scale = np.array([2, 3, 2]) - >>> csr = sparse.csr_matrix((data, indices, indptr)) + >>> csr = sparse.csr_array((data, indices, indptr)) >>> csr.todense() - matrix([[8, 1, 2], - [0, 0, 5], - [0, 0, 0], - [0, 0, 0]]) + array([[8, 1, 2], + [0, 0, 5], + [0, 0, 0], + [0, 0, 0]]) >>> sparsefuncs.incr_mean_variance_axis( ... csr, axis=0, last_mean=np.zeros(3), last_var=np.zeros(3), last_n=2 ... ) @@ -315,18 +315,18 @@ def inplace_column_scale(X, scale): >>> indices = np.array([0, 1, 2, 2]) >>> data = np.array([8, 1, 2, 5]) >>> scale = np.array([2, 3, 2]) - >>> csr = sparse.csr_matrix((data, indices, indptr)) + >>> csr = sparse.csr_array((data, indices, indptr)) >>> csr.todense() - matrix([[8, 1, 2], - [0, 0, 5], - [0, 0, 0], - [0, 0, 0]]) + array([[8, 1, 2], + [0, 0, 5], + [0, 0, 0], + [0, 0, 0]]) >>> sparsefuncs.inplace_column_scale(csr, scale) >>> csr.todense() - matrix([[16, 3, 4], - [ 0, 0, 10], - [ 0, 0, 0], - [ 0, 0, 0]]) + array([[16, 3, 4], + [ 0, 0, 10], + [ 0, 0, 0], + [ 0, 0, 0]]) """ if sp.issparse(X) and X.format == "csc": inplace_csr_row_scale(X.T, scale) @@ -359,18 +359,18 @@ def inplace_row_scale(X, scale): >>> indices = np.array([0, 1, 2, 3, 3]) >>> data = np.array([8, 1, 2, 5, 6]) >>> scale = np.array([2, 3, 4, 5]) - >>> csr = sparse.csr_matrix((data, indices, indptr)) + >>> csr = sparse.csr_array((data, indices, indptr)) >>> csr.todense() - matrix([[8, 1, 0, 0], - [0, 0, 2, 0], - [0, 0, 0, 5], - [0, 0, 0, 6]]) + array([[8, 1, 0, 0], + [0, 0, 2, 0], + [0, 0, 0, 5], + [0, 0, 0, 6]]) >>> sparsefuncs.inplace_row_scale(csr, scale) >>> csr.todense() - matrix([[16, 2, 0, 0], - [ 0, 0, 6, 0], - [ 0, 0, 0, 20], - [ 0, 0, 0, 30]]) + array([[16, 2, 0, 0], + [ 0, 0, 6, 0], + [ 0, 0, 0, 20], + [ 0, 0, 0, 30]]) """ if sp.issparse(X) and X.format == "csc": inplace_csr_column_scale(X.T, scale) @@ -496,18 +496,18 @@ def inplace_swap_row(X, m, n): >>> indptr = np.array([0, 2, 3, 3, 3]) >>> indices = np.array([0, 2, 2]) >>> data = np.array([8, 2, 5]) - >>> csr = sparse.csr_matrix((data, indices, indptr)) + >>> csr = sparse.csr_array((data, indices, indptr)) >>> csr.todense() - matrix([[8, 0, 2], - [0, 0, 5], - [0, 0, 0], - [0, 0, 0]]) + array([[8, 0, 2], + [0, 0, 5], + [0, 0, 0], + [0, 0, 0]]) >>> sparsefuncs.inplace_swap_row(csr, 0, 1) >>> csr.todense() - matrix([[0, 0, 5], - [8, 0, 2], - [0, 0, 0], - [0, 0, 0]]) + array([[0, 0, 5], + [8, 0, 2], + [0, 0, 0], + [0, 0, 0]]) """ if sp.issparse(X) and X.format == "csc": inplace_swap_row_csc(X, m, n) @@ -541,18 +541,18 @@ def inplace_swap_column(X, m, n): >>> indptr = np.array([0, 2, 3, 3, 3]) >>> indices = np.array([0, 2, 2]) >>> data = np.array([8, 2, 5]) - >>> csr = sparse.csr_matrix((data, indices, indptr)) + >>> csr = sparse.csr_array((data, indices, indptr)) >>> csr.todense() - matrix([[8, 0, 2], - [0, 0, 5], - [0, 0, 0], - [0, 0, 0]]) + array([[8, 0, 2], + [0, 0, 5], + [0, 0, 0], + [0, 0, 0]]) >>> sparsefuncs.inplace_swap_column(csr, 0, 1) >>> csr.todense() - matrix([[0, 8, 2], - [0, 0, 5], - [0, 0, 0], - [0, 0, 0]]) + array([[0, 8, 2], + [0, 0, 5], + [0, 0, 0], + [0, 0, 0]]) """ if m < 0: m += X.shape[1] diff --git a/sklearn/utils/sparsefuncs_fast.pyx b/sklearn/utils/sparsefuncs_fast.pyx index 2859b4d127f11..cf4bdf4b9d946 100644 --- a/sklearn/utils/sparsefuncs_fast.pyx +++ b/sklearn/utils/sparsefuncs_fast.pyx @@ -8,6 +8,7 @@ from libc.stdint cimport intptr_t import numpy as np from cython cimport floating +from sklearn.utils.fixes import _ensure_sparse_index_int32 from sklearn.utils._typedefs cimport float64_t, int32_t, int64_t, intp_t, uint64_t @@ -371,6 +372,7 @@ def incr_mean_variance_axis0(X, last_mean, last_var, last_n, weights=None): if last_n.dtype not in [np.float32, np.float64]: last_n = last_n.astype(np.float64, copy=False) + _ensure_sparse_index_int32(X) return _incr_mean_variance_axis0(X.data, np.sum(weights), X.shape[1], @@ -491,13 +493,13 @@ def inplace_csr_row_normalize_l1(X): Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from sklearn.utils.sparsefuncs_fast import inplace_csr_row_normalize_l1 >>> import numpy as np >>> indptr = np.array([0, 2, 3, 4]) >>> indices = np.array([0, 1, 2, 3]) >>> data = np.array([1.0, 2.0, 3.0, 4.0]) - >>> X = csr_matrix((data, indices, indptr), shape=(3, 4)) + >>> X = csr_array((data, indices, indptr), shape=(3, 4)) >>> X.toarray() array([[1., 2., 0., 0.], [0., 0., 3., 0.], @@ -553,13 +555,13 @@ def inplace_csr_row_normalize_l2(X): Examples -------- - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> from sklearn.utils.sparsefuncs_fast import inplace_csr_row_normalize_l2 >>> import numpy as np >>> indptr = np.array([0, 2, 3, 4]) >>> indices = np.array([0, 1, 2, 3]) >>> data = np.array([1.0, 2.0, 3.0, 4.0]) - >>> X = csr_matrix((data, indices, indptr), shape=(3, 4)) + >>> X = csr_array((data, indices, indptr), shape=(3, 4)) >>> X.toarray() array([[1., 2., 0., 0.], [0., 0., 3., 0.], @@ -615,7 +617,7 @@ def assign_rows_csr( Parameters ---------- - X : scipy.sparse.csr_matrix, shape=(n_samples, n_features) + X : scipy.sparse.csr_array, shape=(n_samples, n_features) X_rows : array, dtype=np.intp, shape=n_rows out_rows : array, dtype=np.intp, shape=n_rows out : array, shape=(arbitrary, n_features) diff --git a/sklearn/utils/tests/test_estimator_checks.py b/sklearn/utils/tests/test_estimator_checks.py index a3c40d8ae4457..3e261f1648e01 100644 --- a/sklearn/utils/tests/test_estimator_checks.py +++ b/sklearn/utils/tests/test_estimator_checks.py @@ -113,6 +113,14 @@ def _mark_thread_unsafe_if_pytest_imported(f): return f +def _mark_no_check_spmatrix_if_pytest_imported(f): + pytest = sys.modules.get("pytest") + if pytest is not None: + return pytest.mark.no_check_spmatrix + else: + return f + + class CorrectNotFittedError(ValueError): """Exception class to raise if estimator is used before fitting. @@ -808,6 +816,7 @@ def test_check_estimator_not_fail_fast(): assert any(item["status"] == "passed" for item in check_results) +@_mark_no_check_spmatrix_if_pytest_imported # pickle breaks check_spmatrix # Some estimator checks rely on warnings in deep functions calls. This is not # automatically detected by pytest-run-parallel shallow AST inspection, so we # need to mark the test function as thread-unsafe. @@ -912,6 +921,7 @@ def test_check_estimator_transformer_no_mixin(): check_estimator(BadTransformerWithoutMixin()) +@_mark_no_check_spmatrix_if_pytest_imported # pickle breaks check_spmatrix def test_check_estimator_clones(): # check that check_estimator doesn't modify the estimator it receives diff --git a/sklearn/utils/tests/test_extmath.py b/sklearn/utils/tests/test_extmath.py index 5f3627972346f..d506c7ced2524 100644 --- a/sklearn/utils/tests/test_extmath.py +++ b/sklearn/utils/tests/test_extmath.py @@ -56,6 +56,7 @@ DOK_CONTAINERS, LIL_CONTAINERS, _mode, + _sparse_random_array, ) @@ -512,7 +513,7 @@ def test_randomized_svd_sparse_warnings(sparse_container): X = sparse_container(X) warn_msg = ( - "Calculating SVD of a {} is expensive. csr_matrix is more efficient.".format( + "Calculating SVD of a {} is expensive. CSR format is more efficient.".format( sparse_container.__name__ ) ) @@ -1072,8 +1073,8 @@ def test_safe_sparse_dot_2d_1d(container): def test_safe_sparse_dot_dense_output(dense_output): rng = np.random.RandomState(0) - A = sparse.random(30, 10, density=0.1, random_state=rng) - B = sparse.random(10, 20, density=0.1, random_state=rng) + A = _sparse_random_array((30, 10), density=0.1, rng=rng) + B = _sparse_random_array((10, 20), density=0.1, rng=rng) expected = A.dot(B) actual = safe_sparse_dot(A, B, dense_output=dense_output) diff --git a/sklearn/utils/tests/test_fixes.py b/sklearn/utils/tests/test_fixes.py index 2aa370df705a3..5fc5e415d0145 100644 --- a/sklearn/utils/tests/test_fixes.py +++ b/sklearn/utils/tests/test_fixes.py @@ -3,9 +3,14 @@ import numpy as np import pytest +import scipy as sp from sklearn.utils._testing import assert_array_equal -from sklearn.utils.fixes import _object_dtype_isnan, _smallest_admissible_index_dtype +from sklearn.utils.fixes import ( + _ensure_sparse_index_int32, + _object_dtype_isnan, + _smallest_admissible_index_dtype, +) @pytest.mark.parametrize("dtype, val", ([object, 1], [object, "a"], [float, 1])) @@ -158,3 +163,40 @@ def test_smallest_admissible_index_dtype_error(params, err_type, err_msg): """Check that we raise the proper error message.""" with pytest.raises(err_type, match=err_msg): _smallest_admissible_index_dtype(**params) + + +INDEX_CONSTRUCTORS = [ + sp.sparse.csc_array, + sp.sparse.csr_array, + sp.sparse.coo_array, + sp.sparse.csc_matrix, + sp.sparse.csr_matrix, + sp.sparse.coo_matrix, +] +NO_INDEX_TEST_CONSTRUCTORS = [ + sp.sparse.bsr_array, + sp.sparse.bsr_matrix, + sp.sparse.dia_array, + sp.sparse.dok_array, + sp.sparse.lil_array, + sp.sparse.dia_matrix, + sp.sparse.dok_matrix, + sp.sparse.lil_matrix, +] +SPARSE_CONSTRUCTORS = INDEX_CONSTRUCTORS + NO_INDEX_TEST_CONSTRUCTORS + + +@pytest.mark.parametrize("constructor", SPARSE_CONSTRUCTORS) +def test_ensure_sparse_index_int32(constructor): + A = constructor(np.array([[1.0, 2.0, 3.0], [3.0, 2.0, 1.0]])) + _ensure_sparse_index_int32(A) + + +@pytest.mark.parametrize("constructor", INDEX_CONSTRUCTORS) +def test_ensure_int32_raises(constructor): + with pytest.raises(ValueError, match="too large"): + rows, cols = [2, 0], [1, np.iinfo(np.int32).max + 1] + if "csc" in constructor.__name__: + rows, cols = cols, rows + A = sp.sparse.coo_array(([1.0, 2.0], (rows, cols))) + _ensure_sparse_index_int32(constructor(A)) diff --git a/sklearn/utils/tests/test_param_validation.py b/sklearn/utils/tests/test_param_validation.py index a47eaace5b9a2..06bd866eac9fc 100644 --- a/sklearn/utils/tests/test_param_validation.py +++ b/sklearn/utils/tests/test_param_validation.py @@ -2,7 +2,7 @@ import numpy as np import pytest -from scipy.sparse import csr_matrix +from scipy.sparse import csr_array, csr_matrix from sklearn._config import config_context, get_config from sklearn.base import BaseEstimator, _fit_context @@ -406,6 +406,7 @@ def test_generate_valid_param(constraint): ("array-like", [[1, 2], [3, 4]]), ("array-like", np.array([[1, 2], [3, 4]])), ("sparse matrix", csr_matrix([[1, 2], [3, 4]])), + ("sparse matrix", csr_array([[1, 2], [3, 4]])), *[ ("sparse matrix", container([[1, 2], [3, 4]])) for container in CSR_CONTAINERS diff --git a/sklearn/utils/tests/test_sparse.py b/sklearn/utils/tests/test_sparse.py new file mode 100644 index 0000000000000..32d6a1666d493 --- /dev/null +++ b/sklearn/utils/tests/test_sparse.py @@ -0,0 +1,78 @@ +import numpy as np +import pytest +from scipy.sparse import csc_array, csc_matrix, csr_array, csr_matrix + +import sklearn + + +@pytest.mark.parametrize( + ["sparse_interface", "x", "result_type"], + [ + ("sparray", csr_array([[1, 2, 3]]), csr_array), + ("sparray", csr_matrix([[1, 2, 3]]), csr_array), + ("sparray", csc_array([[1, 2, 3]]), csc_array), + ("sparray", csc_matrix([[1, 2, 3]]), csc_array), + ("spmatrix", csr_array([[1, 2, 3]]), csr_matrix), + ("spmatrix", csr_matrix([[1, 2, 3]]), csr_matrix), + ("spmatrix", csc_array([[1, 2, 3]]), csc_matrix), + ("spmatrix", csc_matrix([[1, 2, 3]]), csc_matrix), + ], +) +def test_align_api_if_sparse(sparse_interface, x, result_type): + with sklearn.config_context(sparse_interface=sparse_interface): + result = sklearn.utils._align_api_if_sparse(x) + assert isinstance(result, result_type) + + +@pytest.mark.parametrize( + ["sparse_interface", "x", "result_type"], + [ + ("sparray", np.array([[1, 2, 3]]), np.ndarray), + ("spmatrix", np.array([[1, 2, 3]]), np.ndarray), + ], +) +def test_ndarray_align_api_if_sparse(sparse_interface, x, result_type): + with sklearn.config_context(sparse_interface=sparse_interface): + result = sklearn.utils._align_api_if_sparse(x) + assert isinstance(result, result_type) + + +@pytest.mark.parametrize( + ["sparse_interface", "result_type"], + [("sparray", csr_array), ("spmatrix", csr_matrix)], +) +def test_transform_returns_sparse(sparse_interface, result_type): + corpus = [ + "This is the first document.", + "This document is the second document.", + "And this is the third one.", + "Is this the first document?", + ] + with sklearn.config_context(sparse_interface=sparse_interface): + vectorizer = sklearn.feature_extraction.text.CountVectorizer() + X = vectorizer.fit_transform(corpus) + assert isinstance(X, result_type) + + +@pytest.mark.parametrize( + ["sparse_interface", "result_type"], + [("sparray", csr_array), ("spmatrix", csr_matrix)], +) +def test_function_returns_sparse(sparse_interface, result_type): + with sklearn.config_context(sparse_interface=sparse_interface): + X, y = sklearn.datasets.make_regression(n_features=2, random_state=0) + X = sklearn.manifold._locally_linear.barycenter_kneighbors_graph(X, 1) + assert isinstance(X, result_type) + + +@pytest.mark.parametrize( + ["sparse_interface", "result_type"], + [("sparray", csr_array), ("spmatrix", csr_matrix)], +) +def test_estimator_property_sparse(sparse_interface, result_type): + with sklearn.config_context(sparse_interface=sparse_interface): + X, y = sklearn.datasets.make_regression(n_features=2, random_state=0) + regr = sklearn.linear_model.ElasticNet(random_state=0) + regr.fit(X, y) + # check spec_coeff property + assert isinstance(regr.sparse_coef_, result_type) diff --git a/sklearn/utils/tests/test_sparsefuncs.py b/sklearn/utils/tests/test_sparsefuncs.py index 2753f48647a0c..2dff80f8e9ac1 100644 --- a/sklearn/utils/tests/test_sparsefuncs.py +++ b/sklearn/utils/tests/test_sparsefuncs.py @@ -7,7 +7,12 @@ from sklearn.datasets import make_classification from sklearn.utils._testing import assert_allclose -from sklearn.utils.fixes import CSC_CONTAINERS, CSR_CONTAINERS, LIL_CONTAINERS +from sklearn.utils.fixes import ( + CSC_CONTAINERS, + CSR_CONTAINERS, + LIL_CONTAINERS, + _sparse_random_array, +) from sklearn.utils.sparsefuncs import ( _implicit_column_offset, count_nonzero, @@ -437,15 +442,15 @@ def test_incr_mean_variance_axis_dim_mismatch(sparse_constructor): "X1, X2", [ ( - sp.random(5, 2, density=0.8, format="csr", random_state=0), - sp.random(13, 2, density=0.8, format="csr", random_state=0), + _sparse_random_array((5, 2), density=0.8, format="csr", rng=0), + _sparse_random_array((13, 2), density=0.8, format="csr", rng=0), ), ( - sp.random(5, 2, density=0.8, format="csr", random_state=0), + _sparse_random_array((5, 2), density=0.8, format="csr", rng=0), sp.hstack( [ np.full((13, 1), fill_value=np.nan), - sp.random(13, 1, density=0.8, random_state=42), + _sparse_random_array((13, 1), density=0.8, rng=42), ], format="csr", ), @@ -478,8 +483,8 @@ def test_incr_mean_variance_axis_equivalence_mean_variance(X1, X2, csr_container def test_incr_mean_variance_no_new_n(): # check the behaviour when we update the variance with an empty matrix axis = 0 - X1 = sp.random(5, 1, density=0.8, random_state=0).tocsr() - X2 = sp.random(0, 1, density=0.8, random_state=0).tocsr() + X1 = _sparse_random_array((5, 1), density=0.8, format="csr", rng=0) + X2 = _sparse_random_array((0, 1), density=0.8, format="csr", rng=0) last_mean, last_var = np.zeros(X1.shape[1]), np.zeros(X1.shape[1]) last_n = np.zeros(X1.shape[1], dtype=np.int64) last_mean, last_var, last_n = incr_mean_variance_axis( @@ -497,7 +502,7 @@ def test_incr_mean_variance_no_new_n(): def test_incr_mean_variance_n_float(): # check the behaviour when last_n is just a number axis = 0 - X = sp.random(5, 2, density=0.8, random_state=0).tocsr() + X = _sparse_random_array((5, 2), density=0.8, format="csr", rng=0) last_mean, last_var = np.zeros(X.shape[1]), np.zeros(X.shape[1]) last_n = 0 _, _, new_n = incr_mean_variance_axis( @@ -605,7 +610,7 @@ def test_densify_rows(csr_container): def test_inplace_column_scale(): rng = np.random.RandomState(0) - X = sp.random(100, 200, density=0.05) + X = _sparse_random_array((100, 200), density=0.05) Xr = X.tocsr() Xc = X.tocsc() XA = X.toarray() @@ -637,7 +642,7 @@ def test_inplace_column_scale(): def test_inplace_row_scale(): rng = np.random.RandomState(0) - X = sp.random(100, 200, density=0.05) + X = _sparse_random_array((100, 200), density=0.05) Xr = X.tocsr() Xc = X.tocsc() XA = X.toarray() @@ -910,7 +915,7 @@ def test_csc_row_median(csc_container, csr_container): ) @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) def test_inplace_normalize(csr_container, inplace_csr_row_normalize): - if csr_container is sp.csr_matrix: + if issubclass(sp.csr_matrix, csr_container): ones = np.ones((10, 1)) else: ones = np.ones(10) @@ -938,7 +943,7 @@ def test_inplace_normalize(csr_container, inplace_csr_row_normalize): def test_csr_row_norms(dtype): # checks that csr_row_norms returns the same output as # scipy.sparse.linalg.norm, and that the dype is the same as X.dtype. - X = sp.random(100, 10, format="csr", dtype=dtype, random_state=42) + X = _sparse_random_array((100, 10), format="csr", dtype=dtype, rng=42) scipy_norms = sp.linalg.norm(X, axis=1) ** 2 norms = csr_row_norms(X) @@ -953,10 +958,10 @@ def centered_matrices(request): """Returns equivalent tuple[sp.linalg.LinearOperator, np.ndarray].""" sparse_container = request.param - random_state = np.random.default_rng(42) + rng = np.random.default_rng(42) X_sparse = sparse_container( - sp.random(500, 100, density=0.1, format="csr", random_state=random_state) + _sparse_random_array((500, 100), density=0.1, format="csr", rng=rng) ) X_dense = X_sparse.toarray() mu = np.asarray(X_sparse.mean(axis=0)).ravel() diff --git a/sklearn/utils/tests/test_testing.py b/sklearn/utils/tests/test_testing.py index cc0094cf53f18..fdd197712cf48 100644 --- a/sklearn/utils/tests/test_testing.py +++ b/sklearn/utils/tests/test_testing.py @@ -30,6 +30,8 @@ _IS_WASM, CSC_CONTAINERS, CSR_CONTAINERS, + _sparse_diags_array, + _sparse_random_array, ) from sklearn.utils.metaestimators import available_if @@ -57,7 +59,7 @@ def test_assert_allclose_dense_sparse(csr_container): with pytest.raises(ValueError, match="Can only compare two sparse"): assert_allclose_dense_sparse(x, y) - A = sparse.diags(np.ones(5), offsets=0).tocsr() + A = _sparse_diags_array(np.ones(5), offsets=0, format="csr") B = csr_container(np.ones((1, 5))) with pytest.raises(AssertionError, match="Arrays are not equal"): assert_allclose_dense_sparse(B, A) @@ -1102,7 +1104,7 @@ def test_convert_container_sparse_to_sparse(constructor_name): """Non-regression test to check that we can still convert a sparse container from a given format to another format. """ - X_sparse = sparse.random(10, 10, density=0.1, format="csr") + X_sparse = _sparse_random_array((10, 10), density=0.1, format="csr") _convert_container(X_sparse, constructor_name) diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 19d1ca5e5f3e9..9bbf02ba9228d 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -61,6 +61,7 @@ CSR_CONTAINERS, DIA_CONTAINERS, DOK_CONTAINERS, + _sparse_random_array, ) from sklearn.utils.validation import ( FLOAT_DTYPES, @@ -144,6 +145,7 @@ def test_as_float_array(): # Test the copy parameter with some matrices matrices = [ sp.csc_matrix(np.arange(5)).toarray(), + sp.csc_array([np.arange(5)]).toarray(), _sparse_random_matrix(10, 10, density=0.10).toarray(), ] for M in matrices: @@ -153,7 +155,7 @@ def test_as_float_array(): @pytest.mark.parametrize( - "X", [np.random.random((10, 2)), sp.random(10, 2, format="csr")] + "X", [np.random.random((10, 2)), _sparse_random_array((10, 2), format="csr")] ) def test_as_float_array_nan(X): X = X.copy() @@ -169,6 +171,7 @@ def test_np_matrix(): assert not isinstance(as_float_array(X), np.matrix) assert not isinstance(as_float_array(sp.csc_matrix(X)), np.matrix) + assert not isinstance(as_float_array(sp.csc_array(X)), np.matrix) def test_memmap(): @@ -201,7 +204,7 @@ def test_ordering(): if copy: assert A is not B - X = sp.csr_matrix(X) + X = sp.csr_array(X) X.data = X.data[::-1] assert not X.data.flags["C_CONTIGUOUS"] @@ -210,7 +213,7 @@ def test_ordering(): "value, ensure_all_finite", [(np.inf, False), (np.nan, "allow-nan"), (np.nan, False)], ) -@pytest.mark.parametrize("retype", [np.asarray, sp.csr_matrix]) +@pytest.mark.parametrize("retype", [np.asarray, sp.csr_array, sp.csr_matrix]) def test_check_array_ensure_all_finite_valid(value, ensure_all_finite, retype): X = retype(np.arange(4).reshape(2, 2).astype(float)) X[0, 0] = value @@ -237,7 +240,7 @@ def test_check_array_ensure_all_finite_valid(value, ensure_all_finite, retype): (np.nan, "", 1, "Input contains NaN"), ], ) -@pytest.mark.parametrize("retype", [np.asarray, sp.csr_matrix]) +@pytest.mark.parametrize("retype", [np.asarray, sp.csr_array, sp.csr_matrix]) def test_check_array_ensure_all_finite_invalid( value, input_name, ensure_all_finite, match_msg, retype ): @@ -253,7 +256,7 @@ def test_check_array_ensure_all_finite_invalid( @pytest.mark.parametrize("input_name", ["X", "y", "sample_weight"]) -@pytest.mark.parametrize("retype", [np.asarray, sp.csr_matrix]) +@pytest.mark.parametrize("retype", [np.asarray, sp.csr_array, sp.csr_matrix]) def test_check_array_links_to_imputer_doc_only_for_X(input_name, retype): data = retype(np.arange(4).reshape(2, 2).astype(np.float64)) data[0, 0] = np.nan @@ -355,7 +358,7 @@ def test_check_array(): # accept_sparse == False # raise error on sparse inputs X = [[1, 2], [3, 4]] - X_csr = sp.csr_matrix(X) + X_csr = sp.csr_array(X) with pytest.raises(TypeError): check_array(X_csr) @@ -619,9 +622,9 @@ def test_check_array_dtype_warning(): X_int_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] X_float32 = np.asarray(X_int_list, dtype=np.float32) X_int64 = np.asarray(X_int_list, dtype=np.int64) - X_csr_float32 = sp.csr_matrix(X_float32) - X_csc_float32 = sp.csc_matrix(X_float32) - X_csc_int32 = sp.csc_matrix(X_int64, dtype=np.int32) + X_csr_float32 = sp.csr_array(X_float32) + X_csc_float32 = sp.csc_array(X_float32) + X_csc_int32 = sp.csc_array(X_int64, dtype=np.int32) integer_data = [X_int64, X_csc_int32] float32_data = [X_float32, X_csr_float32, X_csc_float32] with warnings.catch_warnings(): @@ -660,7 +663,7 @@ def test_check_array_dtype_warning(): def test_check_array_accept_sparse_type_exception(): X = [[1, 2], [3, 4]] - X_csr = sp.csr_matrix(X) + X_csr = sp.csr_array(X) invalid_type = SVR() msg = ( @@ -691,7 +694,7 @@ def test_check_array_accept_sparse_type_exception(): def test_check_array_accept_sparse_no_exception(): X = [[1, 2], [3, 4]] - X_csr = sp.csr_matrix(X) + X_csr = sp.csr_array(X) check_array(X_csr, accept_sparse=True) check_array(X_csr, accept_sparse="csr") @@ -701,7 +704,7 @@ def test_check_array_accept_sparse_no_exception(): @pytest.fixture(params=["csr", "csc", "coo", "bsr"]) def X_64bit(request): - X = sp.random(20, 10, format=request.param) + X = _sparse_random_array((20, 10), format=request.param) if request.param == "coo": if hasattr(X, "coords"): @@ -831,7 +834,7 @@ def test_check_array_complex_data_error(): check_array(X) # sparse matrix - X = sp.coo_matrix([[0, 1 + 2j], [0, 0]]) + X = sp.coo_array([[0, 1 + 2j], [0, 0]]) with pytest.raises(ValueError, match="Complex data not supported"): check_array(X) @@ -865,12 +868,12 @@ def test_check_symmetric(): test_arrays = { "dense": arr_asym, - "dok": sp.dok_matrix(arr_asym), - "csr": sp.csr_matrix(arr_asym), - "csc": sp.csc_matrix(arr_asym), - "coo": sp.coo_matrix(arr_asym), - "lil": sp.lil_matrix(arr_asym), - "bsr": sp.bsr_matrix(arr_asym), + "dok": sp.dok_array(arr_asym), + "csr": sp.csr_array(arr_asym), + "csc": sp.csc_array(arr_asym), + "coo": sp.coo_array(arr_asym), + "lil": sp.lil_array(arr_asym), + "bsr": sp.bsr_array(arr_asym), } # check error for bad inputs @@ -1018,7 +1021,7 @@ def test_check_consistent_length(): input types trigger TypeErrors.""" check_consistent_length([1], [2], [3], [4], [5]) check_consistent_length([[1, 2], [[1, 2]]], [1, 2], ["a", "b"]) - check_consistent_length([1], (2,), np.array([3]), sp.csr_matrix((1, 2))) + check_consistent_length([1], (2,), np.array([3]), sp.csr_array((1, 2))) with pytest.raises(ValueError, match="inconsistent numbers of samples"): check_consistent_length([1, 2], [1]) with pytest.raises(TypeError, match=r"got <\w+ 'int'>"): @@ -1296,6 +1299,13 @@ class MockEstimator: sp.bsr_matrix, sp.dok_matrix, sp.dia_matrix, + sp.csr_array, + sp.csc_array, + sp.coo_array, + sp.lil_array, + sp.bsr_array, + sp.dok_array, + sp.dia_array, ], ) def test_check_non_negative(retype): @@ -1712,21 +1722,24 @@ def test_check_pos_label_consistency_invalid_array_api( assert _check_pos_label_consistency("a", arr) == "a" -@pytest.mark.parametrize("toarray", [np.array, sp.csr_matrix, sp.csc_matrix]) +CS_SPARSE = [sp.csr_array, sp.csr_matrix, sp.csc_array, sp.csc_matrix] + + +@pytest.mark.parametrize("toarray", [np.array] + CS_SPARSE) def test_allclose_dense_sparse_equals(toarray): base = np.arange(9).reshape(3, 3) x, y = toarray(base), toarray(base) assert _allclose_dense_sparse(x, y) -@pytest.mark.parametrize("toarray", [np.array, sp.csr_matrix, sp.csc_matrix]) +@pytest.mark.parametrize("toarray", [np.array] + CS_SPARSE) def test_allclose_dense_sparse_not_equals(toarray): base = np.arange(9).reshape(3, 3) x, y = toarray(base), toarray(base + 1) assert not _allclose_dense_sparse(x, y) -@pytest.mark.parametrize("toarray", [sp.csr_matrix, sp.csc_matrix]) +@pytest.mark.parametrize("toarray", CS_SPARSE) def test_allclose_dense_sparse_raise(toarray): x = np.arange(9).reshape(3, 3) y = toarray(x + 1) @@ -1804,8 +1817,10 @@ def test_check_method_params(indices): _params = { "list": [1, 2, 3, 4], "array": np.array([1, 2, 3, 4]), - "sparse-col": sp.csc_matrix([1, 2, 3, 4]).T, - "sparse-row": sp.csc_matrix([1, 2, 3, 4]), + "sparse-col2": sp.csc_matrix([[1, 2, 3, 4]]).T, + "sparse-row2": sp.csc_matrix([[1, 2, 3, 4]]), + "sparse-col": sp.csc_array([[1, 2, 3, 4]]).T, + "sparse-row": sp.csc_array([[1, 2, 3, 4]]), "scalar-int": 1, "scalar-str": "xxx", "None": None, @@ -1813,7 +1828,7 @@ def test_check_method_params(indices): result = _check_method_params(X, params=_params, indices=indices) indices_ = indices if indices is not None else list(range(X.shape[0])) - for key in ["sparse-row", "scalar-int", "scalar-str", "None"]: + for key in ["sparse-row", "sparse-row2", "scalar-int", "scalar-str", "None"]: assert result[key] is _params[key] assert result["list"] == _safe_indexing(_params["list"], indices_) @@ -1821,6 +1836,9 @@ def test_check_method_params(indices): assert_allclose_dense_sparse( result["sparse-col"], _safe_indexing(_params["sparse-col"], indices_) ) + assert_allclose_dense_sparse( + result["sparse-col2"], _safe_indexing(_params["sparse-col2"], indices_) + ) @pytest.mark.parametrize("sp_format", [True, "csr", "csc", "coo", "bsr"]) diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index 7b39ef4952169..3ea39c38a025f 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -508,10 +508,10 @@ def indexable(*iterables): Examples -------- >>> from sklearn.utils import indexable - >>> from scipy.sparse import csr_matrix + >>> from scipy.sparse import csr_array >>> import numpy as np >>> iterables = [ - ... [1, 2, 3], np.array([2, 3, 4]), None, csr_matrix([[5], [6], [7]]) + ... [1, 2, 3], np.array([2, 3, 4]), None, csr_array([[5], [6], [7]]) ... ] >>> indexable(*iterables) [[1, 2, 3], array([2, 3, 4]), None, <...Sparse...dtype 'int64'...shape (3, 1)>] @@ -570,6 +570,10 @@ def _ensure_sparse_format( .. versionchanged:: 0.23 Accepts `pd.NA` and converts it into `np.nan` + accept_large_sparse : bool + If a CSR, CSC, COO or BSR sparse matrix is supplied and accepted by + accept_sparse, accept_large_sparse will cause it to be accepted only + if its indices are stored with a 32-bit dtype. estimator_name : str, default=None The estimator name, used to construct the error message. @@ -1540,10 +1544,10 @@ def check_symmetric(array, *, tol=1e-10, raise_warning=True, raise_exception=Fal array([[0, 1, 2], [1, 0, 1], [2, 1, 0]]) - >>> from scipy.sparse import csr_matrix - >>> sparse_symmetric_array = csr_matrix(symmetric_array) + >>> from scipy.sparse import csr_array + >>> sparse_symmetric_array = csr_array(symmetric_array) >>> check_symmetric(sparse_symmetric_array) - <Compressed Sparse Row sparse matrix of dtype 'int64' + <Compressed Sparse Row sparse array of dtype 'int64' with 6 stored elements and shape (3, 3)> """ if (array.ndim != 2) or (array.shape[0] != array.shape[1]): From 370e7f0f2614b5e9fb43a4d1e8aa788e9dd27a85 Mon Sep 17 00:00:00 2001 From: Tim Head <betatim@gmail.com> Date: Wed, 11 Mar 2026 13:24:10 +0100 Subject: [PATCH 273/462] Mixed array namespace input for `mean_absolute_error`, `mean_squared_error`, `root_mean_squared_error`, `mean_pinball_loss`, `mean_absolute_percentage_error` (#33511) --- sklearn/metrics/_regression.py | 17 ++++++++++------- sklearn/metrics/tests/test_common.py | 5 +++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index 007c192e424a2..ed9e2683063fe 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -278,7 +278,8 @@ def mean_absolute_error( >>> mean_absolute_error(y_true, y_pred, multioutput=[0.3, 0.7]) 0.85... """ - xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) + xp, _, device = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_with_floating_dtype( @@ -377,7 +378,8 @@ def mean_pinball_loss( >>> mean_pinball_loss(y_true, y_true, alpha=0.9) 0.0 """ - xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) + xp, _, device = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_with_floating_dtype( @@ -482,9 +484,8 @@ def mean_absolute_percentage_error( >>> mean_absolute_percentage_error(y_true, y_pred) 112589990684262.48 """ - xp, _, device_ = get_namespace_and_device( - y_true, y_pred, sample_weight, multioutput - ) + xp, _, device_ = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device_) _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp @@ -575,7 +576,8 @@ def mean_squared_error( >>> mean_squared_error(y_true, y_pred, multioutput=[0.3, 0.7]) 0.825... """ - xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) + xp, _, device = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp @@ -661,7 +663,8 @@ def root_mean_squared_error( 0.822... """ - xp, _ = get_namespace(y_true, y_pred, sample_weight, multioutput) + xp, _, device = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) output_errors = xp.sqrt( mean_squared_error( diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index a05d39950d185..cc4da3146c816 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -628,6 +628,11 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "d2_log_loss_score", "log_loss", "max_error", + "mean_absolute_error", + "mean_absolute_percentage_error", + "mean_pinball_loss", + "mean_squared_error", + "root_mean_squared_error", ] From 3bbf8d9c238f46a4ba5b08e662f57cd53f101149 Mon Sep 17 00:00:00 2001 From: Tim Head <betatim@gmail.com> Date: Wed, 11 Mar 2026 14:11:24 +0100 Subject: [PATCH 274/462] Mixed array namespace input for `explained_variance_score`, `mean_squared_log_error`, `median_absolute_error`, `r2_score`, `root_mean_squared_log_error` (#33515) --- sklearn/metrics/_regression.py | 19 +++++++++++-------- sklearn/metrics/tests/test_common.py | 5 +++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index ed9e2683063fe..ed4c2d6223d68 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -755,7 +755,8 @@ def mean_squared_log_error( >>> mean_squared_log_error(y_true, y_pred, multioutput=[0.3, 0.7]) 0.060... """ - xp, _ = get_namespace(y_true, y_pred) + xp, _, device = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_with_floating_dtype( @@ -833,7 +834,8 @@ def root_mean_squared_log_error( >>> root_mean_squared_log_error(y_true, y_pred) 0.199... """ - xp, _ = get_namespace(y_true, y_pred) + xp, _, device = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_with_floating_dtype( @@ -920,9 +922,10 @@ def median_absolute_error( >>> median_absolute_error(y_true, y_pred, multioutput=[0.3, 0.7]) 0.85 """ - xp, _ = get_namespace(y_true, y_pred, multioutput, sample_weight) + xp, _, device = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) _, y_true, y_pred, sample_weight, multioutput = _check_reg_targets( - y_true, y_pred, sample_weight, multioutput + y_true, y_pred, sample_weight, multioutput, xp=xp ) if sample_weight is None: output_errors = _median(xp.abs(y_pred - y_true), axis=0) @@ -1107,7 +1110,8 @@ def explained_variance_score( >>> explained_variance_score(y_true, y_pred, force_finite=False) -inf """ - xp, _, device = get_namespace_and_device(y_true, y_pred, sample_weight, multioutput) + xp, _, device = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_with_floating_dtype( @@ -1277,9 +1281,8 @@ def r2_score( >>> r2_score(y_true, y_pred, force_finite=False) -inf """ - xp, _, device_ = get_namespace_and_device( - y_true, y_pred, sample_weight, multioutput - ) + xp, _, device_ = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device_) _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_with_floating_dtype( diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index cc4da3146c816..40f6badf37366 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -626,13 +626,18 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "confusion_matrix_at_thresholds", "d2_brier_score", "d2_log_loss_score", + "explained_variance_score", "log_loss", "max_error", "mean_absolute_error", "mean_absolute_percentage_error", "mean_pinball_loss", "mean_squared_error", + "mean_squared_log_error", + "median_absolute_error", + "r2_score", "root_mean_squared_error", + "root_mean_squared_log_error", ] From 08f9b20d69a787a5a1e06e0ba6dd8693aeb5d223 Mon Sep 17 00:00:00 2001 From: Arthur Lacote <arthur.lcte@gmail.com> Date: Wed, 11 Mar 2026 14:33:18 +0100 Subject: [PATCH 275/462] TST Remove call to `np.random.randint` in `test_missing_values_is_resilient` (#33518) --- sklearn/ensemble/tests/test_forest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/ensemble/tests/test_forest.py b/sklearn/ensemble/tests/test_forest.py index 7a0b27b66b327..ca2a4d102a844 100644 --- a/sklearn/ensemble/tests/test_forest.py +++ b/sklearn/ensemble/tests/test_forest.py @@ -1843,7 +1843,7 @@ def test_estimators_samples(ForestClass, bootstrap, seed): ) def test_missing_values_is_resilient(Forest, criterion): """Check that forest can deal with missing values and has decent performance.""" - rng = np.random.RandomState(np.random.randint(0, 100000)) + rng = np.random.RandomState(0) n_samples, n_features = 500, 5 make_data = make_regression if criterion in REG_CRITERIONS else make_classification X, y = make_data(n_samples=n_samples, n_features=n_features, random_state=rng) From e3930505a79d6c1e59f2d77712fac5f7bd05b713 Mon Sep 17 00:00:00 2001 From: Dan Schult <dschult@colgate.edu> Date: Wed, 11 Mar 2026 12:37:24 -0400 Subject: [PATCH 276/462] MNT Return sparray from older fixes of sparse eye, diags, random (#33516) --- sklearn/utils/fixes.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sklearn/utils/fixes.py b/sklearn/utils/fixes.py index 8e856452213da..eaee5b2b1237d 100644 --- a/sklearn/utils/fixes.py +++ b/sklearn/utils/fixes.py @@ -435,14 +435,14 @@ def _sparse_random_array( else: def _sparse_eye_array(m, n=None, *, k=0, dtype=float, format=None): - return scipy.sparse.eye(m, n, k=k, dtype=dtype, format=format) + A = scipy.sparse.eye(m, n, k=k, dtype=dtype) + return scipy.sparse.dia_array(A).asformat(format) def _sparse_diags_array( diagonals, /, *, offsets=0, shape=None, format=None, dtype=None ): - return scipy.sparse.diags( - diagonals, offsets=offsets, shape=shape, format=format, dtype=dtype - ) + A = scipy.sparse.diags(diagonals, offsets=offsets, shape=shape, dtype=dtype) + return scipy.sparse.dia_array(A).asformat(format) def _sparse_random_array( shape, @@ -454,14 +454,14 @@ def _sparse_random_array( rng=None, data_sampler=None, ): - return scipy.sparse.random( + A = scipy.sparse.random( *shape, density=density, - format=format, dtype=dtype, random_state=rng or random_state, data_rvs=data_sampler, ) + return scipy.sparse.coo_array(A).asformat(format) # TODO: remove when SciPy 1.15 is minimal supported version From 7aae3427d8b6b7ee6aa150ac355262dd0b0e793f Mon Sep 17 00:00:00 2001 From: Omar Salman <omar.salman@arbisoft.com> Date: Wed, 11 Mar 2026 22:10:52 +0500 Subject: [PATCH 277/462] MNT enable mixed array support for `accuracy_score`, `f1_score`, `multilabel_confusion_matrix`, `precision_score` and `recall_score` (#33504) Co-authored-by: Tim Head <betatim@gmail.com> --- sklearn/metrics/_classification.py | 6 ++++-- sklearn/metrics/tests/test_common.py | 9 ++++++++- sklearn/utils/validation.py | 4 +++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 8a0ad68343574..62c9424568309 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -742,7 +742,8 @@ def multilabel_confusion_matrix( [1, 2]]]) """ y_true, y_pred = attach_unique(y_true, y_pred) - xp, _, device_ = get_namespace_and_device(y_true, y_pred, sample_weight) + xp, _, device_ = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device_) y_type, y_true, y_pred, sample_weight = _check_targets( y_true, y_pred, sample_weight ) @@ -2146,6 +2147,8 @@ def precision_recall_fscore_support( array([2, 2, 2])) """ _check_zero_division(zero_division) + xp, _, device_ = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device_) labels = _check_set_wise_labels(y_true, y_pred, average, labels, pos_label) # Calculate tp_sum, pred_sum, true_sum ### @@ -2161,7 +2164,6 @@ def precision_recall_fscore_support( pred_sum = tp_sum + MCM[:, 0, 1] true_sum = tp_sum + MCM[:, 1, 0] - xp, _, device_ = get_namespace_and_device(y_true, y_pred) if average == "micro": tp_sum = xp.reshape(xp.sum(tp_sum), (1,)) pred_sum = xp.reshape(xp.sum(pred_sum), (1,)) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 40f6badf37366..657303c9b8a64 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -100,6 +100,7 @@ assert_array_equal, assert_array_less, ignore_warnings, + skip_if_array_api_compat_not_configured, ) from sklearn.utils.fixes import COO_CONTAINERS, parse_version, sp_version from sklearn.utils.multiclass import type_of_target @@ -619,14 +620,16 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): } # Metrics that support mixed namespace/device array API inputs -# Mixed mixed namespace/device support is NOT planned for pairwise metrics +# Mixed namespace/device support is NOT planned for pairwise metrics METRICS_SUPPORTING_MIXED_NAMESPACE = [ + "accuracy_score", "average_precision_score", "brier_score_loss", "confusion_matrix_at_thresholds", "d2_brier_score", "d2_log_loss_score", "explained_variance_score", + "f1_score", "log_loss", "max_error", "mean_absolute_error", @@ -635,7 +638,10 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "mean_squared_error", "mean_squared_log_error", "median_absolute_error", + "multilabel_confusion_matrix", + "precision_score", "r2_score", + "recall_score", "root_mean_squared_error", "root_mean_squared_log_error", ] @@ -2611,6 +2617,7 @@ def _get_dtype(data, xp, device): & (set(CLASSIFICATION_METRICS.keys()) - METRIC_UNDEFINED_BINARY) ), ) +@skip_if_array_api_compat_not_configured def test_array_api_classification_string_input(metric_name): """Check string inputs accepted with array API dispatch enabled. diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index 3ea39c38a025f..7ba1c19733621 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -2140,7 +2140,9 @@ def _check_sample_weight( sample_weight : ndarray of shape (n_samples,) Validated sample weight. It is guaranteed to be "C" contiguous. """ - xp, is_array_api, device = get_namespace_and_device(X, remove_types=(int, float)) + xp, is_array_api, device = get_namespace_and_device( + X, remove_types=(list, int, float) + ) n_samples = _num_samples(X) From c451b03bf1f295fba46f300921746ce01d925f86 Mon Sep 17 00:00:00 2001 From: sauravyadav1008 <sauravyadav1008@gmail.com> Date: Fri, 13 Mar 2026 11:18:38 +0530 Subject: [PATCH 278/462] CI Add GHA aggregate job (#33508) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Loïc Estève <loic.esteve@ymail.com> --- .github/workflows/unit-tests.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index e4f57f04457da..146af926287ef 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -476,3 +476,16 @@ jobs: --junit-file $TEST_DIR/$JUNITXML \ --auto-close false \ --job-name "$JOB_NAME" + + # This aggregates all unit test jobs statuses into a single status. This is + # useful to be able to have a single required check in GitHub. + check-job-statuses: + name: Check all job statuses + runs-on: ubuntu-latest + if: always() + needs: [lint, unit-tests, debian-32bit, free-threaded, scipy-dev] + steps: + - uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} + allowed-skips: free-threaded,scipy-dev From 4fdd24594e67ad2e4600e25bfd24b5d86cdb4007 Mon Sep 17 00:00:00 2001 From: Dan Schult <dschult@colgate.edu> Date: Fri, 13 Mar 2026 12:40:52 -0400 Subject: [PATCH 279/462] FIX example with OneHotEncoder involving int32 index arrays for sparse arrrays (#33530) --- sklearn/preprocessing/_encoders.py | 2 ++ sklearn/preprocessing/tests/test_encoders.py | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/sklearn/preprocessing/_encoders.py b/sklearn/preprocessing/_encoders.py index 186056d6715a0..c6223612ba4bb 100644 --- a/sklearn/preprocessing/_encoders.py +++ b/sklearn/preprocessing/_encoders.py @@ -20,6 +20,7 @@ from sklearn.utils._missing import is_scalar_nan from sklearn.utils._param_validation import Interval, RealNotInt, StrOptions from sklearn.utils._set_output import _get_output_config +from sklearn.utils.fixes import _ensure_sparse_index_int32 from sklearn.utils.validation import ( _check_feature_names_in, check_is_fitted, @@ -1087,6 +1088,7 @@ def transform(self, X): dtype=self.dtype, ) if self.sparse_output: + _ensure_sparse_index_int32(out) return _align_api_if_sparse(out) else: return out.toarray() diff --git a/sklearn/preprocessing/tests/test_encoders.py b/sklearn/preprocessing/tests/test_encoders.py index 636055c599a4e..b467e36b83a2e 100644 --- a/sklearn/preprocessing/tests/test_encoders.py +++ b/sklearn/preprocessing/tests/test_encoders.py @@ -39,6 +39,16 @@ def test_one_hot_encoder_sparse_dense(): assert_array_equal(X_trans_sparse.toarray(), X_trans_dense) +def test_one_hot_encoder_sparse_index_array_int32(): + X = np.array([[3, 2, 1], [0, 1, 1]]) + enc_sparse = OneHotEncoder(sparse_output=True) + + X_trans_sparse = enc_sparse.fit_transform(X) + assert X_trans_sparse.format == "csr" + assert X_trans_sparse.indices.dtype == np.int32 + assert X_trans_sparse.indptr.dtype == np.int32 + + @pytest.mark.parametrize("handle_unknown", ["ignore", "infrequent_if_exist", "warn"]) def test_one_hot_encoder_handle_unknown(handle_unknown): X = np.array([[0, 2, 1], [1, 0, 3], [1, 0, 2]]) From 0fa2fb665eb96ee064f9932d15a720f713c7242e Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Sun, 15 Mar 2026 02:34:13 +1100 Subject: [PATCH 280/462] TST Clean up `METRICS_WITH_LABELS` in `test_common.py` (#33506) --- sklearn/metrics/tests/test_common.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 657303c9b8a64..9e83afe2386ec 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -392,9 +392,6 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): METRICS_WITH_LABELS = { "confusion_matrix", "normalized_confusion_matrix", - "roc_curve", - "precision_recall_curve", - "det_curve", "precision_score", "recall_score", "f1_score", From 99779b60555634dde448a48cd740e9692249b928 Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Sun, 15 Mar 2026 02:41:25 +1100 Subject: [PATCH 281/462] TST Add `log_loss` to `METRICS_WITH_NORMALIZE_OPTION` in `test_common.py` (#33505) --- sklearn/metrics/tests/test_common.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 9e83afe2386ec..c55668c72fe6c 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -428,6 +428,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): # Metrics with a "normalize" option METRICS_WITH_NORMALIZE_OPTION = { "accuracy_score", + "log_loss", "top_k_accuracy_score", "zero_one_loss", } @@ -1343,7 +1344,7 @@ def test_normalize_option_binary_classification(name): y_true = random_state.randint(0, n_classes, size=(n_samples,)) y_pred = random_state.randint(0, n_classes, size=(n_samples,)) - y_score = random_state.normal(size=y_true.shape) + y_score = random_state.uniform(size=y_true.shape) metrics = ALL_METRICS[name] pred = y_score if name in CONTINUOUS_CLASSIFICATION_METRICS else y_pred @@ -1372,7 +1373,9 @@ def test_normalize_option_multiclass_classification(name): y_true = random_state.randint(0, n_classes, size=(n_samples,)) y_pred = random_state.randint(0, n_classes, size=(n_samples,)) - y_score = random_state.uniform(size=(n_samples, n_classes)) + y_score = random_state.rand(n_samples, n_classes) + temp = np.exp(-y_score) + y_score = temp / temp.sum(axis=-1).reshape(-1, 1) metrics = ALL_METRICS[name] pred = y_score if name in CONTINUOUS_CLASSIFICATION_METRICS else y_pred From 1ee0cf6a8cb50d6f18f4d2a224acb4380ef7eb5c Mon Sep 17 00:00:00 2001 From: Tim Head <betatim@gmail.com> Date: Sat, 14 Mar 2026 23:27:36 +0100 Subject: [PATCH 282/462] DOC Tweak heading type (#33534) --- doc/related_projects.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/related_projects.rst b/doc/related_projects.rst index ae8d7d2ed165c..9c2dd0a92a047 100644 --- a/doc/related_projects.rst +++ b/doc/related_projects.rst @@ -287,7 +287,7 @@ Other packages useful for data analysis and machine learning. Models are fully compatible with scikit-learn. Recommendation Engine packages -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------------ - `implicit <https://github.com/benfred/implicit>`_, Library for implicit feedback datasets. @@ -299,7 +299,7 @@ Recommendation Engine packages datasets. Domain specific packages -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ - `scikit-network <https://scikit-network.readthedocs.io/>`_ Machine learning on graphs. From 3b63811f30679ba79347dfccdb82b63bcb3098d9 Mon Sep 17 00:00:00 2001 From: shifanaaaa <shifanaaparveen@gmail.com> Date: Mon, 16 Mar 2026 12:18:06 +0530 Subject: [PATCH 283/462] DOC Fix typo in naive_bayes.rst (#33539) --- doc/modules/naive_bayes.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/modules/naive_bayes.rst b/doc/modules/naive_bayes.rst index 0f291599d8008..423c6fc8ae126 100644 --- a/doc/modules/naive_bayes.rst +++ b/doc/modules/naive_bayes.rst @@ -12,7 +12,7 @@ based on applying Bayes' theorem with the "naive" assumption of conditional independence between every pair of features given the value of the class variable. Bayes' theorem states the following relationship, given class variable :math:`y` and dependent feature -vector :math:`x_1` through :math:`x_n`, : +vector :math:`x_1` through :math:`x_n`: .. math:: @@ -61,7 +61,7 @@ the references below.) Naive Bayes learners and classifiers can be extremely fast compared to more sophisticated methods. The decoupling of the class conditional feature distributions means that each -distribution can be independently estimated as a one dimensional distribution. +distribution can be independently estimated as a one-dimensional distribution. This in turn helps to alleviate problems stemming from the curse of dimensionality. From ea08d967909ca854bed7790511891c44c9800d7c Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 16 Mar 2026 03:11:50 -0400 Subject: [PATCH 284/462] =?UTF-8?q?=F0=9F=94=92=20=F0=9F=A4=96=20CI=20Upda?= =?UTF-8?q?te=20lock=20files=20for=20scipy-dev=20CI=20build(s)=20?= =?UTF-8?q?=F0=9F=94=92=20=F0=9F=A4=96=20(#33549)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lock file bot <noreply@github.com> --- .../github/pylatest_pip_scipy_dev_linux-64_conda.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index c60f88b51fc45..ecebd17088beb 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -24,7 +24,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.cond https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 @@ -32,7 +32,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa -# pip charset-normalizer @ https://files.pythonhosted.org/packages/38/9c/71336bff6934418dc8d1e8a1644176ac9088068bc571da612767619c97b3/charset_normalizer-3.4.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=01a1ed54b953303ca7e310fafe0fe347aab348bd81834a0bcd602eb538f89d66 +# pip charset-normalizer @ https://files.pythonhosted.org/packages/76/7e/bc8911719f7084f72fd545f647601ea3532363927f807d296a8c88a62c0d/charset_normalizer-3.4.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=7bda6eebafd42133efdca535b04ccb338ab29467b3f7bf79569883676fc628db # pip coverage @ https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec @@ -40,7 +40,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip imagesize @ https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl#sha256=5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip markupsafe @ https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 -# pip meson @ https://files.pythonhosted.org/packages/9c/d5/582789135863eec7c8c1fa31fbde401b3d5d82dbbb4a0973351a1698f738/meson-1.10.1-py3-none-any.whl#sha256=fe43d1cc2e6de146fbea78f3a062194bcc0e779efc8a0f0d7c35544dfb86731f +# pip meson @ https://files.pythonhosted.org/packages/0b/78/7d049e63e624d51d0065191dae101a1e36d5d3a2360633772d9ad8afb2d5/meson-1.10.2-py3-none-any.whl#sha256=5f84ef186e6e788d9154db63620fc61b3ece69f643b94b43c8b9203c43d89b36 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 # pip platformdirs @ https://files.pythonhosted.org/packages/63/d7/97f7e3a6abb67d8080dd406fd4df842c2be0efaf712d1c899c32a075027c/platformdirs-4.9.4-py3-none-any.whl#sha256=68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868 From 1543e992af9125e7dbbe0e0546f3c2e4d5c808f4 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 16 Mar 2026 03:12:19 -0400 Subject: [PATCH 285/462] =?UTF-8?q?=F0=9F=94=92=20=F0=9F=A4=96=20CI=20Upda?= =?UTF-8?q?te=20lock=20files=20for=20free-threaded=20CI=20build(s)=20?= =?UTF-8?q?=F0=9F=94=92=20=F0=9F=A4=96=20(#33548)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lock file bot <noreply@github.com> --- .../github/pylatest_free_threaded_linux-64_conda.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index 1522105aec7c5..25a0dcd381517 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -27,7 +27,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 @@ -39,12 +39,12 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.con https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d From c3ed270cc49b0216104f1b5d354f60faa825d541 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 16 Mar 2026 03:13:44 -0400 Subject: [PATCH 286/462] =?UTF-8?q?=F0=9F=94=92=20=F0=9F=A4=96=20CI=20Upda?= =?UTF-8?q?te=20lock=20files=20for=20array-api=20CI=20build(s)=20?= =?UTF-8?q?=F0=9F=94=92=20=F0=9F=A4=96=20(#33550)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lock file bot <noreply@github.com> --- ...a_forge_cuda_array-api_linux-64_conda.lock | 89 ++++++++++--------- 1 file changed, 45 insertions(+), 44 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 637ae1cfb4c71..9b2ad3c68b403 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -32,7 +32,6 @@ https://conda.anaconda.org/conda-forge/linux-64/libnvptxcompiler-dev-12.9.86-ha7 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb -https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 @@ -40,6 +39,7 @@ https://conda.anaconda.org/conda-forge/noarch/cuda-nvcc-dev_linux-64-12.9.86-he9 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-impl-12.9.86-h4bc722e_2.conda#82125dd3c0c4aa009faa00e2829b93d8 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-tools-12.9.86-h4bc722e_2.conda#f9af26e4079adcd72688a8e8dbecb229 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 +https://conda.anaconda.org/conda-forge/linux-64/libattr-2.5.2-hb03c661_1.conda#7e7f0a692eb62b95d3010563e7f963b6 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 @@ -66,6 +66,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 +https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-hb03c661_1.conda#9bb149f49de3f322fca007283eaa2725 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.13-h2c9d079_1.conda#3c3d02681058c3d206b562b2e3bc337f https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.2-h8b1a151_0.conda#f16f498641c9e05b645fe65902df661a https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h8b1a151_4.conda#c7e3e08b7b1b285524ab9d74162ce40b @@ -82,11 +83,10 @@ https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda#f7d7 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 -https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda#6f7b4302263347698fd24565fbf11310 https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f -https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libcufft-11.4.1.4-hecca717_1.conda#75ae571353ec92c8f34d4cf6ec6ba264 https://conda.anaconda.org/conda-forge/linux-64/libcurand-10.3.10.19-h676940d_1.conda#2a91559a9345bedf09af8b7903deb6e6 https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 @@ -108,7 +108,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/rapidsai/linux-64/rapids-logger-0.2.3-h98325ef_0.conda#81257f29bfcc1e58f0405d7bc9feb309 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.0-ha63dd3a_1.conda#f9bb0a7187f2e25b19cde17aa8c846c4 +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.1-h1cbb8d7_1.conda#9d978822b57bafe72ebd3f8b527bba71 https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -117,15 +117,16 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.cond https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-h3ca20c3_1.conda#c9aa75692f24cce182c3ecd001a1a595 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-hc87160b_2.conda#3a7d90d34895728f0b69107602b6e189 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_1.conda#55a83761db33f82d92d7d7a4a61662e5 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd +https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.conda#af0df9bc982b5ed2c67e8f5062d1f8c1 https://conda.anaconda.org/conda-forge/linux-64/libcurand-dev-10.3.10.19-h676940d_1.conda#fc716aaff5af15b80ccbd28b3e67672c @@ -138,10 +139,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.co https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 https://conda.anaconda.org/rapidsai/linux-64/librmm-26.02.00-cuda12_260204_498dafcf.conda#057e94dab29e9c69b4542eb0c61b161e https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-259.3-h6569c3e_0.conda#14f6f781723e56e33ca7e04d406511e4 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libudev1-259.3-h6569c3e_0.conda#41fd789b8466d0f68083ff37b637a090 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 @@ -150,7 +149,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.9-h841be55_2.conda#7e1ea1a67435a32e04305fda877acd1e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.10-hf621c6d_0.conda#977e7d3cba1ef84fc088869b292672fe +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.11-hf621c6d_0.conda#caf217f88155d551b4a586f2da37941a https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvcc-impl-12.9.86-h85509e4_2.conda#67458d2685e7503933efa550f3ee40f3 https://conda.anaconda.org/conda-forge/linux-64/cuda-profiler-api-12.9.79-h7938cbb_1.conda#90d09865fb37d11d510444e34ebe6a09 @@ -162,52 +161,52 @@ https://conda.anaconda.org/conda-forge/linux-64/libcublas-dev-12.9.1.4-h676940d_ https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.conda#a178a1f3642521f104ecceeefa138d01 https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_1.conda#c5b8ea827c65e5811d61aa49cd0bae9a https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-hcf29cc6_1.conda#1707cdd636af2ff697b53186572c9f77 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2.conda#bb6e31a0daa64ede76fe8d3fff01c06f https://conda.anaconda.org/conda-forge/linux-64/libcusparse-dev-12.5.10.65-hecca717_2.conda#db94469fbd554c107acc3afd0af5d8ec https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-26.02.00-cuda12_260204_c212ab9b.conda#702a98df50c3b8be134516647a217fde +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-259.5-h6569c3e_0.conda#208dd14d53c3968afd1ebb6d5647b14e +https://conda.anaconda.org/conda-forge/linux-64/libudev1-259.5-h6569c3e_0.conda#166de8bb898bc883626e2382e5dd8621 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d -https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 +https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-openmp_hd77311e_4.conda#525e2455ed342f2aef93c59ac5db2e28 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-hbb90d81_1.conda#9269175175f18091b8844c8e9f213205 +https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d -https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.6-hb9c0fe4_1.conda#b1143a5b5a03ee174b3f3f7c49df3c09 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.14.0-ha25ca29_1.conda#a827b063719f5aac504d06ac77cc3125 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h536185d_1.conda#bc645a385e91cd3d9235174fcbd17e25 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.0-hac84f0a_1.conda#9cf66b4abc53e47857afbee27364102b https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.4.1-pyhc364b38_0.conda#50e2bf874bbde47e66c2b0c6b62d0026 +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.4.2-pyhc364b38_0.conda#0b582191a96267c4bd173f35deba3f7a https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.0-pyhd8ed1ab_0.conda#49a92015e912176999ae81bea11ea778 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py313hc8edb43_2.conda#3e0e65595330e26515e31b7fc6d933c7 +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py313hc8edb43_0.conda#b81883b9dbf5069821c2fb09a8ba1407 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 -https://conda.anaconda.org/conda-forge/linux-64/libcufile-1.14.1.1-hbc026e6_1.conda#cab1818eada3952ed09c8dcbb7c26af7 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-dev-11.7.5.82-h676940d_2.conda#0fe12e558abf507458bcec839e29778d https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.0-h1d1128b_1.conda#66055700c90b50c0405a4e515bb4fe3c https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.0-hf7376ad_0.conda#213f51bbcce2964ff2ec00d0fdd38541 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/llvmlite-0.44.0-py313hfdae721_2.conda#dd0d7947635c0c524608eab7db55dcc9 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda#aeb9b9da79fd0258b3db091d1fefcd71 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 @@ -222,14 +221,14 @@ https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0. https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.4-py313hd02dea0_0.conda#442d7ac35e5d6bc89eba2998a9e1de06 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/linux-64/ucx-1.20.0-hbe80e26_1.conda#ffdaec09a7c09710040eb9e613f8c531 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b @@ -237,25 +236,24 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h9b5df67_3.conda#1f130ac4eb7f1dea1ae4b5f53683e3aa +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h37c9286_4.conda#e9c44a6e46de739827d2eae25ed2ee32 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py313h3dea7bd_0.conda#77e1fc7133e03ccd62070f2405c82ea9 -https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.5-py313h929d4db_0.conda#f2416964cdb2808dd2ed5be276a8fcdb https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py313h3dea7bd_0.conda#c0f36dfbb130da4f6ce2df31f6b25ea8 -https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py313h86d8783_2.conda#d904f240d2d2500d4906361c67569217 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py313h3dea7bd_0.conda#e479cfdec38fb69dc81ce8806b5c75f6 +https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py313h86d8783_1.conda#047e3ea395eab013f918b338fecc19a0 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d +https://conda.anaconda.org/conda-forge/linux-64/libcufile-1.14.1.1-hbc026e6_1.conda#cab1818eada3952ed09c8dcbb7c26af7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-h9d11ab5_1.conda#cd398eb8374fb626a710b7a35b7ffa98 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-h9692893_2.conda#c3de1cc30bc11edbc98aed352381449d https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 -https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff @@ -264,19 +262,20 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.12-h4df99d1_100.conda#3d92938d5b83c49162ade038aab58a59 https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py313h246eb7c_1.conda#8526afdb4ae2d95db733c4188f092f01 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 +https://conda.anaconda.org/conda-forge/linux-64/ucx-1.20.0-hbe80e26_1.conda#ffdaec09a7c09710040eb9e613f8c531 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.3-hb153662_0.conda#9ce778ddbd927385bf145224e291e2a1 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h753c7c1_1.conda#f59686fd4b442be1dc4a59c35a6c7449 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 -https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.6.0-cuda12_py313hacc9b55_0.conda#1986c17fb0b8184289ea7d6fc8ba4b34 -https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.5-pyh698daf1_0.conda#a4fb0d4ffdac1cf2cda9318d2f789d20 +https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.6-py313h929d4db_0.conda#602176b8957b10172dfea675a332d0ac https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py313h28b6081_0.conda#fe933a91c19fa88788b4204b6ba67ba2 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.1.1-h6083320_0.conda#56d73078fe51aee26b7934cb1378d464 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_1.conda#384a1730ea66a72692e377cb45996d61 https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_hb019b6b_203.conda#5e373fc37a76270b4454c02cb126ab34 +https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.conda#84cef0ce56c6db53edb3f8b83bdbb364 https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py313h7037e92_0.conda#21f1c403983c8a4e067ba6eec6b878ec @@ -284,35 +283,37 @@ https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py313hbfd7664_0.con https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-h133b1ee_1.conda#36afc05aac7c7f516749cdd3b5e978d9 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-h5f21323_2.conda#47b0ddc79fc15341d7110a1078868326 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 +https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.6.0-cuda12_py313hacc9b55_0.conda#1986c17fb0b8184289ea7d6fc8ba4b34 +https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.conda#8d3dbe5292af711edd6df92c68e55a89 https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py313h7fc6698_0.conda#41368ea5c4c7c607ac98ecab56833535 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 -https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hffdcd12_0.conda#b659a59ec7b67623dcaec02388e06fb9 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_hb8e8477_203.conda#6cfb64f7fc401f2c7c789214237aea24 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-h17e89b9_5.conda#6c4f73c9a7e9b51f3a8e321c3e867bb6 -https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-h711ef25_3_cpu.conda#2c3ae75a99b9d824c0b64a6c2daa533c +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-hc1a2089_5_cpu.conda#ece55298311b727b6810156aad9ccad1 +https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313h85046ba_0.conda#f6161781ceb86e9f5da1b532e4c4453c +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313hcd51b16_0.conda#2ae30c246bf80b1d5e57480d9069dab4 https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_203.conda#969fd0ea1b469425630712ba3513deff +https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_5_cpu.conda#16e8c9aa6a76282ddfc0fc5e7d5e7ae3 +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_5_cpu.conda#50b3355129c86b3fe13a58e2fc4e959a +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_3_cpu.conda#9d22a47a7902caf8736275487cfabd4e -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_3_cpu.conda#7941cce779e45e6803d39408dd20f373 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_5_cpu.conda#9010a95bfa086bd3ba8697ed64b99264 https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_3_cpu.conda#312f95714162590832593173872b9e1d +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py313h98bfbea_0_cpu.conda#d2b771a9050c52941a61a72f2d161c64 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_5_cpu.conda#368ee0f69d66d97fa9726e0a2d43c068 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py313h98bfbea_0_cpu.conda#d2b771a9050c52941a61a72f2d161c64 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_3_cpu.conda#9d4fcb24972610d1ad53acf6773f92cb +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_5_cpu.conda#823d932334271476a5195ee86696e647 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.02.00-cuda12_260204_a2f5a8b7.conda#361cae27e77618c6ba9f943807471f9f https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.02.00-cuda12_py313_260204_c212ab9b.conda#14933b753ec82f9d5a61d7cb4b5e2e71 https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.02.00-cuda12_py313_260204_a2f5a8b7.conda#c46807878ad576379e7be3acc187d13a -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_3_cpu.conda#1035c10de0713956d0b503eed07825b5 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py313h78bf25f_0.conda#bd299f66ab2d10d1e03d4148397fe263 From 3aef816dec6741e851e2c839f1e50bc4bc6003a4 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 16 Mar 2026 03:16:04 -0400 Subject: [PATCH 287/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33551) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/circle/doc_linux-64_conda.lock | 22 +++---- .../doc_min_dependencies_linux-64_conda.lock | 23 ++++---- build_tools/github/debian_32bit_lock.txt | 2 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 58 +++++++++---------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 14 ++--- .../pylatest_conda_forge_osx-arm64_conda.lock | 20 +++---- ...st_pip_openblas_pandas_linux-64_conda.lock | 14 ++--- ...n_conda_forge_arm_linux-aarch64_conda.lock | 18 +++--- ...nblas_min_dependencies_linux-64_conda.lock | 25 ++++---- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 8 +-- ...min_conda_forge_openblas_win-64_conda.lock | 14 ++--- build_tools/github/ubuntu_atlas_lock.txt | 2 +- 12 files changed, 111 insertions(+), 109 deletions(-) diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index ce61b78abae09..4a933c56a548d 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -56,7 +56,7 @@ https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3b https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c -https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.5-h088129d_0.conda#86f7414544ae606282352fa1e116b41f https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f @@ -153,26 +153,26 @@ https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.b https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/noarch/json5-0.13.0-pyhd8ed1ab_0.conda#8d5f66ebf832c4ce28d5c37a0e76605c https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda#cd2214824e36b0180141d422aba01938 -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b965c999135d43a3d0f7bd7d024e26a https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.0-hf7376ad_0.conda#213f51bbcce2964ff2ec00d0fdd38541 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.17.0-pyhcf101f3_0.conda#538f3a813e0805c7e3f037603f12a400 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.0-pyhcf101f3_0.conda#bc317f07dd82e410012684d2e3a9c06d https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda#4fefefb892ce9cc1539405bec2f1a6cd +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.24.1-pyhd8ed1ab_0.conda#7526d20621b53440b0aae45d4797847e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f @@ -190,7 +190,7 @@ https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda#3893f7b40738f9fe87510cb4468cdda5 https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda#28eb91468df04f655a57bcfbb35fc5c5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda#18de09b20462742fe093ba39185d9bac @@ -221,7 +221,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 @@ -267,14 +267,14 @@ https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d354 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.1.1-h6083320_0.conda#56d73078fe51aee26b7934cb1378d464 https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda#7b8bace4943e0dc345fc45938826f2b8 -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.3-pyhcf101f3_0.conda#8ecf1988b05090fafc3387ada297e22b +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.4-pyhcf101f3_0.conda#e81089ba496151ed0bfe3e9cb196ca11 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.conda#3ac73c673df24589b5b84d43a4afd235 @@ -306,7 +306,7 @@ https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py311he4c1a5a_0.conda#7287f5cca6b7f82571c1911a43e924b0 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py311hf27b23e_0.conda#d47160bd36bce78bc139d5e992ff81ce https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py311h2a99c40_0.conda#557f5d7ca735d89d706742bc19cd7e26 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index e1fc5ce83ca2a..aac2f024ad9af 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -24,10 +24,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c1 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb -https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda#f9f81ea472684d75b9dd8d0b328cf655 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 +https://conda.anaconda.org/conda-forge/linux-64/libattr-2.5.2-hb03c661_1.conda#7e7f0a692eb62b95d3010563e7f963b6 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 @@ -54,6 +54,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 +https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-hb03c661_1.conda#9bb149f49de3f322fca007283eaa2725 https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.3-hecca717_0.conda#937ca49a245fcf2b88d51b6b52959426 https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 @@ -61,11 +62,10 @@ https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.cond https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 -https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.5-h088129d_0.conda#86f7414544ae606282352fa1e116b41f https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f -https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d @@ -99,13 +99,13 @@ https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#594 https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.1-hc31b594_0.conda#68ceffc6cadae61846a207cae60de094 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd +https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda#1d4c18d75c51ed9d00092a891a547a7d https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 @@ -124,6 +124,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.0-hcfa2d63_0.conda https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda#1d4c18d75c51ed9d00092a891a547a7d https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -156,20 +157,20 @@ https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.0-hf7376ad_0.conda#213f51bbcce2964ff2ec00d0fdd38541 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda#4fefefb892ce9cc1539405bec2f1a6cd +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f @@ -179,7 +180,7 @@ https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda#3eeeeb9e4827ace8c0c1419c85d590ad -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda#18de09b20462742fe093ba39185d9bac @@ -199,7 +200,7 @@ https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 @@ -226,7 +227,7 @@ https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.1.1-h6083320_0.conda#56d73078fe51aee26b7934cb1378d464 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.5-pyhd8ed1ab_0.conda#4c8327180586e7b1cd8b6815fc8827f1 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 diff --git a/build_tools/github/debian_32bit_lock.txt b/build_tools/github/debian_32bit_lock.txt index c19d7786d5046..01f4ab19cfc44 100644 --- a/build_tools/github/debian_32bit_lock.txt +++ b/build_tools/github/debian_32bit_lock.txt @@ -14,7 +14,7 @@ iniconfig==2.3.0 # via pytest joblib==1.5.3 # via -r build_tools/github/debian_32bit_requirements.txt -meson==1.10.1 +meson==1.10.2 # via meson-python meson-python==0.19.0 # via -r build_tools/github/debian_32bit_requirements.txt diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock index 6c8c37687f7d4..57c50f5e345ee 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -60,7 +60,7 @@ https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda#f7d7 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 -https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda#6f7b4302263347698fd24565fbf11310 https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f @@ -80,7 +80,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.0-ha63dd3a_1.conda#f9bb0a7187f2e25b19cde17aa8c846c4 +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.1-h1cbb8d7_1.conda#9d978822b57bafe72ebd3f8b527bba71 https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -89,9 +89,9 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.cond https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-h3ca20c3_1.conda#c9aa75692f24cce182c3ecd001a1a595 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-hc87160b_2.conda#3a7d90d34895728f0b69107602b6e189 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 @@ -113,20 +113,20 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.9-h841be55_2.conda#7e1ea1a67435a32e04305fda877acd1e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.10-hf621c6d_0.conda#977e7d3cba1ef84fc088869b292672fe +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.11-hf621c6d_0.conda#caf217f88155d551b4a586f2da37941a https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-hcf29cc6_1.conda#1707cdd636af2ff697b53186572c9f77 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d -https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.1-h90cbb55_3.conda#2eeb50cab6652538eee8fc0bc3340c81 +https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.14.0-h3d65ac4_0.conda#2ef8b1658ab236df39a14f2b1126796e https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/orc-2.2.2-hbb90d81_1.conda#9269175175f18091b8844c8e9f213205 +https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 @@ -134,8 +134,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.9.6-hb9c0fe4_1.conda#b1143a5b5a03ee174b3f3f7c49df3c09 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.14.0-ha25ca29_1.conda#a827b063719f5aac504d06ac77cc3125 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h536185d_1.conda#bc645a385e91cd3d9235174fcbd17e25 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.0-hac84f0a_1.conda#9cf66b4abc53e47857afbee27364102b https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a @@ -146,7 +146,7 @@ https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.c https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.0-pyhd8ed1ab_0.conda#49a92015e912176999ae81bea11ea778 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 @@ -155,15 +155,15 @@ https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a8 https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py314h97ea11e_2.conda#57f1ce4f7ba6bcd460be8f83c8f04c69 +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.0-h1d1128b_1.conda#66055700c90b50c0405a4e515bb4fe3c https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.0-hf7376ad_0.conda#213f51bbcce2964ff2ec00d0fdd38541 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 @@ -179,7 +179,7 @@ https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda#23b4ba5619c4752976eb7ba1f5acb7e8 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f @@ -195,14 +195,14 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h9b5df67_3.conda#1f130ac4eb7f1dea1ae4b5f53683e3aa +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h37c9286_4.conda#e9c44a6e46de739827d2eae25ed2ee32 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py314h67df5f8_0.conda#6c7efc167cee337d9c41200506d022b8 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f -https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.2.1-py314h28848ee_2.conda#6958d0a4028e0b3ffd80ce539482c605 +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 +https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 @@ -222,9 +222,9 @@ https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.3-hb153662_0.conda#9ce778ddbd927385bf145224e291e2a1 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h753c7c1_1.conda#f59686fd4b442be1dc4a59c35a6c7449 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.1.1-h6083320_0.conda#56d73078fe51aee26b7934cb1378d464 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_1.conda#384a1730ea66a72692e377cb45996d61 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 @@ -233,7 +233,7 @@ https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.58.0-pyhcf101f https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-h133b1ee_1.conda#36afc05aac7c7f516749cdd3b5e978d9 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-h5f21323_2.conda#47b0ddc79fc15341d7110a1078868326 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad @@ -242,32 +242,32 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-h17e89b9_5.conda#6c4f73c9a7e9b51f3a8e321c3e867bb6 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-h711ef25_3_cpu.conda#2c3ae75a99b9d824c0b64a6c2daa533c +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-hc1a2089_5_cpu.conda#ece55298311b727b6810156aad9ccad1 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py314hf36963e_0.conda#46a2b79da4213038907306040c9c9fd8 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py314h3987850_0.conda#071ad1489776fd8bdf85d811c37c9b1d https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_3_cpu.conda#9d22a47a7902caf8736275487cfabd4e +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_5_cpu.conda#16e8c9aa6a76282ddfc0fc5e7d5e7ae3 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_3_cpu.conda#7941cce779e45e6803d39408dd20f373 +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_5_cpu.conda#50b3355129c86b3fe13a58e2fc4e959a https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h7058990_103.conda#2df90510834746b1f52c5299bc99a81f https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_1.conda#4ea6b620fdf24a1a0bc4f1c7134dfafb https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_3_cpu.conda#312f95714162590832593173872b9e1d +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_5_cpu.conda#9010a95bfa086bd3ba8697ed64b99264 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py314hb4ffadd_0.conda#23fc526360815090f6bfcd7c6c8e4954 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py314h969be7f_0_cpu.conda#97c21b0d5952f4e0f80bb790df1a5c88 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h6018c46_103.conda#a3c40f317db763f9631d078d0fb2759e https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 -https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.1.0-pyhcf101f3_0.conda#57d364589a8c710c5b34e8b4a5312ea6 +https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_3_cpu.conda#9d4fcb24972610d1ad53acf6773f92cb +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_5_cpu.conda#368ee0f69d66d97fa9726e0a2d43c068 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_103.conda#54ad123774a53ce33aa7e99b6e53b4a6 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_3_cpu.conda#1035c10de0713956d0b503eed07825b5 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_5_cpu.conda#823d932334271476a5195ee86696e647 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py314hdafbbf9_0.conda#860f29e99f5b5f15b0d6a21166588bab diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 1f5aef251e4ae..80c3b36385ffb 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -9,7 +9,7 @@ https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda#4173a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda#30334add4de016489b731c6662511684 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 -https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.0-h19cb2f5_1.conda#836389b6b9ae58f3fbcf7cafebd5c7f2 +https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.1-h19cb2f5_0.conda#799141ac68a99265f04bcee196b2df51 https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda#a684eb8a19b2aa68fde0267df172a1e3 https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda#66a0dc7464927d0853b590b6f53ba3ea @@ -26,7 +26,7 @@ https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.cond https://conda.anaconda.org/conda-forge/osx-64/xorg-libxdmcp-1.1.5-h8616949_1.conda#435446d9d7db8e094d2c989766cfb146 https://conda.anaconda.org/conda-forge/osx-64/xxhash-0.8.3-h13e91ac_0.conda#3e1f33316570709dac5d04bc4ad1b6d0 https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda#eaac87c21aff3ed21ad9656697bb8326 -https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hcca01a6_1.conda#21f765ced1a0ef4070df53cb425e1967 +https://conda.anaconda.org/conda-forge/osx-64/lerc-4.1.0-h35c7297_0.conda#d2fe7e177d1c97c985140bd54e2a5e33 https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda#63186ac7a8a24b3528b4b14f21c03f54 https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda#5a088b358e37ccb4f4e5c573ff37a9f9 @@ -42,7 +42,7 @@ https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda#6e6efb7 https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.3-h8bce59a_1.conda#b3ecb6480fd46194e3f7dd0ff4445dff https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf -https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13-h894318c_0.conda#46f5cb2b8d79732c282aedd47a92709f +https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.1-h894318c_0.conda#914b70b4746a94f78a34262416ba69d0 https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.2-h58fbd8d_0.conda#2e6760656fde7df787fdef045d0fc65d https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda#9a5cb96e43f5c2296690186e15b3296f https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 @@ -54,12 +54,12 @@ https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4 https://conda.anaconda.org/conda-forge/osx-64/cython-3.2.4-py314hf0dd12f_0.conda#4dbcccd0d8e2bfe89246de1547d58c17 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.9-py314hf3ac25a_2.conda#28a77c52c425fa9c6d914c609c626b1a +https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.5.0-py314hd6e1bd6_0.conda#25a8718587d3d0d9114b25dfa93b864c https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.18-h90db99b_0.conda#753acc10c7277f953f168890e5397c80 https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.2-h694c41f_0.conda#bf29ee73174c610d7cad0b081b500df7 https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda#ca52daf58cea766656266c8771d8be81 https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h52bb76a_0.conda#46e628da6e796c948fa8ec9d6d10bda3 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 @@ -67,7 +67,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -77,7 +77,7 @@ https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.1-py314h4f144dc_0.conda#773e3141f292d9698e706da094ada8c1 https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.4-py314h10d0514_0.conda#f27072a17bcb5061cd46de7d01f69028 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.2-h694c41f_0.conda#0959d7034baef0a8274387fde505c347 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda#34a9f67498721abcfef00178bcf4b190 diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock index 47e562623d1fa..05187feeac1a5 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock @@ -12,7 +12,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda#62 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda#114e6bfe7c5ad2525eb3597acdbf2300 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa -https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.0-h55c6f16_1.conda#e9c56daea841013e7774b5cd46f41564 +https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.1-h55c6f16_0.conda#7a290d944bc0c481a55baf33fa289deb https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda#a92e310ae8dfc206ff449f362fc4217f @@ -34,7 +34,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.co https://conda.anaconda.org/conda-forge/osx-arm64/fmt-12.1.0-h403dcb5_0.conda#ae2f556fbb43e5a75cc80a47ac942a8e https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-h7bae524_2.conda#eed7278dfbab727b56f2c0b64330814b https://conda.anaconda.org/conda-forge/osx-arm64/isl-0.26-imath32_h347afa1_101.conda#e80e44a3f4862b1da870dc0557f8cf3b -https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-hd64df32_1.conda#a74332d9b60b62905e3d30709df08bf1 +https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.1.0-h1eee2c3_0.conda#095e5749868adab9cae42d4b460e5443 https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20260107.1-cxx17_h2062a1b_0.conda#bb65152e0d7c7178c0f1ee25692c9fd1 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.conda#079e88933963f3f149054eec2c487bc2 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 @@ -55,14 +55,14 @@ https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda#e31 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.3-hed4e4f5_1.conda#d99c2a23a31b0172e90f456f580b695e https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c -https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13-h414bf82_0.conda#2c80c04f787fc8f9acacdc44707b18dc +https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.1-h414bf82_0.conda#69983a492267b903ddc6a4eac4dff5aa https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.2-hdfa99f5_0.conda#e726e134a392ae5d7bafa6cc4a3d5725 https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda#92df6107310b1fff92c4cc84f0de247b https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.33.5-h4a5acfd_0.conda#b839e3295b66434f20969c8b940f056a https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda#c08557d00807785decafb932b5be7ef5 https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.2-h8d039ee_0.conda#e476ba84e57f2bd2004a27381812ad4e -https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.1-hb693164_3.conda#4e4ea852d54cc2b869842de5044662fb +https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.2-h6bc93b0_0.conda#a47a14da2103c9c7a390f7c8bc8d7f9b https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda#753c8d0447677acb7ddbcc6e03e82661 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda#48ece20aa479be6ac9a284772827d00c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 @@ -70,16 +70,16 @@ https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.c https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py314hc6117b3_0.conda#1289de88f884ac89144949cb97ccabe7 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.0-pyhd8ed1ab_0.conda#49a92015e912176999ae81bea11ea778 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.9-py314h42813c9_2.conda#9aa431bf603c231e8c77a1b0842a85ed +https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.5.0-py314hf8a3a22_0.conda#eb1465d8a644ef290d18fb86af6e9bc4 https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.18-hdfa7624_0.conda#6631a7bd2335bb9699b1dbc234b19784 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.2-hce30654_0.conda#a3a53232936b55ffea76806aefe19e8b https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda#c4a6f7989cffb0544bfd9207b6789971 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py314h6e9b3f0_1.conda#d33c0a15882b70255abdd54711b06a45 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.3.1-h8f1351a_1.conda#a5635df796b71f6ca400fc7026f50701 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 @@ -91,7 +91,7 @@ https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda#ade77ad7513177297b1d75e351e136ce https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f @@ -102,9 +102,9 @@ https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py314h6c2aa35_0.conda#4fffb3ba871bb05f34ffb705534dfef5 https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.4-py314h6e9b3f0_0.conda#96c7bf4f2b5010d29604a62e91e634bb https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.61.1-pyh7db6752_0.conda#d5da976e963e70364b9e3ff270842b9f +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.2-hce30654_0.conda#ca730d8e7d1de1f71013edfef0e08f13 -https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.2.1-py314h07d5e28_2.conda#2e07295c0b3bcdae3551d525b70e396f +https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.3.0-py314hf9f5e1b_1.conda#036584b863246f278f4057327c36a94d https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_4.conda#eaf3d06e3a8a10dee7565e8d76ae618d diff --git a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock index 628693b40c145..48ebb67c1667c 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -24,7 +24,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.cond https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d @@ -32,22 +32,22 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa -# pip charset-normalizer @ https://files.pythonhosted.org/packages/94/0a/af49691938dfe175d71b8a929bd7e4ace2809c0c5134e28bc535660d5262/charset_normalizer-3.4.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=0625665e4ebdddb553ab185de5db7054393af8879fb0c87bd5690d14379d6819 +# pip charset-normalizer @ https://files.pythonhosted.org/packages/2b/58/a199d245894b12db0b957d627516c78e055adc3a0d978bc7f65ddaf7c399/charset_normalizer-3.4.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=530e8cebeea0d76bdcf93357aa5e41336f48c3dc709ac52da2bb167c5b8271d9 # pip coverage @ https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 # pip cython @ https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec -# pip fonttools @ https://files.pythonhosted.org/packages/a3/4b/d67eedaed19def5967fade3297fed8161b25ba94699efc124b14fb68cdbc/fonttools-4.61.1-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl#sha256=64102ca87e84261419c3747a0d20f396eb024bdbeb04c2bfb37e2891f5fadcb5 +# pip fonttools @ https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1 # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea # pip imagesize @ https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl#sha256=5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip joblib @ https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl#sha256=5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 -# pip kiwisolver @ https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098 +# pip kiwisolver @ https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 -# pip meson @ https://files.pythonhosted.org/packages/9c/d5/582789135863eec7c8c1fa31fbde401b3d5d82dbbb4a0973351a1698f738/meson-1.10.1-py3-none-any.whl#sha256=fe43d1cc2e6de146fbea78f3a062194bcc0e779efc8a0f0d7c35544dfb86731f +# pip meson @ https://files.pythonhosted.org/packages/0b/78/7d049e63e624d51d0065191dae101a1e36d5d3a2360633772d9ad8afb2d5/meson-1.10.2-py3-none-any.whl#sha256=5f84ef186e6e788d9154db63620fc61b3ece69f643b94b43c8b9203c43d89b36 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa -# pip numpy @ https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499 +# pip numpy @ https://files.pythonhosted.org/packages/7e/eb/7daecbea84ec935b7fc732e18f532073064a3816f0932a40a17f3349185f/numpy-2.4.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc # pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 # pip pillow @ https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 @@ -79,6 +79,6 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip pyamg @ https://files.pythonhosted.org/packages/63/f3/c13ae1422434baeefe4d4f306a1cc77f024fe96d2abab3c212cfa1bf3ff8/pyamg-5.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=5cc223c66a7aca06fba898eb5e8ede6bb7974a9ddf7b8a98f56143c829e63631 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 -# pip scipy-doctest @ https://files.pythonhosted.org/packages/92/4f/b10c11591ca2e98f5a51568e39ea625ac0686f651130f5ef18e38b5f4816/scipy_doctest-2.1.0-py3-none-any.whl#sha256=f3187913469a335f7e9546b5588160e1b25de58999c0a5d21615f281b794f66d +# pip scipy-doctest @ https://files.pythonhosted.org/packages/71/65/91154fa8addb81ad204406e9cbf8dbe630e86d3cf8689957de17b6a12ca2/scipy_doctest-2.2.0-py3-none-any.whl#sha256=2a0c2d445825176442e223bea24f57c645563a7de3a879f4bd5270ff12523d91 # pip sphinx @ https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl#sha256=c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978 # pip numpydoc @ https://files.pythonhosted.org/packages/62/5e/3a6a3e90f35cea3853c45e5d5fb9b7192ce4384616f932cf7591298ab6e1/numpydoc-1.10.0-py3-none-any.whl#sha256=3149da9874af890bcc2a82ef7aae5484e5aa81cb2778f08e3c307ba6d963721b diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 0b7b0fdcfefa6..78ed255574448 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -45,7 +45,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xxhash-0.8.3-hd794028_0.con https://conda.anaconda.org/conda-forge/linux-aarch64/double-conversion-3.4.0-hfae3067_0.conda#9fd794eaf983eabf975ead524540b4be https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda#4aa540e9541cc9d6581ab23ff2043f13 https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.2-hcab7f73_0.conda#998ee7d53e32f7ab57fc35707285527e -https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.0.0-hfdc4d58_1.conda#60dceb7e876f4d74a9cbd42bbbc6b9cf +https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda#d13423b06447113a90b5b1366d4da171 https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf_1.conda#47e5b71b77bb8b47b4ecf9659492977f https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda#6553a5d017fe14859ea8a4e6ea5def8f https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda#2079727b538f6dd16f3fa579d4c3c53f @@ -67,7 +67,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0 https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda#f731af71c723065d91b4c01bb822641b https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 -https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13-h185addb_0.conda#e82dd46d52f3696ad7451abe0af74831 +https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.1-h185addb_0.conda#dd42f9e00baaecee065571c4b522373b https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda#d9ca108bd680ea86a963104b6b3e95ca https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda#35b2ae7fadf364b8e5fb8185aaeb80e5 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.2-hdae7a39_0.conda#69d1cdfdabb66464cbde17890e8be3b9 @@ -106,14 +106,14 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda#0fed1ff55f4938a65907f3ecf62609db https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.2-h8af1aa0_0.conda#9cb47d7bbb36646c44d7cf1cb8047887 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.4.9-py311h229e7f7_2.conda#18358d47ebdc1f936003b7d407c9e16f +https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.5.0-py311h229e7f7_0.conda#aeade47300d466d9d6ba01daaca31a86 https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda#0b2f1143ae2d0aa4c991959d0daaf256 https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda#0d00176464ebb25af83d40736a2cd3bb https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda#88d1e4133d1182522b403e9ba7435f04 -https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.0-hfd2ba90_0.conda#c109137a7e54fde795637863f62485a1 +https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.1-hfd2ba90_0.conda#9684eec87b0eb9c81c6b95dfcbe574a0 https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h2fb54aa_1.conda#b761e5f1358577a16ca187c6116d9fcc https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 @@ -121,7 +121,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.1-py311h8e17b9e https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -139,7 +139,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.7-he30d https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.4-py311h2dad8b0_0.conda#6fcc144f2f5c3537297288e61d09e8f2 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.61.1-py311h164a683_0.conda#b59452fef1470e7e5c34a7c5deefe853 +https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.62.0-py311h164a683_0.conda#d3ef6350930100e30aaf0ecdf4e4dd3a https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp22.1-22.1.0-default_he95a3c9_0.conda#1519a50e2f4caca01098a33d39f45f5c https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.0-default_h94a09a5_0.conda#4e1023aa62d0919a4014954d57bcb786 @@ -153,7 +153,7 @@ https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bd https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-5_h9678261_openblas.conda#33a0e650392a79b56ae0bfa3db02ddbf https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311h04741b4_4.conda#1eeea54b0c520a475db39f8c711de661 -https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-12.3.2-h1134a53_0.conda#f8ab08bc3716972b7bd47e48a6884260 +https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-13.1.1-h1134a53_0.conda#46a7a399537501c4501be18a9f871976 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 @@ -163,5 +163,5 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py31 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.10.2-h4f79d1e_5.conda#c5a6c2e22d9e1a1ef8870a5997fe2eda -https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.10.2-py311hf1caecd_0.conda#a245e6ef62e8403f5c5e449e6227924d +https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.10.2-py311hb02cd75_0.conda#b9c3166811022d7f8f984816b644f7d4 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.8-py311hfecb2dc_0.conda#3920b856b59a909812f1913b96adaad8 diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index f0f3b99ff8dff..f5dcc72ab6889 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -18,11 +18,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c1 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb -https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda#791365c5f65975051e4e017b5da3abf5 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda#f9f81ea472684d75b9dd8d0b328cf655 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 +https://conda.anaconda.org/conda-forge/linux-64/libattr-2.5.2-hb03c661_1.conda#7e7f0a692eb62b95d3010563e7f963b6 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb @@ -50,14 +50,14 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 +https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-hb03c661_1.conda#9bb149f49de3f322fca007283eaa2725 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.8.23-hd590300_0.conda#cc4f06f7eedb1523f3b83fd0fb3942ff https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 -https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.0.9-h166bdaf_9.conda#61641e239f96eae2b8492dc7e755828c -https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 @@ -87,13 +87,14 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1.conda#f883d61afbc95c50f7b3f62546da4235 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda#d1db1b8be7c3a8983dcbbbfe4f0765de https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.conda#081aa22f4581c08e4372b0b6c2f8478e https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.conda#1f0a03af852a9659ed2bf08f2f1704fd +https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 @@ -102,7 +103,6 @@ https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.con https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda#1d4c18d75c51ed9d00092a891a547a7d https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h8fd135c_2.conda#bbf65f7688512872f063810623b755dc https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 @@ -127,6 +127,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.co https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda#1d4c18d75c51ed9d00092a891a547a7d https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -154,20 +155,20 @@ https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a8 https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.9-py311h724c32c_2.conda#4089f739463c798e10d8644bc34e24de +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.0-hf7376ad_0.conda#213f51bbcce2964ff2ec00d0fdd38541 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.2-pyhcf101f3_0.conda#4fefefb892ce9cc1539405bec2f1a6cd +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 @@ -175,7 +176,7 @@ https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda# https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda#978d03388b62173b8e6f79162cf52b86 https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -192,7 +193,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py311h3778330_0.conda#6b1b19bdc407007d5e41079eab797ddc https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.61.1-py311h3778330_0.conda#2e8ccb31890a95d5cd90d74a11c7d5e2 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae @@ -207,7 +208,7 @@ https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-12.3.2-h6083320_0.conda#d170a70fc1d5c605fcebdf16851bd54a +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.1.1-h6083320_0.conda#56d73078fe51aee26b7934cb1378d464 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 02c1194c1e4ec..d7ea66215a420 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -28,7 +28,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 -https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h0aef613_1.conda#9344155d33912347b37f0ae6c410a835 +https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 @@ -39,7 +39,7 @@ https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13-hedf47ba_0.conda#92a194f6d6511e91afbdd2944491ea8e +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 @@ -69,14 +69,14 @@ https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb diff --git a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock index 53eeacbef001d..e4249e00804f0 100644 --- a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock @@ -22,7 +22,7 @@ https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda#4cb8e https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_0.conda#3d3caf4ccc6415023640af4b1b33060a https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda#b785694dd3ec77a011ccf0c24725382b https://conda.anaconda.org/conda-forge/win-64/icu-78.2-h637d24d_0.conda#0ee3bb487600d5e71ab7d28951b2016a -https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h6470a55_1.conda#c1b81da6d29a14b542da14a36c9fbf3f +https://conda.anaconda.org/conda-forge/win-64/lerc-4.1.0-hd936e49_0.conda#54b231d595bc1ff9bff668dd443ee012 https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda#444b0a45bbd1cb24f82eedb56721b9c4 https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda#1c1ced969021592407f16ada4573586d @@ -62,7 +62,7 @@ https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4 https://conda.anaconda.org/conda-forge/win-64/cython-3.2.4-py311h9990397_0.conda#74e8c626533a6011c33fdf2a47fbf71c https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.9-py311h275cad7_2.conda#e9eb24a8d111be48179bf82a9e0e13ca +https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.5.0-py311h275cad7_0.conda#e50d15677f2673c114f18d60c88d9196 https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a8eebe_openblas.conda#1db756824d3aec6a25599c7821cb3e24 https://conda.anaconda.org/conda-forge/win-64/libclang13-22.1.0-default_ha2db4b5_0.conda#7ad437870ea7d487e1b0e663503b6b1d https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.2-hdbac1cb_0.conda#c21a474a38982cdb56b3454cf4f78389 @@ -71,13 +71,13 @@ https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hd232482_openbl https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h779ef1b_0.conda#be3843e412c9f9d697958aa68c72d09d -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.1-pyhcf101f3_0.conda#6c07238c531b1f93603c6908d1a4ef4f +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.0-pyh332efcf_0.conda#1d00d46c634177fc8ede8b99d6089239 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 @@ -101,7 +101,7 @@ https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bd https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-5_ha590de0_openblas.conda#e19a49b16cf765708e6d8676a50f74e1 https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h275cad7_4.conda#9fb1f375c704c5287c97c60f6a88d137 https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda#a0b1b87e871011ca3b783bbf410bc39f -https://conda.anaconda.org/conda-forge/win-64/fonttools-4.61.1-py311h3f79411_0.conda#e5445b571c6e2919198c40c6db3d25c5 +https://conda.anaconda.org/conda-forge/win-64/fonttools-4.62.0-py311h3f79411_0.conda#5abfb5569386a6a7e8f6f88d4845af10 https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.2-h57928b3_0.conda#c360b467564b875a9f5dc481b8726cee https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.1-py311h17b8079_0.conda#b17fe050184f2f7fd03e094a5fdc56ae @@ -113,7 +113,7 @@ https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda#52ea https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/win-64/harfbuzz-12.3.2-h5a1b470_0.conda#fb5d7b9527b418f83e3316f3e6daa8a2 +https://conda.anaconda.org/conda-forge/win-64/harfbuzz-13.1.1-h5a1b470_0.conda#987061cd0ee71af3493e5dbc6cbde56b https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.10.2-h35725d6_5.conda#193fcaa5c64aa817cd8cde92afbc9d4e -https://conda.anaconda.org/conda-forge/win-64/pyside6-6.10.2-py311hf70c7b4_0.conda#8512eff5fd02b371f36b0da26f5a78ee +https://conda.anaconda.org/conda-forge/win-64/pyside6-6.10.2-py311he824864_0.conda#de20381acf972a7a48692efd4614e53e https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py311h1ea47a8_0.conda#64fe28aa2486e41918239d385336e88e diff --git a/build_tools/github/ubuntu_atlas_lock.txt b/build_tools/github/ubuntu_atlas_lock.txt index 7803f0d8406c4..99eeff36b60bc 100644 --- a/build_tools/github/ubuntu_atlas_lock.txt +++ b/build_tools/github/ubuntu_atlas_lock.txt @@ -12,7 +12,7 @@ iniconfig==2.3.0 # via pytest joblib==1.3.0 # via -r build_tools/github/ubuntu_atlas_requirements.txt -meson==1.10.1 +meson==1.10.2 # via meson-python meson-python==0.19.0 # via -r build_tools/github/ubuntu_atlas_requirements.txt From 811b5883607253f8f619ab8b86f0944cde3970d6 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Mon, 16 Mar 2026 10:56:30 +0100 Subject: [PATCH 288/462] ENH change default scoring to log loss in LogisticRegressionCV (#33333) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> Co-authored-by: Omar Salman <omar.salman@arbisoft.com> --- .../upcoming_changes/changed-models/33333.api | 8 ++ .../sklearn.linear_model/33333.api | 8 ++ .../preprocessing/plot_scaling_importance.py | 15 ++- sklearn/linear_model/_logistic.py | 43 ++++-- sklearn/linear_model/tests/test_common.py | 10 +- sklearn/linear_model/tests/test_logistic.py | 126 +++++++++++++++--- sklearn/tests/test_docstring_parameters.py | 6 +- .../test_metaestimators_metadata_routing.py | 7 +- .../utils/_test_common/instance_generator.py | 5 +- sklearn/utils/tests/test_pprint.py | 8 +- 10 files changed, 199 insertions(+), 37 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/changed-models/33333.api create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33333.api diff --git a/doc/whats_new/upcoming_changes/changed-models/33333.api b/doc/whats_new/upcoming_changes/changed-models/33333.api new file mode 100644 index 0000000000000..684030b2e51d6 --- /dev/null +++ b/doc/whats_new/upcoming_changes/changed-models/33333.api @@ -0,0 +1,8 @@ +- The default value of the `scoring` parameter in + :class:`linear_model.LogisticRegressionCV` will change in version 1.11 from `None`, + i.e. accuracy, to `"neg_log_loss"`. This is a much better default scoring function + as it aligns with the log loss that logistic regression is minimizing + (with regularization). + For the meantime, you can silence the warning for this change by explicitly passing + a value to `scoring`. + By :user:`Christian Lorentzen <lorentzenchr>`. diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33333.api b/doc/whats_new/upcoming_changes/sklearn.linear_model/33333.api new file mode 100644 index 0000000000000..684030b2e51d6 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33333.api @@ -0,0 +1,8 @@ +- The default value of the `scoring` parameter in + :class:`linear_model.LogisticRegressionCV` will change in version 1.11 from `None`, + i.e. accuracy, to `"neg_log_loss"`. This is a much better default scoring function + as it aligns with the log loss that logistic regression is minimizing + (with regularization). + For the meantime, you can silence the warning for this change by explicitly passing + a value to `scoring`. + By :user:`Christian Lorentzen <lorentzenchr>`. diff --git a/examples/preprocessing/plot_scaling_importance.py b/examples/preprocessing/plot_scaling_importance.py index c0f133ee38175..267e4d4e764a4 100644 --- a/examples/preprocessing/plot_scaling_importance.py +++ b/examples/preprocessing/plot_scaling_importance.py @@ -207,14 +207,25 @@ def fit_and_plot_model(X_plot, y, clf, ax): Cs = np.logspace(-5, 5, 20) unscaled_clf = make_pipeline( - pca, LogisticRegressionCV(Cs=Cs, use_legacy_attributes=False, l1_ratios=(0,)) + pca, + LogisticRegressionCV( + Cs=Cs, + use_legacy_attributes=False, + l1_ratios=(0,), # TODO(1.10): remove because it is default now + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + ), ) unscaled_clf.fit(X_train, y_train) scaled_clf = make_pipeline( scaler, pca, - LogisticRegressionCV(Cs=Cs, use_legacy_attributes=False, l1_ratios=(0,)), + LogisticRegressionCV( + Cs=Cs, + use_legacy_attributes=False, + l1_ratios=(0,), # TODO(1.10): remove because it is default now + scoring="neg_log_loss", # TODO(1.11): remove because it is default now, + ), ) scaled_clf.fit(X_train, y_train) diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index 3a9104eb2c300..867e766b57fd6 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -777,11 +777,9 @@ def calc_score(log_reg): else: sig = [] - if (is_binary and "labels" in sig and "pos_label" in sig) or ( - len(classes) >= 3 and "labels" in sig - ): + if "labels" in sig: pos_label_kwarg = {} - if is_binary: + if is_binary and "pos_label" in sig: # see _logistic_regression_path pos_label_kwarg["pos_label"] = classes[-1] scoring = make_scorer( @@ -1533,6 +1531,10 @@ class LogisticRegressionCV(LogisticRegression, LinearClassifierMixin, BaseEstima ``scorer(estimator, X, y)``. See :ref:`scoring_callable` for details. - `None`: :ref:`accuracy <accuracy_score>` is used. + .. versionchanged:: 1.11 + The default will change from None, i.e. accuracy, to 'neg_log_loss' in + version 1.11. + solver : {'lbfgs', 'liblinear', 'newton-cg', 'newton-cholesky', 'sag', 'saga'}, \ default='lbfgs' @@ -1755,14 +1757,17 @@ class of problems. >>> from sklearn.linear_model import LogisticRegressionCV >>> X, y = load_iris(return_X_y=True) >>> clf = LogisticRegressionCV( - ... cv=5, random_state=0, use_legacy_attributes=False, l1_ratios=(0,) + ... cv=5, random_state=0, + ... use_legacy_attributes=False, + ... l1_ratios=(0,), + ... scoring="neg_log_loss", ... ).fit(X, y) >>> clf.predict(X[:2, :]) array([0, 0]) >>> clf.predict_proba(X[:2, :]).shape (2, 3) >>> clf.score(X, y) - 0.98... + -0.041... """ _parameter_constraints: dict = {**LogisticRegression._parameter_constraints} @@ -1775,7 +1780,12 @@ class of problems. "Cs": [Interval(Integral, 1, None, closed="left"), "array-like"], "l1_ratios": ["array-like", None, Hidden(StrOptions({"warn"}))], "cv": ["cv_object"], - "scoring": [StrOptions(set(get_scorer_names())), callable, None], + "scoring": [ + StrOptions(set(get_scorer_names())), + callable, + None, + Hidden(StrOptions({"warn"})), + ], "refit": ["boolean"], "penalty": [ StrOptions({"l1", "l2", "elasticnet"}), @@ -1794,7 +1804,7 @@ def __init__( cv=None, dual=False, penalty="deprecated", - scoring=None, + scoring="warn", solver="lbfgs", tol=1e-4, max_iter=100, @@ -1897,6 +1907,19 @@ def fit(self, X, y, sample_weight=None, **params): FutureWarning, ) + if self.scoring == "warn": + warnings.warn( + "The default value of the parameter 'scoring' will change from None, " + "i.e. accuracy, to 'neg_log_loss' in version 1.11. To silence this " + "warning, explicitly set the scoring parameter: " + "scoring='neg_log_loss' for the new, scoring='accuracy' or " + "scoring=None for the old default.", + FutureWarning, + ) + scoring = None + else: + scoring = self.scoring + if self.use_legacy_attributes == "warn": warnings.warn( f"The fitted attributes of {self.__class__.__name__} will be " @@ -2043,7 +2066,7 @@ def fit(self, X, y, sample_weight=None, **params): max_iter=self.max_iter, verbose=self.verbose, class_weight=class_weight, - scoring=self.scoring, + scoring=scoring, intercept_scaling=self.intercept_scaling, random_state=self.random_state, max_squared_sum=max_squared_sum, @@ -2310,6 +2333,8 @@ def _get_scorer(self): """Get the scorer based on the scoring method specified. The default scoring method is `accuracy`. """ + if self.scoring == "warn": # TODO(1.11): remove + return get_scorer("accuracy") scoring = self.scoring or "accuracy" return get_scorer(scoring) diff --git a/sklearn/linear_model/tests/test_common.py b/sklearn/linear_model/tests/test_common.py index a3796c9c0d7e1..6858e8e2b45c2 100644 --- a/sklearn/linear_model/tests/test_common.py +++ b/sklearn/linear_model/tests/test_common.py @@ -72,7 +72,12 @@ LogisticRegression(l1_ratio=0.5, solver="saga", tol=1e-15), marks=pytest.mark.xfail(reason="Missing importance sampling scheme"), ), - LogisticRegressionCV(tol=1e-6, use_legacy_attributes=False, l1_ratios=(0,)), + LogisticRegressionCV( + tol=1e-6, + use_legacy_attributes=False, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + l1_ratios=(0,), # TODO(1.10): remove because it is default now + ), MultiTaskElasticNet(), MultiTaskElasticNetCV(), MultiTaskLasso(), @@ -217,7 +222,8 @@ def test_linear_model_regressor_coef_shape(Regressor, ndim): { "solver": "newton-cholesky", "use_legacy_attributes": False, - "l1_ratios": (0,), + "l1_ratios": (0,), # TODO(1.10): remove + "scoring": "neg_log_loss", # TODO(1.11): remove }, ), (PassiveAggressiveClassifier, {}), diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index da5818b1d7139..d908edcc799f4 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -170,6 +170,8 @@ def test_logistic_glmnet(solver): ) +# TODO(1.11): remove filterwarnings with change of default scoring +@pytest.mark.filterwarnings("ignore:The default value.*scoring.*:FutureWarning") # TODO(1.10): remove filterwarnings with deprecation period of use_legacy_attributes @pytest.mark.filterwarnings("ignore:.*use_legacy_attributes.*:FutureWarning") @pytest.mark.parametrize("LR", [LogisticRegression, LogisticRegressionCV]) @@ -219,6 +221,8 @@ def test_check_solver_option(LR): lr.fit(X, y) +# TODO(1.11): remove filterwarnings with change of default scoring +@pytest.mark.filterwarnings("ignore:The default value.*scoring.*:FutureWarning") # TODO(1.10): remove test with removal of penalty @pytest.mark.filterwarnings("ignore::FutureWarning") @pytest.mark.parametrize( @@ -439,6 +443,7 @@ def test_logistic_cv(global_random_seed, use_legacy_attributes): random_state=global_random_seed, solver="liblinear", cv=n_cv, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now use_legacy_attributes=use_legacy_attributes, ) lr_cv.fit(X_ref, y) @@ -578,9 +583,17 @@ def test_multinomial_logistic_regression_string_inputs(): y = np.array(y) - 1 # Test for string labels lr = LogisticRegression() - lr_cv = LogisticRegressionCV(Cs=3, use_legacy_attributes=False) + lr_cv = LogisticRegressionCV( + Cs=3, + use_legacy_attributes=False, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + ) lr_str = LogisticRegression() - lr_cv_str = LogisticRegressionCV(Cs=3, use_legacy_attributes=False) + lr_cv_str = LogisticRegressionCV( + Cs=3, + use_legacy_attributes=False, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + ) lr.fit(X_ref, y) lr_cv.fit(X_ref, y) @@ -601,9 +614,11 @@ def test_multinomial_logistic_regression_string_inputs(): assert set(np.unique(lr_cv_str.predict(X_ref))) <= {"bar", "baz", "foo"} # We use explicit Cs parameter to make sure all labels are predicted for each C. - lr_cv_str = LogisticRegressionCV(Cs=[1, 2, 10], use_legacy_attributes=False).fit( - X_ref, y_str - ) + lr_cv_str = LogisticRegressionCV( + Cs=[1, 2, 10], + use_legacy_attributes=False, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + ).fit(X_ref, y_str) assert sorted(np.unique(lr_cv_str.predict(X_ref))) == ["bar", "baz", "foo"] # Make sure class weights can be given with string labels @@ -628,7 +643,10 @@ def test_multinomial_cv_iris(use_legacy_attributes): # Train clf on the original dataset clf = LogisticRegressionCV( - cv=precomputed_folds, solver="newton-cholesky", use_legacy_attributes=True + cv=precomputed_folds, + solver="newton-cholesky", + use_legacy_attributes=True, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now ) clf.fit(X, y) @@ -645,6 +663,7 @@ def test_multinomial_cv_iris(use_legacy_attributes): clf_ovr = GridSearchCV( OneVsRestClassifier(LogisticRegression(solver="newton-cholesky")), {"estimator__C": np.logspace(-4, 4, num=10)}, + scoring="neg_log_loss", ).fit(X, y) for solver in ["lbfgs", "newton-cg", "sag", "saga"]: max_iter = 500 if solver in ["sag", "saga"] else 30 @@ -654,6 +673,7 @@ def test_multinomial_cv_iris(use_legacy_attributes): random_state=42, tol=1e-3 if solver in ["sag", "saga"] else 1e-2, cv=2, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now use_legacy_attributes=use_legacy_attributes, ) if solver == "lbfgs": @@ -723,7 +743,11 @@ def test_multinomial_cv_iris(use_legacy_attributes): assert len(np.unique(y[test])) == 1 assert set(y[train]) & set(y[test]) == set() - clf = LogisticRegressionCV(cv=cv, use_legacy_attributes=False).fit(X, y) + clf = LogisticRegressionCV( + cv=cv, + use_legacy_attributes=False, + scoring="accuracy", + ).fit(X, y) # We expect accuracy to be exactly 0 because train and test sets have # non-overlapping labels assert np.all(clf.scores_ == 0.0) @@ -872,6 +896,7 @@ def test_logistic_regression_solvers_multiclass(fit_intercept): solver=solver, max_iter=solver_max_iter.get(solver, 100), use_legacy_attributes=False, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now **params, ).fit(X, y) for solver in set(SOLVERS) - set(["liblinear"]) @@ -968,9 +993,19 @@ def test_logistic_cv_sparse(global_random_seed, solver, csr_container): X[X < 0.0] = 0.0 # make it a bit sparse params = dict(Cs=[1e-1, 1, 1e1], max_iter=10_000, tol=1e-7, random_state=42) - clf = LogisticRegressionCV(solver=solver, use_legacy_attributes=False, **params) + clf = LogisticRegressionCV( + solver=solver, + use_legacy_attributes=False, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + **params, + ) clf.fit(X, y) - clfs = LogisticRegressionCV(solver=solver, use_legacy_attributes=False, **params) + clfs = LogisticRegressionCV( + solver=solver, + use_legacy_attributes=False, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + **params, + ) clfs.fit(csr_container(X), y) rtol = 6e-2 if solver in ("sag", "saga") else 1e-5 @@ -1003,7 +1038,11 @@ def test_logistic_regressioncv_class_weights(weight, class_weight, global_random tol=1e-8, use_legacy_attributes=False, ) - clf_lbfgs = LogisticRegressionCV(solver="lbfgs", **params) + clf_lbfgs = LogisticRegressionCV( + solver="lbfgs", + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + **params, + ) # XXX: lbfgs' line search can fail and cause a ConvergenceWarning for some # 10% of the random seeds, but only on specific platforms (in particular @@ -1016,7 +1055,11 @@ def test_logistic_regressioncv_class_weights(weight, class_weight, global_random clf_lbfgs.fit(X, y) for solver in set(SOLVERS) - set(["lbfgs", "liblinear", "newton-cholesky"]): - clf = LogisticRegressionCV(solver=solver, **params) + clf = LogisticRegressionCV( + solver=solver, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + **params, + ) if solver in ("sag", "saga"): clf.set_params( tol=1e-18, max_iter=10000, random_state=global_random_seed + 1 @@ -1028,6 +1071,8 @@ def test_logistic_regressioncv_class_weights(weight, class_weight, global_random ) +# TODO(1.11): remove filterwarnings with change of default scoring +@pytest.mark.filterwarnings("ignore:The default value.*scoring.*:FutureWarning") # TODO(1.10): remove filterwarnings with deprecation period of use_legacy_attributes @pytest.mark.filterwarnings("ignore:.*use_legacy_attributes.*:FutureWarning") @pytest.mark.parametrize("problem", ("single", "cv")) @@ -1330,6 +1375,7 @@ def test_logistic_regression_cv_refit(global_random_seed, l1_ratio): Cs=[1.0], l1_ratios=(l1_ratio,), refit=True, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now use_legacy_attributes=False, **common_params, ) @@ -1436,6 +1482,7 @@ def test_n_iter(solver, use_legacy_attributes): cv=n_cv_fold, random_state=42, use_legacy_attributes=use_legacy_attributes, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now ) clf_cv.fit(X, y_bin) if use_legacy_attributes: @@ -1818,6 +1865,7 @@ def test_LogisticRegressionCV_GridSearchCV_elastic_net(n_classes): cv=cv, random_state=0, tol=1e-2, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now use_legacy_attributes=False, ) lrcv.fit(X, y) @@ -1828,7 +1876,7 @@ def test_LogisticRegressionCV_GridSearchCV_elastic_net(n_classes): random_state=0, tol=1e-2, ) - gs = GridSearchCV(lr, param_grid, cv=cv) + gs = GridSearchCV(lr, param_grid, cv=cv, scoring="neg_log_loss") gs.fit(X, y) assert gs.best_params_["l1_ratio"] == lrcv.l1_ratio_ @@ -1857,6 +1905,7 @@ def test_LogisticRegressionCV_no_refit(l1_ratios, n_classes): random_state=0, tol=1e-2, refit=False, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now use_legacy_attributes=True, ) lrcv.fit(X, y) @@ -1896,6 +1945,7 @@ def test_LogisticRegressionCV_elasticnet_attribute_shapes(n_classes): cv=n_folds, random_state=0, tol=1e-2, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now use_legacy_attributes=True, ) lrcv.fit(X, y) @@ -1923,7 +1973,10 @@ def test_LogisticRegressionCV_on_folds(): """Test that LogisticRegressionCV produces the correct result on a fold.""" X, y = iris.data, iris.target lrcv = LogisticRegressionCV( - solver="newton-cholesky", tol=1e-8, use_legacy_attributes=True + solver="newton-cholesky", + tol=1e-8, + use_legacy_attributes=True, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now ).fit(X, y) # Reproduce the exact same split as default LogisticRegressionCV. @@ -2241,6 +2294,7 @@ def test_scores_attribute_layout_elasticnet(): random_state=0, max_iter=250, tol=1e-3, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now use_legacy_attributes=True, ) lrcv.fit(X, y) @@ -2258,8 +2312,10 @@ def test_scores_attribute_layout_elasticnet(): tol=1e-3, ) - avg_score_lr = cross_val_score(lr, X, y, cv=cv).mean() - assert avg_scores_lrcv[i, j] == pytest.approx(avg_score_lr) + avg_score_lr = cross_val_score( + lr, X, y, cv=cv, scoring="neg_log_loss" + ).mean() + assert avg_scores_lrcv[i, j] == pytest.approx(avg_score_lr, rel=1e-3) @pytest.mark.parametrize("solver", ["lbfgs", "newton-cg", "newton-cholesky"]) @@ -2498,7 +2554,10 @@ def test_passing_params_without_enabling_metadata_routing(): """Test that the right error message is raised when metadata params are passed while not supported when `enable_metadata_routing=False`.""" X, y = make_classification(n_samples=10, random_state=0) - lr_cv = LogisticRegressionCV(use_legacy_attributes=False) + lr_cv = LogisticRegressionCV( + use_legacy_attributes=False, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + ) msg = "is only supported if enable_metadata_routing=True" with config_context(enable_metadata_routing=False): @@ -2551,6 +2610,8 @@ def test_newton_cholesky_fallback_to_lbfgs(): assert n_iter_nc_limited == lr_nc_limited.max_iter - 1 +# TODO(1.11): remove filterwarnings with change of default scoring +@pytest.mark.filterwarnings("ignore:The default value.*scoring.*:FutureWarning") # TODO(1.10): remove filterwarnings with deprecation period of use_legacy_attributes @pytest.mark.filterwarnings("ignore:.*use_legacy_attributes.*:FutureWarning") @pytest.mark.parametrize("Estimator", [LogisticRegression, LogisticRegressionCV]) @@ -2562,6 +2623,7 @@ def test_liblinear_multiclass_raises(Estimator): # TODO(1.10): remove after deprecation cycle of penalty. +@pytest.mark.filterwarnings("ignore:The default value.*scoring.*:FutureWarning") @pytest.mark.filterwarnings("ignore:.*default.*use_legacy_attributes.*:FutureWarning") @pytest.mark.parametrize("est", [LogisticRegression, LogisticRegressionCV]) def test_penalty_deprecated(est): @@ -2576,7 +2638,9 @@ def test_penalty_deprecated(est): # TODO(1.10): use_legacy_attributes gets deprecated def test_logisticregressioncv_warns_with_use_legacy_attributes(): X, y = make_classification(n_classes=3, n_samples=50, n_informative=6) - lr = LogisticRegressionCV() + lr = LogisticRegressionCV( + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + ) msg = "The default value of use_legacy_attributes will change from True" with pytest.warns(FutureWarning, match=msg): lr.fit(X, y) @@ -2594,12 +2658,17 @@ def test_l1_ratio_None_deprecated(): with pytest.warns(FutureWarning, match=msg): lr.fit(X, y) - lr = LogisticRegressionCV() + lr = LogisticRegressionCV( + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + ) msg = "The default value for l1_ratios will change" with pytest.warns(FutureWarning, match=msg): lr.fit(X, y) - lr = LogisticRegressionCV(l1_ratios=None) + lr = LogisticRegressionCV( + l1_ratios=None, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + ) msg = "'l1_ratios=None' was deprecated" with pytest.warns(FutureWarning, match=msg): lr.fit(X, y) @@ -2758,3 +2827,22 @@ def test_lr_penalty_l1ratio_incompatible(penalty, l1_ratio): msg = f"Inconsistent values: penalty={penalty} with l1_ratio={l1_ratio}" with pytest.warns(UserWarning, match=msg): lr.fit(X, y) + + +# TODO(1.11): remove when default of scoring has changed +@pytest.mark.filterwarnings("ignore:.*default.*use_legacy_attributes.*:FutureWarning") +def test_lr_scoring_warns(): + """Check that scoring raises a warning.""" + X, y = make_classification(n_samples=20) + lr = LogisticRegressionCV(l1_ratios=[0]) + msg = "The default value of the parameter 'scoring' will change" + with pytest.warns(FutureWarning, match=msg): + lr.fit(X, y) + + +# TODO(1.11): remove test when default of scoring has changed +@pytest.mark.filterwarnings("ignore:The default value.*scoring.*:FutureWarning") +def test_get_default_scorer(): + """Test that LogisticRegressionCV gets correct default scorer.""" + lr = LogisticRegressionCV() + assert lr._get_scorer()._score_func.__name__ == "accuracy_score" diff --git a/sklearn/tests/test_docstring_parameters.py b/sklearn/tests/test_docstring_parameters.py index ad90ec99e602e..4b6a2636f0831 100644 --- a/sklearn/tests/test_docstring_parameters.py +++ b/sklearn/tests/test_docstring_parameters.py @@ -232,10 +232,12 @@ def test_fit_docstring_attributes(name, Estimator): elif Estimator.__name__ == "MDS": # default raises a FutureWarning est.set_params(n_init=1, init="random") - # TODO(1.10) remove + # TODO(1.10) remove l1_ratios + # TODO(1.11) remove completely elif Estimator.__name__ == "LogisticRegressionCV": # default 'l1_ratios' value creates a FutureWarning - est.set_params(l1_ratios=(0,)) + # default 'scoring' value creates a FutureWarning + est.set_params(l1_ratios=(0,), scoring="neg_log_loss") # Low max iter to speed up tests: we are only interested in checking the existence # of fitted attributes. This should be invariant to whether it has converged or not. diff --git a/sklearn/tests/test_metaestimators_metadata_routing.py b/sklearn/tests/test_metaestimators_metadata_routing.py index ecd9808bd9749..70ed1ba237313 100644 --- a/sklearn/tests/test_metaestimators_metadata_routing.py +++ b/sklearn/tests/test_metaestimators_metadata_routing.py @@ -137,7 +137,12 @@ }, { "metaestimator": LogisticRegressionCV, - "init_args": {"use_legacy_attributes": False, "l1_ratios": (0,)}, + # TODO(1.11): remove scoring because neg_log_loss is default now + "init_args": { + "use_legacy_attributes": False, + "l1_ratios": (0,), + "scoring": "neg_log_loss", + }, "X": X, "y": y, "scorer_name": "scoring", diff --git a/sklearn/utils/_test_common/instance_generator.py b/sklearn/utils/_test_common/instance_generator.py index cdd9c78881695..4f2c43a0b106e 100644 --- a/sklearn/utils/_test_common/instance_generator.py +++ b/sklearn/utils/_test_common/instance_generator.py @@ -349,7 +349,10 @@ LinearSVC: dict(max_iter=20), LinearSVR: dict(max_iter=20), LocallyLinearEmbedding: dict(max_iter=5), - LogisticRegressionCV: dict(max_iter=5, cv=3, use_legacy_attributes=False), + # TODO(1.11): remove scoring because it is default now + LogisticRegressionCV: dict( + max_iter=5, cv=3, use_legacy_attributes=False, scoring="neg_log_loss" + ), LogisticRegression: dict(max_iter=5), MDS: dict(n_init=2, max_iter=5), # In the case of check_fit2d_1sample, bandwidth is set to None and diff --git a/sklearn/utils/tests/test_pprint.py b/sklearn/utils/tests/test_pprint.py index c8b2d9d195681..cb5eb7fffca60 100644 --- a/sklearn/utils/tests/test_pprint.py +++ b/sklearn/utils/tests/test_pprint.py @@ -280,7 +280,13 @@ def test_changed_only(): assert imputer.__repr__() == expected # make sure array parameters don't throw error (see #13583) - repr(LogisticRegressionCV(Cs=np.array([0.1, 1]), use_legacy_attributes=False)) + repr( + LogisticRegressionCV( + Cs=np.array([0.1, 1]), + use_legacy_attributes=False, + scoring="neg_log_loss", # TODO(1.11): remove because it is default now + ) + ) @config_context(print_changed_only=False) From 40eb9ba71417243429fef1fb45032aa9a061e26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Est=C3=A8ve?= <loic.esteve@ymail.com> Date: Mon, 16 Mar 2026 11:46:33 +0100 Subject: [PATCH 289/462] TST Use clone to avoid failure for free-threaded (#33553) --- sklearn/decomposition/tests/test_dict_learning.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sklearn/decomposition/tests/test_dict_learning.py b/sklearn/decomposition/tests/test_dict_learning.py index 80bcd92480ae7..4b53c942d23fa 100644 --- a/sklearn/decomposition/tests/test_dict_learning.py +++ b/sklearn/decomposition/tests/test_dict_learning.py @@ -978,6 +978,7 @@ def test_dict_learning_online_numerical_consistency(method): ) def test_get_feature_names_out(estimator): """Check feature names for dict learning estimators.""" + estimator = clone(estimator) estimator.fit(X) n_components = X.shape[1] From cbeeaeb399dc0b72d9b2f793204ed7ff39b80c70 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Tue, 17 Mar 2026 03:56:53 +0100 Subject: [PATCH 290/462] FIX revert pyplot import changes to prevent import issues (#33517) Co-authored-by: Lucy Liu <jliu176@gmail.com> --- sklearn/inspection/_plot/decision_boundary.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index e5c3f11eee17c..8c974706edfcb 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -303,6 +303,7 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar """ check_matplotlib_support("DecisionBoundaryDisplay.plot") import matplotlib as mpl + import matplotlib.pyplot as plt if plot_method not in ("contourf", "contour", "pcolormesh"): raise ValueError( @@ -311,7 +312,7 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar ) if ax is None: - _, ax = mpl.pyplot.subplots() + _, ax = plt.subplots() plot_func = getattr(ax, plot_method) if self.n_classes == 2: From 139323a85b28de70f8b1876670f89b7ae56da3cd Mon Sep 17 00:00:00 2001 From: Tim Head <betatim@gmail.com> Date: Tue, 17 Mar 2026 12:38:26 +0100 Subject: [PATCH 291/462] Add mixed input support to more metrics `mean_tweedie_deviance`, `d2_tweedie_score`, `d2_pinball_score` (#33552) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> --- sklearn/metrics/_regression.py | 11 ++++++----- sklearn/metrics/tests/test_common.py | 12 ++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/sklearn/metrics/_regression.py b/sklearn/metrics/_regression.py index ed4c2d6223d68..c70df88e098e4 100644 --- a/sklearn/metrics/_regression.py +++ b/sklearn/metrics/_regression.py @@ -1455,7 +1455,8 @@ def mean_tweedie_deviance(y_true, y_pred, *, sample_weight=None, power=0): >>> mean_tweedie_deviance(y_true, y_pred, power=1) 1.4260... """ - xp, _ = get_namespace(y_true, y_pred) + xp, _, device = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) y_type, y_true, y_pred, sample_weight, _ = _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput=None, xp=xp ) @@ -1667,7 +1668,8 @@ def d2_tweedie_score(y_true, y_pred, *, sample_weight=None, power=0): >>> d2_tweedie_score(y_true, y_true, power=2) 1.0 """ - xp, _ = get_namespace(y_true, y_pred) + xp, _, device = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) y_type, y_true, y_pred, sample_weight, _ = _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput=None, xp=xp @@ -1811,9 +1813,8 @@ def d2_pinball_score( >>> grid.best_params_ {'fit_intercept': True} """ - xp, _, device_ = get_namespace_and_device( - y_true, y_pred, sample_weight, multioutput - ) + xp, _, device_ = get_namespace_and_device(y_pred) + y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device_) _, y_true, y_pred, sample_weight, multioutput = ( _check_reg_targets_with_floating_dtype( y_true, y_pred, sample_weight, multioutput, xp=xp diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index c55668c72fe6c..7e6886d8639bd 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -155,6 +155,7 @@ "mean_poisson_deviance": mean_poisson_deviance, "mean_gamma_deviance": mean_gamma_deviance, "mean_compound_poisson_deviance": partial(mean_tweedie_deviance, power=1.4), + "mean_tweedie_deviance": mean_tweedie_deviance, "d2_tweedie_score": partial(d2_tweedie_score, power=1.4), "d2_pinball_score": d2_pinball_score, # The default `alpha=0.5` (median) masks differences between quantile methods, @@ -525,6 +526,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "macro_f1_score", "weighted_recall_score", "mean_squared_log_error", + "mean_tweedie_deviance", "root_mean_squared_error", "root_mean_squared_log_error", # P = R = F = accuracy in multiclass case @@ -624,17 +626,27 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): "average_precision_score", "brier_score_loss", "confusion_matrix_at_thresholds", + "d2_absolute_error_score", "d2_brier_score", "d2_log_loss_score", + "d2_pinball_score", + "d2_pinball_score_01", + "d2_pinball_score_09", + "d2_tweedie_score", "explained_variance_score", "f1_score", "log_loss", "max_error", "mean_absolute_error", "mean_absolute_percentage_error", + "mean_compound_poisson_deviance", + "mean_gamma_deviance", + "mean_normal_deviance", "mean_pinball_loss", + "mean_poisson_deviance", "mean_squared_error", "mean_squared_log_error", + "mean_tweedie_deviance", "median_absolute_error", "multilabel_confusion_matrix", "precision_score", From a8c13a2416b61bbbfe33a9ffe532458103a899af Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Tue, 17 Mar 2026 14:06:50 +0100 Subject: [PATCH 292/462] FEA Add array API support for PoissonRegressor with LBFGS (#33348) Co-authored-by: Omar Salman <omar.salman@arbisoft.com> Co-authored-by: Omar Salman <omar.salman2007@gmail.com> Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> --- doc/modules/array_api.rst | 1 + .../array-api/33348.feature.rst | 3 + sklearn/_loss/loss.py | 413 ++++++++++++------ sklearn/_loss/tests/test_loss.py | 17 +- sklearn/calibration.py | 5 +- sklearn/linear_model/_glm/glm.py | 68 ++- sklearn/linear_model/_glm/tests/test_glm.py | 113 ++++- sklearn/linear_model/_linear_loss.py | 4 +- sklearn/linear_model/_logistic.py | 6 +- 9 files changed, 458 insertions(+), 172 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/33348.feature.rst diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index 82cd26cf497a0..a2475e199954f 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -133,6 +133,7 @@ Estimators `svd_solver="randomized"` (`svd_solver="randomized"` only if `power_iteration_normalizer="QR"`)) - :class:`kernel_approximation.Nystroem` - :class:`linear_model.LogisticRegression` (with `solver="lbfgs"`) +- :class:`linear_model.PoissonRegressor` (with `solver="lbfgs"`) - :class:`linear_model.Ridge` (with `solver="svd"`) - :class:`linear_model.RidgeCV` (see :ref:`device_support_for_float64`) - :class:`linear_model.RidgeClassifier` (with `solver="svd"`) diff --git a/doc/whats_new/upcoming_changes/array-api/33348.feature.rst b/doc/whats_new/upcoming_changes/array-api/33348.feature.rst new file mode 100644 index 0000000000000..a390ccc1ddb8e --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/33348.feature.rst @@ -0,0 +1,3 @@ +- :class:`linear_model.PoissonRegressor` now supports array API compatible inputs + with `solver="lbfgs"`. + By :user:`Christian Lorentzen <lorentzenchr>` and :user:`Omar Salman <OmarManzoor>`. diff --git a/sklearn/_loss/loss.py b/sklearn/_loss/loss.py index 429745a0c5462..c2b53fa3d3cd4 100644 --- a/sklearn/_loss/loss.py +++ b/sklearn/_loss/loss.py @@ -45,13 +45,12 @@ LogLink, MultinomialLogit, ) +from sklearn.externals.array_api_extra import one_hot from sklearn.utils import check_scalar from sklearn.utils._array_api import ( _average, _logsumexp, _ravel, - get_namespace, - get_namespace_and_device, ) from sklearn.utils.extmath import softmax from sklearn.utils.stats import _weighted_percentile @@ -97,15 +96,29 @@ class BaseLoss: Parameters ---------- + closs: CyLossFunction + For example, a CyLossFunction; hence the name "c"loss. + link : BaseLink sample_weight : {None, ndarray} If sample_weight is None, the hessian might be constant. n_classes : {None, int} The number of classes for classification, else None. + xp : module, default=None + Array namespace module. + device : device, default=None + A device object (see the "Device Support" section of the array API spec). Attributes ---------- closs: CyLossFunction + For example, a CyLossFunction; hence the name "c"loss. link : BaseLink + n_classes : {None, int} + The number of classes for classification, else None. + xp : module or None + Array namespace module. Ignored by the Cython implementation. + device : device or None + A device object. Ignored by the Cython implementation. interval_y_true : Interval Valid interval for y_true interval_y_pred : Interval @@ -134,12 +147,14 @@ class BaseLoss: differentiable = True is_multiclass = False - def __init__(self, closs, link, n_classes=None): + def __init__(self, closs, link, n_classes=None, xp=None, device=None): self.closs = closs self.link = link + self.n_classes = n_classes + self.xp = xp # simplifies array API versions + self.device = device # simplifies array API versions self.approx_hessian = False self.constant_hessian = False - self.n_classes = n_classes self.interval_y_true = Interval(-np.inf, np.inf, False, False) self.interval_y_pred = self.link.interval_y_pred @@ -384,9 +399,7 @@ def gradient_hessian( ) return gradient_out, hessian_out - def __call__( - self, y_true, raw_prediction, sample_weight=None, n_threads=1, xp=None - ): + def __call__(self, y_true, raw_prediction, sample_weight=None, n_threads=1): """Compute the weighted average loss. Parameters @@ -400,8 +413,6 @@ def __call__( Sample weights. n_threads : int, default=1 Might use openmp thread parallelism. - xp : module, default=None - Array namespace module. Ignored by the Cython implementation. Returns ------- @@ -552,8 +563,10 @@ class HalfSquaredError(BaseLoss): half the Normal distribution deviance. """ - def __init__(self, sample_weight=None): - super().__init__(closs=CyHalfSquaredError(), link=IdentityLink()) + def __init__(self, sample_weight=None, xp=None, device=None): + super().__init__( + closs=CyHalfSquaredError(), link=IdentityLink(), xp=xp, device=device + ) self.constant_hessian = sample_weight is None @@ -577,8 +590,10 @@ class AbsoluteError(BaseLoss): differentiable = False - def __init__(self, sample_weight=None): - super().__init__(closs=CyAbsoluteError(), link=IdentityLink()) + def __init__(self, sample_weight=None, xp=None, device=None): + super().__init__( + closs=CyAbsoluteError(), link=IdentityLink(), xp=xp, device=device + ) self.approx_hessian = True self.constant_hessian = sample_weight is None @@ -626,7 +641,7 @@ class PinballLoss(BaseLoss): differentiable = False - def __init__(self, sample_weight=None, quantile=0.5): + def __init__(self, sample_weight=None, quantile=0.5, xp=None, device=None): check_scalar( quantile, "quantile", @@ -638,6 +653,8 @@ def __init__(self, sample_weight=None, quantile=0.5): super().__init__( closs=CyPinballLoss(quantile=float(quantile)), link=IdentityLink(), + xp=xp, + device=device, ) self.approx_hessian = True self.constant_hessian = sample_weight is None @@ -692,7 +709,9 @@ class HuberLoss(BaseLoss): differentiable = False - def __init__(self, sample_weight=None, quantile=0.9, delta=0.5): + def __init__( + self, sample_weight=None, quantile=0.9, delta=0.5, xp=None, device=None + ): check_scalar( quantile, "quantile", @@ -705,6 +724,8 @@ def __init__(self, sample_weight=None, quantile=0.9, delta=0.5): super().__init__( closs=CyHuberLoss(delta=float(delta)), link=IdentityLink(), + xp=xp, + device=device, ) self.approx_hessian = True self.constant_hessian = False @@ -749,8 +770,10 @@ class HalfPoissonLoss(BaseLoss): We also skip the constant term `y_true_i * log(y_true_i) - y_true_i`. """ - def __init__(self, sample_weight=None): - super().__init__(closs=CyHalfPoissonLoss(), link=LogLink()) + def __init__(self, sample_weight=None, xp=None, device=None): + super().__init__( + closs=CyHalfPoissonLoss(), link=LogLink(), xp=xp, device=device + ) self.interval_y_true = Interval(0, np.inf, True, False) def constant_to_optimal_zero(self, y_true, sample_weight=None): @@ -780,8 +803,8 @@ class HalfGammaLoss(BaseLoss): We also skip the constant term `-log(y_true_i) - 1`. """ - def __init__(self, sample_weight=None): - super().__init__(closs=CyHalfGammaLoss(), link=LogLink()) + def __init__(self, sample_weight=None, xp=None, device=None): + super().__init__(closs=CyHalfGammaLoss(), link=LogLink(), xp=xp, device=device) self.interval_y_true = Interval(0, np.inf, False, False) def constant_to_optimal_zero(self, y_true, sample_weight=None): @@ -822,10 +845,12 @@ class HalfTweedieLoss(BaseLoss): the expectation. """ - def __init__(self, sample_weight=None, power=1.5): + def __init__(self, sample_weight=None, power=1.5, xp=None, device=None): super().__init__( closs=CyHalfTweedieLoss(power=float(power)), link=LogLink(), + xp=xp, + device=device, ) if self.closs.power <= 0: self.interval_y_true = Interval(-np.inf, np.inf, False, False) @@ -883,10 +908,12 @@ class HalfTweedieLossIdentity(BaseLoss): the expectation. """ - def __init__(self, sample_weight=None, power=1.5): + def __init__(self, sample_weight=None, power=1.5, xp=None, device=None): super().__init__( closs=CyHalfTweedieLossIdentity(power=float(power)), link=IdentityLink(), + xp=xp, + device=device, ) if self.closs.power <= 0: self.interval_y_true = Interval(-np.inf, np.inf, False, False) @@ -933,11 +960,13 @@ class HalfBinomialLoss(BaseLoss): loss(x_i) = - y_true_i * log(y_pred_i) - (1 - y_true_i) * log(1 - y_pred_i) """ - def __init__(self, sample_weight=None): + def __init__(self, sample_weight=None, xp=None, device=None): super().__init__( closs=CyHalfBinomialLoss(), link=LogitLink(), n_classes=2, + xp=xp, + device=device, ) self.interval_y_true = Interval(0, 1, True, True) @@ -1005,6 +1034,12 @@ class HalfMultinomialLoss(BaseLoss): n_classes : {None, int} The number of classes for classification, else None. + xp : module or None + Array namespace module. Ignored by the Cython implementation. + + device : device or None + A device object. Ignored by the Cython implementation. + References ---------- .. [1] :arxiv:`Simon, Noah, J. Friedman and T. Hastie. @@ -1015,11 +1050,13 @@ class HalfMultinomialLoss(BaseLoss): is_multiclass = True - def __init__(self, sample_weight=None, n_classes=3): + def __init__(self, sample_weight=None, n_classes=3, xp=None, device=None): super().__init__( closs=CyHalfMultinomialLoss(), link=MultinomialLogit(), n_classes=n_classes, + xp=xp, + device=device, ) self.interval_y_true = Interval(0, np.inf, True, False) self.interval_y_pred = Interval(0, 1, False, False) @@ -1172,11 +1209,13 @@ class ExponentialLoss(BaseLoss): + (1 - y_true_i) * sqrt(y_pred_i / (1 - y_pred_i)) """ - def __init__(self, sample_weight=None): + def __init__(self, sample_weight=None, xp=None, device=None): super().__init__( closs=CyExponentialLoss(), link=HalfLogitLink(), n_classes=2, + xp=xp, + device=device, ) self.interval_y_true = Interval(0, 1, True, True) @@ -1225,8 +1264,16 @@ def predict_proba(self, raw_prediction): class ArrayAPILossMixin: """Mixin for loss classes that are compatible with the array API. - Currently this mixin only redefines the `__call__` method such that it - works according to the array API specification. + + Currently this mixin redefines methods: + - __call__(...) + - loss(...) + - loss_gradient(...) + - gradient(...) + + such that they work according to the array API specification. + It uses the attributes self.xp and self.device from BaseLoss and it assumes that + methods self._compute_loss and self._compute_gradient are implemented. """ def __call__( @@ -1235,7 +1282,6 @@ def __call__( raw_prediction, sample_weight=None, n_threads=1, - xp=None, ): """Compute the weighted average loss for the array API losses. @@ -1250,19 +1296,135 @@ def __call__( Sample weights. n_threads : int, default=1 Ignored by the array API implementation. - xp : module, default=None - Array namespace module. Returns ------- loss : float Mean or averaged loss function. """ - xp, _ = get_namespace(y_true, raw_prediction, sample_weight, xp=xp) loss_xp = self.loss( y_true=y_true, raw_prediction=raw_prediction, sample_weight=None ) - return float(_average(loss_xp, weights=sample_weight, xp=xp)) + return float(_average(loss_xp, weights=sample_weight, xp=self.xp)) + + def loss( + self, + y_true, + raw_prediction, + sample_weight=None, + loss_out=None, + n_threads=1, + ): + """Compute the pointwise loss value for each input. + + Parameters + ---------- + y_true : C-contiguous array of shape (n_samples,) + Observed, true target values. + raw_prediction : C-contiguous array of shape (n_samples,) or array of \ + shape (n_samples, n_classes) + Raw prediction values (in link space). + sample_weight : None or C-contiguous array of shape (n_samples,) + Sample weights. + loss_out : None or C-contiguous array of shape (n_samples,) + Ignored by the array API implementation. + n_threads : int, default=1 + Ignored by the array API implementation. + + Returns + ------- + loss : array of shape (n_samples,) + Element-wise loss function. + """ + return self._compute_loss( + y_true=y_true, + raw_prediction=raw_prediction, + sample_weight=sample_weight, + ) + + def loss_gradient( + self, + y_true, + raw_prediction, + sample_weight=None, + loss_out=None, + gradient_out=None, + n_threads=1, + ): + """Compute loss and gradient w.r.t. raw_prediction for each input. + + Parameters + ---------- + y_true : C-contiguous array of shape (n_samples,) + Observed, true target values. + raw_prediction : C-contiguous array of shape (n_samples,) or array of \ + shape (n_samples, n_classes) + Raw prediction values (in link space). + sample_weight : None or C-contiguous array of shape (n_samples,) + Sample weights. + loss_out : None or C-contiguous array of shape (n_samples,) + Ignored by the array API implementation. + gradient_out : None or C-contiguous array of shape (n_samples,) or array \ + of shape (n_samples, n_classes) + Ignored by the array API implementation. + n_threads : int, default=1 + Ignored by the array API implementation. + + Returns + ------- + loss : array of shape (n_samples,) + Element-wise loss function. + + gradient : array of shape (n_samples,) or (n_samples, n_classes) + Element-wise gradients. + """ + loss = self._compute_loss( + y_true=y_true, + raw_prediction=raw_prediction, + sample_weight=sample_weight, + ) + gradient = self._compute_gradient( + y_true=y_true, + raw_prediction=raw_prediction, + sample_weight=sample_weight, + ) + return loss, gradient + + def gradient( + self, + y_true, + raw_prediction, + sample_weight=None, + gradient_out=None, + n_threads=1, + ): + """Compute gradient of loss w.r.t raw_prediction for each input. + + Parameters + ---------- + y_true : C-contiguous array of shape (n_samples,) + Observed, true target values. + raw_prediction : C-contiguous array of shape (n_samples,) or array of \ + shape (n_samples, n_classes) + Raw prediction values (in link space). + sample_weight : None or C-contiguous array of shape (n_samples,) + Sample weights. + gradient_out : None or C-contiguous array of shape (n_samples,) or array \ + of shape (n_samples, n_classes) + Ignored by the array API implementation. + n_threads : int, default=1 + Ignored by the array API implementation. + + Returns + ------- + gradient : array of shape (n_samples,) or (n_samples, n_classes) + Element-wise gradients. + """ + return self._compute_gradient( + y_true=y_true, + raw_prediction=raw_prediction, + sample_weight=sample_weight, + ) def _log1pexp(raw_prediction, raw_prediction_exp, xp): @@ -1343,40 +1505,6 @@ def _log1pexp(raw_prediction, raw_prediction_exp, xp): class HalfBinomialLossArrayAPI(ArrayAPILossMixin, HalfBinomialLoss): """A version of the HalfBinomialLoss that is compatible with the array API.""" - def loss( - self, - y_true, - raw_prediction, - sample_weight=None, - loss_out=None, - n_threads=1, - ): - xp, _ = get_namespace(y_true, raw_prediction, sample_weight) - return self._compute_loss( - xp=xp, - y_true=y_true, - raw_prediction=raw_prediction, - raw_prediction_exp=xp.exp(raw_prediction), - sample_weight=sample_weight, - ) - - def gradient( - self, - y_true, - raw_prediction, - sample_weight=None, - gradient_out=None, - n_threads=1, - ): - xp, _ = get_namespace(y_true, raw_prediction, sample_weight) - return self._compute_gradient( - xp=xp, - y_true=y_true, - raw_prediction=raw_prediction, - raw_prediction_exp=xp.exp(raw_prediction), - sample_weight=sample_weight, - ) - def loss_gradient( self, y_true, @@ -1386,36 +1514,34 @@ def loss_gradient( gradient_out=None, n_threads=1, ): - xp, _ = get_namespace(y_true, raw_prediction, sample_weight) - raw_prediction_exp = xp.exp(raw_prediction) + raw_prediction_exp = self.xp.exp(raw_prediction) loss = self._compute_loss( - xp=xp, y_true=y_true, raw_prediction=raw_prediction, - raw_prediction_exp=raw_prediction_exp, sample_weight=sample_weight, + raw_prediction_exp=raw_prediction_exp, ) gradient = self._compute_gradient( - xp=xp, y_true=y_true, raw_prediction=raw_prediction, - raw_prediction_exp=raw_prediction_exp, sample_weight=sample_weight, + raw_prediction_exp=raw_prediction_exp, ) return loss, gradient def _compute_loss( self, - xp, y_true, raw_prediction, - raw_prediction_exp, sample_weight=None, + raw_prediction_exp=None, ): + if raw_prediction_exp is None: + raw_prediction_exp = self.xp.exp(raw_prediction) log1pexp = _log1pexp( raw_prediction=raw_prediction, raw_prediction_exp=raw_prediction_exp, - xp=xp, + xp=self.xp, ) loss = log1pexp - y_true * raw_prediction if sample_weight is not None: @@ -1424,12 +1550,14 @@ def _compute_loss( def _compute_gradient( self, - xp, y_true, raw_prediction, - raw_prediction_exp, sample_weight=None, + raw_prediction_exp=None, ): + xp = self.xp + if raw_prediction_exp is None: + raw_prediction_exp = xp.exp(raw_prediction) neg_raw_prediction_exp = 1 / raw_prediction_exp grad = xp.where( raw_prediction > (-37 if raw_prediction.dtype == xp.float64 else -17), @@ -1452,10 +1580,16 @@ class HalfMultinomialLossArrayAPI(ArrayAPILossMixin, HalfMultinomialLoss): n_classes : {None, int} The number of classes for classification, else None. + + xp : module or None + Array namespace module. + + device : device or None + A device object. """ - def __init__(self, sample_weight=None, n_classes=3): - super().__init__(n_classes=n_classes) + def __init__(self, sample_weight=None, n_classes=3, xp=None, device=None): + super().__init__(n_classes=n_classes, xp=xp, device=device) # These instance variables are specifically to store certain # intermediate values in order to avoid having to recompute # them repeatedly. @@ -1467,39 +1601,65 @@ def __init__(self, sample_weight=None, n_classes=3): # Used when computing the gradient. self.y_true_one_hot = None - def loss( + def _compute_loss( self, y_true, raw_prediction, sample_weight=None, - loss_out=None, - n_threads=1, ): - xp, _, device_ = get_namespace_and_device(y_true, raw_prediction, sample_weight) - return self._compute_loss( - xp=xp, - device_=device_, - y_true=y_true, - raw_prediction=raw_prediction, - sample_weight=sample_weight, + xp = self.xp + device = self.device + log_sum_exp = _logsumexp(raw_prediction, axis=1, xp=xp) + if self.y_true_int is None: + self.y_true_int = xp.asarray(y_true, dtype=xp.int64, device=device) + + if self.class_indexing_offsets is None: + self.class_indexing_offsets = ( + xp.arange(y_true.shape[0], device=device) * self.n_classes + ) + true_label_probs = xp.take( + _ravel(raw_prediction), self.y_true_int + self.class_indexing_offsets ) + loss = log_sum_exp - true_label_probs + if sample_weight is not None: + loss *= sample_weight + return loss - def gradient( + def _compute_gradient( self, y_true, raw_prediction, sample_weight=None, - gradient_out=None, - n_threads=1, ): - xp, _, device_ = get_namespace_and_device(y_true, raw_prediction, sample_weight) - return self._compute_gradient( - xp=xp, - device_=device_, - y_true=y_true, - raw_prediction=raw_prediction, - sample_weight=sample_weight, - ) + xp = self.xp + device_ = self.device + if self.y_true_one_hot is None: + if self.y_true_int is None: + self.y_true_int = xp.asarray(y_true, dtype=xp.int64, device=device_) + + self.y_true_one_hot = one_hot( + self.y_true_int, + num_classes=self.n_classes, + dtype=raw_prediction.dtype, + ) + grad = softmax(raw_prediction) + # TODO: once incremental assignment for multiple integer array + # indices is part of a released version of the array API + # spec and array-api-strict has been updated accordingly, + # we can further avoid allocating a big (n_samples, n_classes) + # array for the one-hot encoded y_true and instead use one of the + # following (the latter should allow for JAX support): + # grad[xp.arange(y_true.shape[0]), y_true_int] -= 1 + # xpx.at(grad)[xp.arange(y_true.shape[0]), y_true_int].add(-1) + # See: https://github.com/data-apis/array-api/issues/864 + grad -= self.y_true_one_hot + if sample_weight is not None: + grad *= sample_weight[:, None] + return grad + + +class HalfPoissonLossArrayAPI(ArrayAPILossMixin, HalfPoissonLoss): + """A version of the HalfPoissonLoss that is compatible with the array API.""" def loss_gradient( self, @@ -1510,76 +1670,45 @@ def loss_gradient( gradient_out=None, n_threads=1, ): - xp, _, device_ = get_namespace_and_device(y_true, raw_prediction, sample_weight) + raw_prediction_exp = self.xp.exp(raw_prediction) loss = self._compute_loss( - xp=xp, - device_=device_, y_true=y_true, raw_prediction=raw_prediction, sample_weight=sample_weight, + raw_prediction_exp=raw_prediction_exp, ) gradient = self._compute_gradient( - xp=xp, - device_=device_, y_true=y_true, raw_prediction=raw_prediction, sample_weight=sample_weight, + raw_prediction_exp=raw_prediction_exp, ) return loss, gradient def _compute_loss( self, - xp, - device_, y_true, raw_prediction, sample_weight=None, + raw_prediction_exp=None, ): - log_sum_exp = _logsumexp(raw_prediction, axis=1, xp=xp) - if self.y_true_int is None: - self.y_true_int = xp.asarray(y_true, dtype=xp.int64, device=device_) - - if self.class_indexing_offsets is None: - self.class_indexing_offsets = ( - xp.arange(y_true.shape[0], device=device_) * self.n_classes - ) - true_label_probs = xp.take( - _ravel(raw_prediction), self.y_true_int + self.class_indexing_offsets - ) - loss = log_sum_exp - true_label_probs + if raw_prediction_exp is None: + raw_prediction_exp = self.xp.exp(raw_prediction) + loss = raw_prediction_exp - y_true * raw_prediction if sample_weight is not None: loss *= sample_weight return loss def _compute_gradient( self, - xp, - device_, y_true, raw_prediction, sample_weight=None, + raw_prediction_exp=None, ): - if self.y_true_one_hot is None: - if self.y_true_int is None: - self.y_true_int = xp.asarray(y_true, dtype=xp.int64, device=device_) - - self.y_true_one_hot = self.y_true_int[:, None] == xp.arange( - self.n_classes, device=device_ - ) - self.y_true_one_hot = xp.astype( - self.y_true_one_hot, raw_prediction.dtype, copy=False - ) - grad = softmax(raw_prediction) - # TODO: once incremental assignment for multiple integer array - # indices is part of a released version of the array API - # spec and array-api-strict has been updated accordingly, - # we can further avoid allocating a big (n_samples, n_classes) - # array for the one-hot encoded y_true and instead use one of the - # following (the latter should allow for JAX support): - # grad[xp.arange(y_true.shape[0]), y_true_int] -= 1 - # xpx.at(grad)[xp.arange(y_true.shape[0]), y_true_int].add(-1) - # See: https://github.com/data-apis/array-api/issues/864 - grad -= self.y_true_one_hot + if raw_prediction_exp is None: + raw_prediction_exp = self.xp.exp(raw_prediction) + grad = raw_prediction_exp - y_true if sample_weight is not None: - grad *= sample_weight[:, None] + grad *= sample_weight return grad diff --git a/sklearn/_loss/tests/test_loss.py b/sklearn/_loss/tests/test_loss.py index 673b6b366074c..b6ec997e84e8f 100644 --- a/sklearn/_loss/tests/test_loss.py +++ b/sklearn/_loss/tests/test_loss.py @@ -24,6 +24,7 @@ HalfMultinomialLoss, HalfMultinomialLossArrayAPI, HalfPoissonLoss, + HalfPoissonLossArrayAPI, HalfSquaredError, HalfTweedieLoss, HalfTweedieLossIdentity, @@ -1378,8 +1379,9 @@ def test_tweedie_log_identity_consistency(p): [ (HalfBinomialLossArrayAPI, HalfBinomialLoss), (HalfMultinomialLossArrayAPI, HalfMultinomialLoss), + (HalfPoissonLossArrayAPI, HalfPoissonLoss), ], - ids=["HalfBinomialLoss", "HalfMultinomialLoss"], + ids=["HalfBinomialLoss", "HalfMultinomialLoss", "HalfPoissonLoss"], ) @pytest.mark.parametrize( "method_name", ["__call__", "gradient", "loss", "loss_gradient"] @@ -1399,16 +1401,21 @@ def test_loss_array_api( device_, dtype_name, ): - def _assert_array_api_result(result_xp, result_np, raw_prediction_xp, xp, atol): - assert_allclose(_convert_to_numpy(result_xp, xp=xp), result_np, atol=atol) + def _assert_array_api_result( + result_xp, result_np, raw_prediction_xp, xp, rtol, atol + ): + assert_allclose( + _convert_to_numpy(result_xp, xp=xp), result_np, rtol=rtol, atol=atol + ) assert result_xp.dtype == raw_prediction_xp.dtype assert device(result_xp) == device(raw_prediction_xp) xp = _array_api_for_tests(namespace, device_) atol = _atol_for_type(dtype_name) + rtol = 1e-6 if dtype_name == "float32" else 1e-11 random_seed = 42 n_samples = 100 - array_api_loss_instance = array_api_loss_class() + array_api_loss_instance = array_api_loss_class(xp=xp, device=device_) loss_instance = loss_class() y_true, raw_prediction = random_y_true_raw_prediction( loss=loss_instance, @@ -1454,6 +1461,7 @@ def _assert_array_api_result(result_xp, result_np, raw_prediction_xp, xp, atol): result_np=res_np, raw_prediction_xp=raw_prediction_xp, xp=xp, + rtol=rtol, atol=atol, ) else: @@ -1462,6 +1470,7 @@ def _assert_array_api_result(result_xp, result_np, raw_prediction_xp, xp, atol): result_np=result_np, raw_prediction_xp=raw_prediction_xp, xp=xp, + rtol=rtol, atol=atol, ) diff --git a/sklearn/calibration.py b/sklearn/calibration.py index 7d3523bf15364..fd6832d6d1cef 100644 --- a/sklearn/calibration.py +++ b/sklearn/calibration.py @@ -1118,7 +1118,9 @@ def fit(self, X, y, sample_weight=None): multinomial_loss = ( HalfMultinomialLoss(n_classes=logits.shape[1]) if is_numpy_namespace - else HalfMultinomialLossArrayAPI(n_classes=logits.shape[1]) + else HalfMultinomialLossArrayAPI( + n_classes=logits.shape[1], xp=xp, device=xp_device + ) ) def log_loss(log_beta=0.0): @@ -1155,7 +1157,6 @@ def log_loss(log_beta=0.0): labels, raw_prediction, sample_weight, - xp=xp, ) xatol = 64 * xp.finfo(dtype_).eps diff --git a/sklearn/linear_model/_glm/glm.py b/sklearn/linear_model/_glm/glm.py index c6225b4527620..b29818591826c 100644 --- a/sklearn/linear_model/_glm/glm.py +++ b/sklearn/linear_model/_glm/glm.py @@ -13,6 +13,7 @@ from sklearn._loss.loss import ( HalfGammaLoss, HalfPoissonLoss, + HalfPoissonLossArrayAPI, HalfSquaredError, HalfTweedieLoss, HalfTweedieLossIdentity, @@ -21,6 +22,15 @@ from sklearn.linear_model._glm._newton_solver import NewtonCholeskySolver, NewtonSolver from sklearn.linear_model._linear_loss import LinearModelLoss from sklearn.utils import check_array +from sklearn.utils._array_api import ( + _average, + _convert_to_numpy, + _is_numpy_namespace, + _matching_numpy_dtype, + get_namespace, + get_namespace_and_device, + move_to, +) from sklearn.utils._openmp_helpers import _openmp_effective_n_threads from sklearn.utils._param_validation import Hidden, Interval, StrOptions from sklearn.utils.fixes import _get_additional_lbfgs_options_dict @@ -192,12 +202,13 @@ def fit(self, X, y, sample_weight=None): self : object Fitted model. """ + xp, _, device_ = get_namespace_and_device(X) X, y = validate_data( self, X, y, accept_sparse=["csc", "csr"], - dtype=[np.float64, np.float32], + dtype=[xp.float64, xp.float32], y_numeric=True, multi_output=False, ) @@ -209,8 +220,10 @@ def fit(self, X, y, sample_weight=None): # losses. sample_weight = _check_sample_weight(sample_weight, X, dtype=loss_dtype) + y, sample_weight = move_to(y, sample_weight, xp=xp, device=device_) + n_samples, n_features = X.shape - self._base_loss = self._get_loss() + self._base_loss = self._get_loss(xp=xp, device=device_) linear_loss = LinearModelLoss( base_loss=self._base_loss, @@ -240,18 +253,20 @@ def fit(self, X, y, sample_weight=None): # Thus, without rescaling, we have # obj = LinearModelLoss.loss(...) + loss_dtype_np = _matching_numpy_dtype(X, xp=xp) if self.warm_start and hasattr(self, "coef_"): + coef_xp, _ = get_namespace(self.coef_) + coef = _convert_to_numpy(self.coef_, xp=coef_xp) if self.fit_intercept: # LinearModelLoss needs intercept at the end of coefficient array. - coef = np.concatenate((self.coef_, np.array([self.intercept_]))) - else: - coef = self.coef_ - coef = coef.astype(loss_dtype, copy=False) + intercept = _convert_to_numpy(self.intercept_, xp=coef_xp) + coef = np.concatenate((coef, np.array([intercept]))) + coef = coef.astype(loss_dtype_np, copy=False) else: - coef = linear_loss.init_zero_coef(X, dtype=loss_dtype) + coef = linear_loss.init_zero_coef(X, dtype=loss_dtype_np) if self.fit_intercept: coef[-1] = linear_loss.base_loss.link.link( - np.average(y, weights=sample_weight) + _average(y, weights=sample_weight) ) l2_reg_strength = self.alpha @@ -283,6 +298,11 @@ def fit(self, X, y, sample_weight=None): "lbfgs", opt_res, max_iter=self.max_iter ) coef = opt_res.x + coef = xp.asarray( + coef.copy(order="C" if not _is_numpy_namespace(xp) else "K"), + dtype=X.dtype, + device=device_, + ) elif self.solver == "newton-cholesky": sol = NewtonCholeskySolver( coef=coef, @@ -334,12 +354,13 @@ def _linear_predictor(self, X): y_pred : array of shape (n_samples,) Returns predicted values of linear predictor. """ + xp, _ = get_namespace(X) check_is_fitted(self) X = validate_data( self, X, accept_sparse=["csr", "csc", "coo"], - dtype=[np.float64, np.float32], + dtype=[xp.float64, xp.float32], ensure_2d=True, allow_nd=False, reset=False, @@ -410,6 +431,9 @@ def score(self, X, y, sample_weight=None): # losses. sample_weight = _check_sample_weight(sample_weight, X, dtype=y.dtype) + xp, _, device_ = get_namespace_and_device(X) + y, sample_weight = move_to(y, sample_weight, xp=xp, device=device_) + base_loss = self._base_loss if not base_loss.in_y_true_range(y): @@ -418,7 +442,7 @@ def score(self, X, y, sample_weight=None): f" {base_loss.__name__}." ) - constant = np.average( + constant = _average( base_loss.constant_to_optimal_zero(y_true=y, sample_weight=None), weights=sample_weight, ) @@ -430,14 +454,14 @@ def score(self, X, y, sample_weight=None): sample_weight=sample_weight, n_threads=1, ) - y_mean = base_loss.link.link(np.average(y, weights=sample_weight)) + y_mean = base_loss.link.link(_average(y, weights=sample_weight)) deviance_null = base_loss( y_true=y, - raw_prediction=np.tile(y_mean, y.shape[0]), + raw_prediction=xp.tile(y_mean, (y.shape[0],)), sample_weight=sample_weight, n_threads=1, ) - return 1 - (deviance + constant) / (deviance_null + constant) + return float(1 - (deviance + constant) / (deviance_null + constant)) def __sklearn_tags__(self): tags = super().__sklearn_tags__() @@ -454,7 +478,7 @@ def __sklearn_tags__(self): pass # pragma: no cover return tags - def _get_loss(self): + def _get_loss(self, xp=None, device=None): """This is only necessary because of the link and power arguments of the TweedieRegressor. @@ -591,8 +615,16 @@ def __init__( verbose=verbose, ) - def _get_loss(self): - return HalfPoissonLoss() + def _get_loss(self, xp=None, device=None): + if xp is None or _is_numpy_namespace(xp): + return HalfPoissonLoss() + else: + return HalfPoissonLossArrayAPI(xp=xp, device=device) + + def __sklearn_tags__(self): + tags = super().__sklearn_tags__() + tags.array_api_support = self.solver == "lbfgs" + return tags class GammaRegressor(_GeneralizedLinearRegressor): @@ -723,7 +755,7 @@ def __init__( verbose=verbose, ) - def _get_loss(self): + def _get_loss(self, xp=None, device=None): return HalfGammaLoss() @@ -891,7 +923,7 @@ def __init__( self.link = link self.power = power - def _get_loss(self): + def _get_loss(self, xp=None, device=None): if self.link == "auto": if self.power <= 0: # identity link diff --git a/sklearn/linear_model/_glm/tests/test_glm.py b/sklearn/linear_model/_glm/tests/test_glm.py index 535651f3242f5..ee579ef1f2035 100644 --- a/sklearn/linear_model/_glm/tests/test_glm.py +++ b/sklearn/linear_model/_glm/tests/test_glm.py @@ -11,6 +11,7 @@ from scipy import linalg from scipy.optimize import minimize, root +from sklearn import config_context from sklearn._loss import HalfBinomialLoss, HalfPoissonLoss, HalfTweedieLoss from sklearn._loss.link import IdentityLink, LogLink from sklearn.base import clone @@ -27,13 +28,20 @@ from sklearn.linear_model._linear_loss import LinearModelLoss from sklearn.metrics import d2_tweedie_score, mean_poisson_deviance from sklearn.model_selection import train_test_split -from sklearn.utils._testing import assert_allclose +from sklearn.utils._array_api import ( + _atol_for_type, + _convert_to_numpy, + _get_namespace_device_dtype_ids, + device, + yield_namespace_device_dtype_combinations, +) +from sklearn.utils._testing import _array_api_for_tests, assert_allclose SOLVERS = ["lbfgs", "newton-cholesky"] class BinomialRegressor(_GeneralizedLinearRegressor): - def _get_loss(self): + def _get_loss(self, xp=None, device=None): return HalfBinomialLoss() @@ -1140,3 +1148,104 @@ def test_newton_solver_verbosity(capsys, verbose): "The inner solver detected a pointwise Hessian with many negative values" " and resorts to lbfgs instead." in captured.out ) + + +@pytest.mark.parametrize("use_sample_weight", [False, True]) +@pytest.mark.parametrize( + "array_namespace, device_, dtype_name", + yield_namespace_device_dtype_combinations(), + ids=_get_namespace_device_dtype_ids, +) +@pytest.mark.filterwarnings("error::sklearn.exceptions.ConvergenceWarning") +def test_poisson_regressor_array_api_compliance( + use_sample_weight, + array_namespace, + device_, + dtype_name, +): + xp = _array_api_for_tests(array_namespace, device_) + X_np, y_np = make_regression( + n_samples=107, n_features=20, n_informative=20, noise=0.5, random_state=2 + ) + # make y positive + y_np = np.abs(y_np) + 1.0 + n_samples = X_np.shape[0] + X_np = X_np.astype(dtype_name, copy=False) + y_np = y_np.astype(dtype_name, copy=False) + X_xp = xp.asarray(X_np, device=device_) + y_xp = xp.asarray(y_np, device=device_) + + if use_sample_weight: + sample_weight = ( + np.random.default_rng(0) + .uniform(-1, 5, size=n_samples) + .clip(0, None) # over-represent null weights to cover edge-cases. + .astype(dtype_name) + ) + else: + sample_weight = None + + params = dict(alpha=1, solver="lbfgs", tol=1e-12, max_iter=500) + glm_np = PoissonRegressor(**params).fit(X_np, y_np, sample_weight=sample_weight) + assert glm_np.n_iter_ < glm_np.max_iter + + # Test that alpha was not too large for meaningful testing. + assert np.abs(glm_np.coef_).max() > 0.1 + + predict_np = glm_np.predict(X_np) + atol = _atol_for_type(dtype_name) * 10 + rtol = 3e-3 if dtype_name == "float32" else 1e-6 + + with config_context(array_api_dispatch=True): + glm_xp = PoissonRegressor(**params).fit(X_xp, y_xp, sample_weight=sample_weight) + if dtype_name == "float64": + assert glm_xp.n_iter_ == glm_np.n_iter_ + + for attr_name in ("coef_", "intercept_"): + attr_xp = getattr(glm_xp, attr_name) + attr_np = getattr(glm_np, attr_name) + assert_allclose( + _convert_to_numpy(attr_xp, xp=xp), attr_np, rtol=rtol, atol=atol + ) + assert attr_xp.dtype == X_xp.dtype + assert device(attr_xp) == device(X_xp) + + predict_xp = glm_xp.predict(X_xp) + assert_allclose( + _convert_to_numpy(predict_xp, xp=xp), + predict_np, + rtol=rtol, + atol=atol, + ) + assert predict_xp.dtype == X_xp.dtype + assert device(predict_xp) == device(X_xp) + + +@pytest.mark.parametrize( + "array_namespace, device_, dtype_name", + yield_namespace_device_dtype_combinations(), + ids=_get_namespace_device_dtype_ids, +) +@pytest.mark.filterwarnings("error::sklearn.exceptions.ConvergenceWarning") +def test_poisson_regressor_array_api_warm_start( + array_namespace, + device_, + dtype_name, +): + """Test that incremental fitting of PoissonRegressor works correctly + with the array API when warm_start is True.""" + rng = np.random.default_rng(42) + X = rng.standard_normal((200, 5)).astype(dtype_name) + y = np.abs(rng.standard_normal(200)) + 0.1 + y = y.astype(dtype_name) + xp = _array_api_for_tests(array_namespace, device_) + X_xp = xp.asarray(X, device=device_) + y_xp = xp.asarray(y, device=device_) + with config_context(array_api_dispatch=True): + reg_xp = PoissonRegressor( + alpha=1.0, solver="lbfgs", max_iter=300, warm_start=True + ) + reg_xp.fit(X_xp, y_xp) + reg_xp.predict(X_xp) + # fit again and ensure there is no error + reg_xp.fit(X_xp, y_xp) diff --git a/sklearn/linear_model/_linear_loss.py b/sklearn/linear_model/_linear_loss.py index 96d7f8d92286e..644ea748e2597 100644 --- a/sklearn/linear_model/_linear_loss.py +++ b/sklearn/linear_model/_linear_loss.py @@ -139,9 +139,9 @@ def init_zero_coef(self, X, dtype=None): else: n_dof = n_features if self.base_loss.is_multiclass: - coef = np.zeros_like(X, shape=(n_classes, n_dof), dtype=dtype, order="F") + coef = np.zeros(shape=(n_classes, n_dof), dtype=dtype, order="F") else: - coef = np.zeros_like(X, shape=n_dof, dtype=dtype) + coef = np.zeros(shape=n_dof, dtype=dtype) return coef def weight_intercept(self, coef): diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index 867e766b57fd6..f9202dc754939 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -379,7 +379,7 @@ def _logistic_regression_path( base_loss=( HalfBinomialLoss() if _is_numpy_namespace(xp) - else HalfBinomialLossArrayAPI() + else HalfBinomialLossArrayAPI(xp=xp, device=device_) ), fit_intercept=fit_intercept, ) @@ -395,7 +395,9 @@ def _logistic_regression_path( base_loss=( HalfMultinomialLoss(n_classes=size(classes)) if _is_numpy_namespace(xp) - else HalfMultinomialLossArrayAPI(n_classes=size(classes)) + else HalfMultinomialLossArrayAPI( + n_classes=size(classes), xp=xp, device=device_ + ) ), fit_intercept=fit_intercept, ) From e0b30df84edcf1c451403e90959eaafa8316598b Mon Sep 17 00:00:00 2001 From: Tim Head <betatim@gmail.com> Date: Wed, 18 Mar 2026 06:44:34 +0100 Subject: [PATCH 293/462] Fix LogisticRegression with array API and warm start (#33567) Co-authored-by: Omar Salman <omar.salman@arbisoft.com> --- sklearn/linear_model/_logistic.py | 12 +++++--- sklearn/linear_model/tests/test_logistic.py | 32 +++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index f9202dc754939..246016a8d14b5 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -40,6 +40,7 @@ compute_class_weight, ) from sklearn.utils._array_api import ( + _convert_to_numpy, _is_numpy_namespace, _matching_numpy_dtype, get_namespace, @@ -1326,10 +1327,13 @@ def fit(self, X, y, sample_weight=None): warm_start_coef = getattr(self, "coef_", None) else: warm_start_coef = None - if warm_start_coef is not None and self.fit_intercept: - warm_start_coef = xp.concat( - [warm_start_coef, self.intercept_[:, None]], axis=1 - ) + if warm_start_coef is not None: + warm_start_coef = _convert_to_numpy(warm_start_coef, xp=xp) + if self.fit_intercept: + intercept_np = _convert_to_numpy(self.intercept_, xp=xp) + warm_start_coef = np.concatenate( + [warm_start_coef, intercept_np[:, None]], axis=1 + ) # TODO: enable multi-threading if benchmarks show a positive effect, # see https://github.com/scikit-learn/scikit-learn/issues/32162 diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index d908edcc799f4..876daf4204553 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -2846,3 +2846,35 @@ def test_get_default_scorer(): """Test that LogisticRegressionCV gets correct default scorer.""" lr = LogisticRegressionCV() assert lr._get_scorer()._score_func.__name__ == "accuracy_score" + + +@pytest.mark.parametrize("binary", [True, False]) +@pytest.mark.parametrize( + "array_namespace, device_, dtype_name", + yield_namespace_device_dtype_combinations(), + ids=_get_namespace_device_dtype_ids, +) +@pytest.mark.filterwarnings("error::sklearn.exceptions.ConvergenceWarning") +def test_logistic_regression_array_api_warm_start( + binary, + array_namespace, + device_, + dtype_name, +): + """Test that warm_start=True works with array API inputs across + multiple fit calls for both binary and multiclass classification.""" + xp = _array_api_for_tests(array_namespace, device_) + X_np = iris.data.astype(dtype_name, copy=True) + if binary: + y_np = (iris.target > 0).astype(dtype_name) + else: + y_np = iris.target.astype(dtype_name) + + X_xp = xp.asarray(X_np, device=device_) + y_xp = xp.asarray(y_np, device=device_) + + with config_context(array_api_dispatch=True): + lr = LogisticRegression(C=1e-2, solver="lbfgs", max_iter=300, warm_start=True) + lr.fit(X_xp, y_xp) + lr.predict(X_xp) + lr.fit(X_xp, y_xp) From 80db4c9f26d6d3daacc8bc5be309ecc98a4ba6fb Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Wed, 18 Mar 2026 18:02:53 +0100 Subject: [PATCH 294/462] DOC multiclass user guide - infos about LogisticRegression (#33536) --- doc/modules/multiclass.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/modules/multiclass.rst b/doc/modules/multiclass.rst index 4f735e9c2a70c..94ef1a4c7b6a5 100644 --- a/doc/modules/multiclass.rst +++ b/doc/modules/multiclass.rst @@ -63,8 +63,8 @@ can provide additional strategies beyond what is built-in: - :class:`semi_supervised.LabelSpreading` - :class:`discriminant_analysis.LinearDiscriminantAnalysis` - :class:`svm.LinearSVC` (setting multi_class="crammer_singer") - - :class:`linear_model.LogisticRegression` (with most solvers) - - :class:`linear_model.LogisticRegressionCV` (with most solvers) + - :class:`linear_model.LogisticRegression` (all solvers but "liblinear") + - :class:`linear_model.LogisticRegressionCV` (all solvers but "liblinear") - :class:`neural_network.MLPClassifier` - :class:`neighbors.NearestCentroid` - :class:`discriminant_analysis.QuadraticDiscriminantAnalysis` @@ -86,8 +86,6 @@ can provide additional strategies beyond what is built-in: - :class:`ensemble.GradientBoostingClassifier` - :class:`gaussian_process.GaussianProcessClassifier` (setting multi_class = "one_vs_rest") - :class:`svm.LinearSVC` (setting multi_class="ovr") - - :class:`linear_model.LogisticRegression` (most solvers) - - :class:`linear_model.LogisticRegressionCV` (most solvers) - :class:`linear_model.SGDClassifier` - :class:`linear_model.Perceptron` From ba4734237af8fae6fe67094de2cc527fa3106204 Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Thu, 19 Mar 2026 18:13:16 +0100 Subject: [PATCH 295/462] Fix `pos_label` validation in multiclass scorers (#33473) Co-authored-by: Lucy Liu <jliu176@gmail.com> --- .../sklearn.model_selection/33473.fix.rst | 7 ++++ sklearn/inspection/_plot/decision_boundary.py | 33 ++++++++---------- .../tests/test_boundary_decision_display.py | 4 +-- sklearn/metrics/tests/test_score_objects.py | 34 +++++++++++++++++++ sklearn/utils/_response.py | 17 +++++----- 5 files changed, 65 insertions(+), 30 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.model_selection/33473.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.model_selection/33473.fix.rst b/doc/whats_new/upcoming_changes/sklearn.model_selection/33473.fix.rst new file mode 100644 index 0000000000000..007b9e614d6a9 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.model_selection/33473.fix.rst @@ -0,0 +1,7 @@ +- Fixed incorrect :class:`ValueError` when using + ``scoring="average_precision"`` or similar in model selection utilities such + as `model_selection.GridSearchCV` or `model_selection.cross_validate` with + multiclass classifiers. The ``pos_label`` parameter is only relevant for + binary classification and was incorrectly being validated for scorers used on + multiclass problems. + By :user:`Olivier Grisel <ogrisel>`. diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index 8c974706edfcb..a1e28882565d5 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -574,26 +574,21 @@ def from_estimator( ) prediction_method = _check_boundary_response_method(estimator, response_method) - try: - response, _, response_method_used = _get_response_values( - estimator, - X_grid, - response_method=prediction_method, - pos_label=class_of_interest, - return_response_method_used=True, + if (class_of_interest is not None and hasattr(estimator, "classes_")) and ( + class_of_interest not in estimator.classes_ + ): + raise ValueError( + f"class_of_interest={class_of_interest} is not a valid label: It " + f"should be one of {estimator.classes_}" ) - except ValueError as exc: - if "is not a valid label" in str(exc): - # re-raise a more informative error message since `pos_label` is unknown - # to our user when interacting with - # `DecisionBoundaryDisplay.from_estimator` - raise ValueError( - # Note: it is ok to use estimator.classes_ here, as this error will - # only be thrown if estimator is a classifier - f"class_of_interest={class_of_interest} is not a valid label: It " - f"should be one of {estimator.classes_}" - ) from exc - raise + + response, _, response_method_used = _get_response_values( + estimator, + X_grid, + response_method=prediction_method, + pos_label=class_of_interest, + return_response_method_used=True, + ) # convert classes predictions into integers if response_method_used == "predict" and hasattr(estimator, "classes_"): diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index 7319af89d6ccb..539caedb013f6 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -578,9 +578,7 @@ def test_class_of_interest_multiclass(pyplot, response_method): response = getattr(estimator, response_method)(grid)[:, class_of_interest_idx] assert_allclose(response.reshape(*disp.response.shape), disp.response) - # check that we raise an error for unknown labels - # this test should already be handled in `_get_response_values` but we can have this - # test here as well + # Check that we raise an error for unknown labels. err_msg = "class_of_interest=2 is not a valid label: It should be one of" with pytest.raises(ValueError, match=err_msg): DecisionBoundaryDisplay.from_estimator( diff --git a/sklearn/metrics/tests/test_score_objects.py b/sklearn/metrics/tests/test_score_objects.py index 7f1c60c691c43..d536884d7f759 100644 --- a/sklearn/metrics/tests/test_score_objects.py +++ b/sklearn/metrics/tests/test_score_objects.py @@ -14,6 +14,7 @@ from sklearn.cluster import KMeans from sklearn.datasets import ( load_diabetes, + load_iris, make_blobs, make_classification, make_multilabel_classification, @@ -63,6 +64,7 @@ ignore_warnings, ) from sklearn.utils.metadata_routing import MetadataRouter, MethodMapping +from sklearn.utils.multiclass import type_of_target REGRESSION_SCORERS = [ "d2_absolute_error_score", @@ -1180,6 +1182,38 @@ def test_scorer_select_proba_error(scorer): scorer(lr, X, y) +def test_invalid_default_pos_label_ignored_on_multiclass(): + iris = load_iris() + X = iris.data + y = np.array(iris.target_names)[iris.target] + + assert type_of_target(y) == "multiclass" + + clf = LogisticRegression(max_iter=1000, random_state=0).fit(X, y) + + # The default of average_precision_score pos_label is 1. It's not one of + # the string class labels but it should be ignored when the scorer is + # called on a multiclass problem. + scorer = make_scorer( + average_precision_score, + response_method=("decision_function", "predict_proba"), + ) + assert scorer(clf, X, y) > 0.7 + + # Passing an invalid pos_label explicitly should raise an error. + scorer = make_scorer( + average_precision_score, + response_method=("decision_function", "predict_proba"), + pos_label="invalid_label", + ) + expected_msg = re.escape( + "Parameter pos_label is fixed to 1 for multiclass y_true. Do not set pos_label " + "or set pos_label to 1." + ) + with pytest.raises(ValueError, match=expected_msg): + scorer(clf, X, y) + + def test_get_scorer_return_copy(): # test that get_scorer returns a copy assert get_scorer("roc_auc") is not get_scorer("roc_auc") diff --git a/sklearn/utils/_response.py b/sklearn/utils/_response.py index 7711f24d0aaae..fc97e5fe9da7c 100644 --- a/sklearn/utils/_response.py +++ b/sklearn/utils/_response.py @@ -41,7 +41,7 @@ def _process_predict_proba(*, y_pred, target_type, classes, pos_label): Class labels as reported by `estimator.classes_`. pos_label : int, float, bool or str - Only used with binary and multiclass targets. + Only used with binary targets. Returns ------- @@ -79,7 +79,8 @@ def _process_decision_function(*, y_pred, target_type, classes, pos_label): This function process the `y_pred` array in the binary and multi-label cases. In the binary case, it inverts the sign of the score if the positive label is not `classes[1]`. In the multi-label case, it stacks the predictions if - they are not in the "compressed" format `(n_samples, n_outputs)`. + the positive label is not `classes[1]`. `y_pred` is returned unchanged if + `target_type` is "multiclass" or "multilabel-indicator". Parameters ---------- @@ -100,7 +101,7 @@ def _process_decision_function(*, y_pred, target_type, classes, pos_label): Class labels as reported by `estimator.classes_`. pos_label : int, float, bool or str - Only used with binary and multiclass targets. + Only used with binary targets. Returns ------- @@ -163,8 +164,8 @@ def _get_response_values( pos_label : int, float, bool or str, default=None The class considered as the positive class when computing - the metrics. If `None` and target is 'binary', `estimators.classes_[1]` is - considered as the positive class. + the response values. If `None` and target is 'binary', + `estimators.classes_[1]` is considered as the positive class. return_response_method_used : bool, default=False Whether to return the response method used to compute the response @@ -181,7 +182,7 @@ def _get_response_values( pos_label : int, float, bool, str or None The class considered as the positive class when computing - the metrics. Returns `None` if `estimator` is a regressor, an outlier + binary response values. Returns `None` if `estimator` is a regressor, an outlier detector or a clusterer. response_method_used : str @@ -202,13 +203,13 @@ def _get_response_values( classes = estimator.classes_ target_type = type_of_target(classes) - if target_type in ("binary", "multiclass"): + if target_type == "binary": if pos_label is not None and pos_label not in classes.tolist(): raise ValueError( f"pos_label={pos_label} is not a valid label: It should be " f"one of {classes}" ) - elif pos_label is None and target_type == "binary": + elif pos_label is None: pos_label = classes[-1] y_pred = prediction_method(X) From 070f14098469e55dcc792324c3ed77929b961ce4 Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Fri, 20 Mar 2026 11:42:57 +0100 Subject: [PATCH 296/462] Refactor array API testing to always pass device and dtype names (#33583) Co-authored-by: Tim Head <betatim@gmail.com> --- sklearn/_loss/tests/test_link.py | 8 +- sklearn/_loss/tests/test_loss.py | 33 ++- sklearn/decomposition/tests/test_pca.py | 35 ++- sklearn/linear_model/_glm/tests/test_glm.py | 31 ++- sklearn/linear_model/tests/test_logistic.py | 29 ++- sklearn/linear_model/tests/test_ridge.py | 32 +-- sklearn/metrics/cluster/tests/test_common.py | 16 +- .../metrics/cluster/tests/test_supervised.py | 8 +- sklearn/metrics/tests/test_classification.py | 64 +++--- sklearn/metrics/tests/test_common.py | 87 ++++---- sklearn/metrics/tests/test_pairwise.py | 22 +- .../mixture/tests/test_gaussian_mixture.py | 43 ++-- sklearn/model_selection/tests/test_search.py | 14 +- sklearn/model_selection/tests/test_split.py | 8 +- .../model_selection/tests/test_validation.py | 12 +- sklearn/preprocessing/tests/test_data.py | 57 ++--- sklearn/preprocessing/tests/test_label.py | 44 ++-- .../preprocessing/tests/test_polynomial.py | 25 +-- sklearn/tests/test_calibration.py | 33 ++- sklearn/tests/test_kernel_approximation.py | 7 +- sklearn/tests/test_naive_bayes.py | 24 +- sklearn/tests/test_pipeline.py | 6 +- sklearn/utils/_array_api.py | 55 +---- sklearn/utils/_testing.py | 39 +++- sklearn/utils/estimator_checks.py | 12 +- sklearn/utils/tests/test_array_api.py | 209 +++++++++--------- sklearn/utils/tests/test_extmath.py | 36 ++- sklearn/utils/tests/test_indexing.py | 29 ++- sklearn/utils/tests/test_multiclass.py | 8 +- sklearn/utils/tests/test_stats.py | 13 +- sklearn/utils/tests/test_validation.py | 34 +-- 31 files changed, 547 insertions(+), 526 deletions(-) diff --git a/sklearn/_loss/tests/test_link.py b/sklearn/_loss/tests/test_link.py index f85b223c6f1fb..5177701c0619a 100644 --- a/sklearn/_loss/tests/test_link.py +++ b/sklearn/_loss/tests/test_link.py @@ -12,7 +12,6 @@ ) from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import _array_api_for_tests @@ -89,13 +88,12 @@ def test_link_inverse_identity(link, global_random_seed): @pytest.mark.parametrize( - "namespace, device, dtype_name", + "namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("link", LINK_FUNCTIONS) def test_link_inverse_array_api( - namespace, device, dtype_name, link, global_random_seed + namespace, device_name, dtype_name, link, global_random_seed ): """Test that link and inverse link give same result for array API inputs.""" rng = np.random.RandomState(global_random_seed) @@ -114,7 +112,7 @@ def test_link_inverse_array_api( else: raw_prediction = rng.uniform(low=-20, high=20, size=(n_samples)) - xp = _array_api_for_tests(namespace, device) + xp, device = _array_api_for_tests(namespace, device_name) if dtype_name != "float64": raw_prediction *= 0.5 # avoid overflow rtol = 1e-3 if n_classes else 1e-4 diff --git a/sklearn/_loss/tests/test_loss.py b/sklearn/_loss/tests/test_loss.py index b6ec997e84e8f..1df697c2d4598 100644 --- a/sklearn/_loss/tests/test_loss.py +++ b/sklearn/_loss/tests/test_loss.py @@ -36,10 +36,11 @@ from sklearn.utils._array_api import ( _atol_for_type, _convert_to_numpy, - _get_namespace_device_dtype_ids, - device, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._testing import ( _array_api_for_tests, create_memmap_backed_data, @@ -1388,9 +1389,8 @@ def test_tweedie_log_identity_consistency(p): ) @pytest.mark.parametrize("use_sample_weight", [False, True]) @pytest.mark.parametrize( - "namespace, device_, dtype_name", + "namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) def test_loss_array_api( array_api_loss_class, @@ -1398,7 +1398,7 @@ def test_loss_array_api( method_name, use_sample_weight, namespace, - device_, + device_name, dtype_name, ): def _assert_array_api_result( @@ -1408,14 +1408,14 @@ def _assert_array_api_result( _convert_to_numpy(result_xp, xp=xp), result_np, rtol=rtol, atol=atol ) assert result_xp.dtype == raw_prediction_xp.dtype - assert device(result_xp) == device(raw_prediction_xp) + assert array_api_device(result_xp) == array_api_device(raw_prediction_xp) - xp = _array_api_for_tests(namespace, device_) + xp, device = _array_api_for_tests(namespace, device_name) atol = _atol_for_type(dtype_name) rtol = 1e-6 if dtype_name == "float32" else 1e-11 random_seed = 42 n_samples = 100 - array_api_loss_instance = array_api_loss_class(xp=xp, device=device_) + array_api_loss_instance = array_api_loss_class(xp=xp, device=device) loss_instance = loss_class() y_true, raw_prediction = random_y_true_raw_prediction( loss=loss_instance, @@ -1426,14 +1426,14 @@ def _assert_array_api_result( ) y_true = y_true.astype(dtype_name) raw_prediction = raw_prediction.astype(dtype_name) - y_true_xp = xp.asarray(y_true, device=device_) - raw_prediction_xp = xp.asarray(raw_prediction, device=device_) + y_true_xp = xp.asarray(y_true, device=device) + raw_prediction_xp = xp.asarray(raw_prediction, device=device) if use_sample_weight: rng = np.random.RandomState(random_seed) sample_weight_np = ( rng.uniform(-1, 5, size=n_samples).clip(0, None).astype(dtype_name) ) - sample_weight_xp = xp.asarray(sample_weight_np, device=device_) + sample_weight_xp = xp.asarray(sample_weight_np, device=device) else: sample_weight_np = None sample_weight_xp = None @@ -1476,20 +1476,19 @@ def _assert_array_api_result( @pytest.mark.parametrize( - "namespace, device_, dtype_name", + "namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_log1pexp(namespace, device_, dtype_name): +def test_log1pexp(namespace, device_name, dtype_name): mpmath = pytest.importorskip("mpmath") mpmath.mp.prec = 100 # Significantly more precise reference than float64. values_to_test = np.linspace(-40, 40, 300) - xp = _array_api_for_tests(namespace, device_) + xp, device = _array_api_for_tests(namespace, device_name) for value in values_to_test: if dtype_name == "float32": - x = xp.asarray(value, dtype=xp.float32, device=device_) + x = xp.asarray(value, dtype=xp.float32, device=device) else: - x = xp.asarray(value, dtype=xp.float64, device=device_) + x = xp.asarray(value, dtype=xp.float64, device=device) result_xp = float( _log1pexp( diff --git a/sklearn/decomposition/tests/test_pca.py b/sklearn/decomposition/tests/test_pca.py index 23aa40cb63cf7..909fee3e6a5c5 100644 --- a/sklearn/decomposition/tests/test_pca.py +++ b/sklearn/decomposition/tests/test_pca.py @@ -14,7 +14,6 @@ from sklearn.utils._array_api import ( _atol_for_type, _convert_to_numpy, - _get_namespace_device_dtype_ids, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import device as array_device @@ -936,8 +935,10 @@ def test_variance_correctness(copy): np.testing.assert_allclose(pca_var, true_var) -def check_array_api_get_precision(name, estimator, array_namespace, device, dtype_name): - xp = _array_api_for_tests(array_namespace, device) +def check_array_api_get_precision( + name, estimator, array_namespace, device_name, dtype_name +): + xp, device = _array_api_for_tests(array_namespace, device_name) iris_np = iris.data.astype(dtype_name) iris_xp = xp.asarray(iris_np, device=device) @@ -971,9 +972,8 @@ def check_array_api_get_precision(name, estimator, array_namespace, device, dtyp @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "check", @@ -998,17 +998,22 @@ def check_array_api_get_precision(name, estimator, array_namespace, device, dtyp ids=_get_check_estimator_ids, ) def test_pca_array_api_compliance( - estimator, check, array_namespace, device, dtype_name + estimator, check, array_namespace, device_name, dtype_name ): name = estimator.__class__.__name__ estimator = clone(estimator) - check(name, estimator, array_namespace, device=device, dtype_name=dtype_name) + check( + name, + estimator, + array_namespace, + device_name=device_name, + dtype_name=dtype_name, + ) @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "check", @@ -1028,14 +1033,20 @@ def test_pca_array_api_compliance( ids=_get_check_estimator_ids, ) def test_pca_mle_array_api_compliance( - estimator, check, array_namespace, device, dtype_name + estimator, check, array_namespace, device_name, dtype_name ): name = estimator.__class__.__name__ - check(name, estimator, array_namespace, device=device, dtype_name=dtype_name) + check( + name, + estimator, + array_namespace, + device_name=device_name, + dtype_name=dtype_name, + ) # Simpler variant of the generic check_array_api_input checker tailored for # the specific case of PCA with mle-trimmed components. - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) X, y = make_classification(random_state=42) X = X.astype(dtype_name, copy=False) diff --git a/sklearn/linear_model/_glm/tests/test_glm.py b/sklearn/linear_model/_glm/tests/test_glm.py index ee579ef1f2035..3c188511414aa 100644 --- a/sklearn/linear_model/_glm/tests/test_glm.py +++ b/sklearn/linear_model/_glm/tests/test_glm.py @@ -31,10 +31,11 @@ from sklearn.utils._array_api import ( _atol_for_type, _convert_to_numpy, - _get_namespace_device_dtype_ids, - device, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._testing import _array_api_for_tests, assert_allclose SOLVERS = ["lbfgs", "newton-cholesky"] @@ -1152,18 +1153,17 @@ def test_newton_solver_verbosity(capsys, verbose): @pytest.mark.parametrize("use_sample_weight", [False, True]) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.filterwarnings("error::sklearn.exceptions.ConvergenceWarning") def test_poisson_regressor_array_api_compliance( use_sample_weight, array_namespace, - device_, + device_name, dtype_name, ): - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) X_np, y_np = make_regression( n_samples=107, n_features=20, n_informative=20, noise=0.5, random_state=2 ) @@ -1172,8 +1172,8 @@ def test_poisson_regressor_array_api_compliance( n_samples = X_np.shape[0] X_np = X_np.astype(dtype_name, copy=False) y_np = y_np.astype(dtype_name, copy=False) - X_xp = xp.asarray(X_np, device=device_) - y_xp = xp.asarray(y_np, device=device_) + X_xp = xp.asarray(X_np, device=device) + y_xp = xp.asarray(y_np, device=device) if use_sample_weight: sample_weight = ( @@ -1208,7 +1208,7 @@ def test_poisson_regressor_array_api_compliance( _convert_to_numpy(attr_xp, xp=xp), attr_np, rtol=rtol, atol=atol ) assert attr_xp.dtype == X_xp.dtype - assert device(attr_xp) == device(X_xp) + assert array_api_device(attr_xp) == array_api_device(X_xp) predict_xp = glm_xp.predict(X_xp) assert_allclose( @@ -1218,18 +1218,17 @@ def test_poisson_regressor_array_api_compliance( atol=atol, ) assert predict_xp.dtype == X_xp.dtype - assert device(predict_xp) == device(X_xp) + assert array_api_device(predict_xp) == array_api_device(X_xp) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.filterwarnings("error::sklearn.exceptions.ConvergenceWarning") def test_poisson_regressor_array_api_warm_start( array_namespace, - device_, + device_name, dtype_name, ): """Test that incremental fitting of PoissonRegressor works correctly @@ -1238,9 +1237,9 @@ def test_poisson_regressor_array_api_warm_start( X = rng.standard_normal((200, 5)).astype(dtype_name) y = np.abs(rng.standard_normal(200)) + 0.1 y = y.astype(dtype_name) - xp = _array_api_for_tests(array_namespace, device_) - X_xp = xp.asarray(X, device=device_) - y_xp = xp.asarray(y, device=device_) + xp, device = _array_api_for_tests(array_namespace, device_name) + X_xp = xp.asarray(X, device=device) + y_xp = xp.asarray(y, device=device) with config_context(array_api_dispatch=True): reg_xp = PoissonRegressor( alpha=1.0, solver="lbfgs", max_iter=300, warm_start=True diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index 876daf4204553..efd094c281d9c 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -39,10 +39,11 @@ from sklearn.utils._array_api import ( _atol_for_type, _convert_to_numpy, - _get_namespace_device_dtype_ids, - device, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._testing import _array_api_for_tests, ignore_warnings from sklearn.utils.fixes import _IS_32BIT, COO_CONTAINERS, CSR_CONTAINERS @@ -2688,9 +2689,8 @@ def test_logisticregression_warns_with_n_jobs(): @pytest.mark.parametrize("use_sample_weight", [False, True]) @pytest.mark.parametrize("class_weight", [None, "balanced", "dict"]) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.filterwarnings("error::sklearn.exceptions.ConvergenceWarning") def test_logistic_regression_array_api_compliance( @@ -2699,13 +2699,13 @@ def test_logistic_regression_array_api_compliance( use_sample_weight, class_weight, array_namespace, - device_, + device_name, dtype_name, ): - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) X_np = iris.data.astype(dtype_name, copy=True) n_samples, _ = X_np.shape - X_xp = xp.asarray(X_np, device=device_) + X_xp = xp.asarray(X_np, device=device) if use_str_y: if binary: target = (iris.target > 0).astype(np.int64) @@ -2728,7 +2728,7 @@ def test_logistic_regression_array_api_compliance( if class_weight == "dict": class_weight = {0: 1.0, 1: 2.0, 2: 3.0} y_np = target.astype(dtype_name) - y_xp_or_np = xp.asarray(y_np, device=device_) + y_xp_or_np = xp.asarray(y_np, device=device) if use_sample_weight: sample_weight = ( @@ -2789,7 +2789,7 @@ def test_logistic_regression_array_api_compliance( _convert_to_numpy(attr_xp, xp=xp), attr_np, rtol=rtol, atol=atol ) assert attr_xp.dtype == X_xp.dtype - assert device(attr_xp) == device(X_xp) + assert array_api_device(attr_xp) == array_api_device(X_xp) predict_proba_xp = lr_xp.predict_proba(X_xp) assert_allclose( @@ -2799,7 +2799,7 @@ def test_logistic_regression_array_api_compliance( atol=atol, ) assert predict_proba_xp.dtype == X_xp.dtype - assert device(predict_proba_xp) == device(X_xp) + assert array_api_device(predict_proba_xp) == array_api_device(X_xp) predict_log_proba_xp = lr_xp.predict_log_proba(X_xp) assert_allclose( @@ -2809,7 +2809,7 @@ def test_logistic_regression_array_api_compliance( atol=atol, ) assert predict_log_proba_xp.dtype == X_xp.dtype - assert device(predict_log_proba_xp) == device(X_xp) + assert array_api_device(predict_log_proba_xp) == array_api_device(X_xp) prediction_xp = lr_xp.predict(X_xp) if not use_str_y: @@ -2850,20 +2850,19 @@ def test_get_default_scorer(): @pytest.mark.parametrize("binary", [True, False]) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.filterwarnings("error::sklearn.exceptions.ConvergenceWarning") def test_logistic_regression_array_api_warm_start( binary, array_namespace, - device_, + device_name, dtype_name, ): """Test that warm_start=True works with array API inputs across multiple fit calls for both binary and multiclass classification.""" - xp = _array_api_for_tests(array_namespace, device_) + xp, device_ = _array_api_for_tests(array_namespace, device_name) X_np = iris.data.astype(dtype_name, copy=True) if binary: y_np = (iris.target > 0).astype(dtype_name) diff --git a/sklearn/linear_model/tests/test_ridge.py b/sklearn/linear_model/tests/test_ridge.py index fe9112bd757ab..0f44c551b57a8 100644 --- a/sklearn/linear_model/tests/test_ridge.py +++ b/sklearn/linear_model/tests/test_ridge.py @@ -45,7 +45,6 @@ _NUMPY_NAMESPACE_NAMES, _atol_for_type, _convert_to_numpy, - _get_namespace_device_dtype_ids, yield_namespace_device_dtype_combinations, yield_namespaces, ) @@ -1409,9 +1408,9 @@ def _test_tolerance(sparse_container): def check_array_api_attributes( - name, estimator, array_namespace, device, dtype_name, rtol=None + name, estimator, array_namespace, device_name, dtype_name, rtol=None ): - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) X_iris_np = X_iris.astype(dtype_name) y_iris_np = y_iris.astype(dtype_name) @@ -1448,9 +1447,8 @@ def check_array_api_attributes( @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "check", @@ -1469,32 +1467,36 @@ def check_array_api_attributes( ids=_get_check_estimator_ids, ) def test_ridge_array_api_compliance( - estimator, check, array_namespace, device, dtype_name + estimator, check, array_namespace, device_name, dtype_name ): name = estimator.__class__.__name__ - xp = _array_api_for_tests(array_namespace, device) - check(name, estimator, array_namespace, device=device, dtype_name=dtype_name) + check( + name, + estimator, + array_namespace, + device_name=device_name, + dtype_name=dtype_name, + ) @pytest.mark.parametrize( "estimator", [RidgeClassifier(solver="svd"), RidgeClassifierCV()] ) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) def test_ridge_classifier_multilabel_array_api( - estimator, array_namespace, device_, dtype_name + estimator, array_namespace, device_name, dtype_name ): - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) X, y = make_multilabel_classification(random_state=0) X_np = X.astype(dtype_name) y_np = y.astype(dtype_name) ridge_np = estimator.fit(X_np, y_np) pred_np = ridge_np.predict(X_np) with config_context(array_api_dispatch=True): - X_xp, y_xp = xp.asarray(X_np, device=device_), xp.asarray(y_np, device=device_) + X_xp, y_xp = xp.asarray(X_np, device=device), xp.asarray(y_np, device=device) ridge_xp = estimator.fit(X_xp, y_xp) pred_xp = ridge_xp.predict(X_xp) assert pred_xp.shape == pred_np.shape == y.shape @@ -1505,7 +1507,7 @@ def test_ridge_classifier_multilabel_array_api( "array_namespace", yield_namespaces(include_numpy_namespaces=False) ) def test_array_api_error_and_warnings_for_solver_parameter(array_namespace): - xp = _array_api_for_tests(array_namespace, device=None) + xp, _ = _array_api_for_tests(array_namespace, device_name=None) X_iris_xp = xp.asarray(X_iris[:5]) y_iris_xp = xp.asarray(y_iris[:5]) @@ -1548,7 +1550,7 @@ def test_array_api_error_and_warnings_for_solver_parameter(array_namespace): @pytest.mark.parametrize("array_namespace", sorted(_NUMPY_NAMESPACE_NAMES)) def test_array_api_numpy_namespace_no_warning(array_namespace): - xp = _array_api_for_tests(array_namespace, device=None) + xp, _ = _array_api_for_tests(array_namespace, device_name=None) X_iris_xp = xp.asarray(X_iris[:5]) y_iris_xp = xp.asarray(y_iris[:5]) diff --git a/sklearn/metrics/cluster/tests/test_common.py b/sklearn/metrics/cluster/tests/test_common.py index f439d4cb5e33a..5e76e6bfd6963 100644 --- a/sklearn/metrics/cluster/tests/test_common.py +++ b/sklearn/metrics/cluster/tests/test_common.py @@ -20,7 +20,6 @@ ) from sklearn.metrics.tests.test_common import check_array_api_metric from sklearn.utils._array_api import ( - _get_namespace_device_dtype_ids, yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import assert_allclose @@ -239,14 +238,16 @@ def test_returned_value_consistency(name): assert not isinstance(score, (np.float64, np.float32)) -def check_array_api_unsupervised_metric(metric, array_namespace, device, dtype_name): +def check_array_api_unsupervised_metric( + metric, array_namespace, device_name, dtype_name +): y_pred = np.array([1, 0, 1, 0, 1, 1, 0]) X = np.random.randint(10, size=(7, 10)) check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=X, b_np=y_pred, @@ -270,10 +271,11 @@ def yield_metric_checker_combinations(metric_checkers=array_api_metric_checkers) @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("metric, check_func", yield_metric_checker_combinations()) -def test_array_api_compliance(metric, array_namespace, device, dtype_name, check_func): - check_func(metric, array_namespace, device, dtype_name) +def test_array_api_compliance( + metric, array_namespace, device_name, dtype_name, check_func +): + check_func(metric, array_namespace, device_name, dtype_name) diff --git a/sklearn/metrics/cluster/tests/test_supervised.py b/sklearn/metrics/cluster/tests/test_supervised.py index fe4bd8b6dd5df..b7f0084e5332f 100644 --- a/sklearn/metrics/cluster/tests/test_supervised.py +++ b/sklearn/metrics/cluster/tests/test_supervised.py @@ -28,7 +28,6 @@ ) from sklearn.utils import assert_all_finite from sklearn.utils._array_api import ( - _get_namespace_device_dtype_ids, yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import _array_api_for_tests, assert_almost_equal @@ -284,12 +283,11 @@ def test_entropy(): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_entropy_array_api(array_namespace, device, dtype_name): - xp = _array_api_for_tests(array_namespace, device) +def test_entropy_array_api(array_namespace, device_name, dtype_name): + xp, device = _array_api_for_tests(array_namespace, device_name) float_labels = xp.asarray(np.asarray([0, 0, 42.0], dtype=dtype_name), device=device) empty_int32_labels = xp.asarray([], dtype=xp.int32, device=device) int_labels = xp.asarray([1, 1, 1, 1], device=device) diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index cd4c63d063eac..850dc3da2dd60 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -46,12 +46,11 @@ from sklearn.preprocessing import LabelBinarizer, label_binarize from sklearn.tree import DecisionTreeClassifier from sklearn.utils._array_api import ( - _get_namespace_device_dtype_ids, - get_namespace, - yield_namespace_device_dtype_combinations, + device as array_api_device, ) from sklearn.utils._array_api import ( - device as array_api_device, + get_namespace, + yield_namespace_device_dtype_combinations, ) from sklearn.utils._mocking import MockDataFrame from sklearn.utils._testing import ( @@ -3683,12 +3682,13 @@ def test_d2_brier_score_warning_on_less_than_two_samples(): @pytest.mark.parametrize( - "array_namespace, device, _", yield_namespace_device_dtype_combinations() + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) -def test_confusion_matrix_array_api(array_namespace, device, _): +def test_confusion_matrix_array_api(array_namespace, device_name, dtype_name): """Test that `confusion_matrix` works for all array types when `labels` are passed such that the inner boolean `need_index_conversion` evaluates to `True`.""" - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) y_true = xp.asarray([1, 2, 3], device=device) y_pred = xp.asarray([4, 5, 6], device=device) @@ -3706,16 +3706,22 @@ def test_confusion_matrix_array_api(array_namespace, device, _): @pytest.mark.parametrize("str_y_true", [False, True]) @pytest.mark.parametrize("use_sample_weight", [False, True]) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", yield_namespace_device_dtype_combinations() + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) def test_probabilistic_metrics_array_api( - prob_metric, str_y_true, use_sample_weight, array_namespace, device_, dtype_name + prob_metric, + str_y_true, + use_sample_weight, + array_namespace, + device_name, + dtype_name, ): """Test that :func:`brier_score_loss`, :func:`log_loss`, :func:`d2_brier_score` and :func:`d2_log_loss_score` work correctly with the array API for binary and multi-class inputs. """ - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) sample_weight = np.array([1, 2, 3, 1]) if use_sample_weight else None # binary case @@ -3729,10 +3735,10 @@ def test_probabilistic_metrics_array_api( extra_kwargs["pos_label"] = "yes" else: y_true_np = np.array([1, 0, 1, 0]) - y_true_xp_or_np = xp.asarray(y_true_np, device=device_) + y_true_xp_or_np = xp.asarray(y_true_np, device=device) y_prob_np = np.array([0.5, 0.2, 0.7, 0.6], dtype=dtype_name) - y_prob_xp = xp.asarray(y_prob_np, device=device_) + y_prob_xp = xp.asarray(y_prob_np, device=device) metric_score_np = prob_metric( y_true_np, y_prob_np, sample_weight=sample_weight, **extra_kwargs ) @@ -3749,7 +3755,7 @@ def test_probabilistic_metrics_array_api( y_true_xp_or_np = np.asarray(y_true_np) else: y_true_np = np.array([0, 1, 2, 3]) - y_true_xp_or_np = xp.asarray(y_true_np, device=device_) + y_true_xp_or_np = xp.asarray(y_true_np, device=device) y_prob_np = np.array( [ @@ -3760,7 +3766,7 @@ def test_probabilistic_metrics_array_api( ], dtype=dtype_name, ) - y_prob_xp = xp.asarray(y_prob_np, device=device_) + y_prob_xp = xp.asarray(y_prob_np, device=device) metric_score_np = prob_metric(y_true_np, y_prob_np) with config_context(array_api_dispatch=True): metric_score_xp = prob_metric(y_true_xp_or_np, y_prob_xp) @@ -3773,16 +3779,21 @@ def test_probabilistic_metrics_array_api( ) @pytest.mark.parametrize("use_sample_weight", [False, True]) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", yield_namespace_device_dtype_combinations() + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) def test_probabilistic_metrics_multilabel_array_api( - prob_metric, use_sample_weight, array_namespace, device_, dtype_name + prob_metric, + use_sample_weight, + array_namespace, + device_name, + dtype_name, ): """Test that :func:`brier_score_loss`, :func:`log_loss`, :func:`d2_brier_score` and :func:`d2_log_loss_score` work correctly with the array API for multi-label inputs. """ - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) sample_weight = np.array([1, 2, 3, 1]) if use_sample_weight else None y_true_np = np.array( [ @@ -3793,7 +3804,7 @@ def test_probabilistic_metrics_multilabel_array_api( ], dtype=dtype_name, ) - y_true_xp = xp.asarray(y_true_np, device=device_) + y_true_xp = xp.asarray(y_true_np, device=device) y_prob_np = np.array( [ [0.15, 0.27, 0.46, 0.12], @@ -3803,7 +3814,7 @@ def test_probabilistic_metrics_multilabel_array_api( ], dtype=dtype_name, ) - y_prob_xp = xp.asarray(y_prob_np, device=device_) + y_prob_xp = xp.asarray(y_prob_np, device=device) metric_score_np = prob_metric(y_true_np, y_prob_np, sample_weight=sample_weight) with config_context(array_api_dispatch=True): metric_score_xp = prob_metric(y_true_xp, y_prob_xp, sample_weight=sample_weight) @@ -3812,24 +3823,21 @@ def test_probabilistic_metrics_multilabel_array_api( @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("prob_metric", [brier_score_loss, d2_brier_score]) def test_pos_label_in_brier_score_metrics_array_api( - prob_metric, array_namespace, device_, dtype_name + prob_metric, array_namespace, device_name, dtype_name ): """Check `pos_label` handled correctly when labels not in {-1, 1} or {0, 1}.""" # For 'brier_score' metrics, when `pos_label=None` and labels are not strings, # `pos_label` defaults to the largest label. - xp = _array_api_for_tests(array_namespace, device_) - y_true_pos_1 = xp.asarray(np.array([1, 0, 1, 0]), device=device_) + xp, device = _array_api_for_tests(array_namespace, device_name) + y_true_pos_1 = xp.asarray(np.array([1, 0, 1, 0]), device=device) # Result should be the same when we use 2's for the label instead of 1's - y_true_pos_2 = xp.asarray(np.array([2, 0, 2, 0]), device=device_) - y_prob = xp.asarray( - np.array([0.5, 0.2, 0.7, 0.6], dtype=dtype_name), device=device_ - ) + y_true_pos_2 = xp.asarray(np.array([2, 0, 2, 0]), device=device) + y_prob = xp.asarray(np.array([0.5, 0.2, 0.7, 0.6], dtype=dtype_name), device=device) with config_context(array_api_dispatch=True): metric_pos_1 = prob_metric(y_true_pos_1, y_prob) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 7e6886d8639bd..a425eeedb640d 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -86,13 +86,14 @@ from sklearn.utils._array_api import ( _atol_for_type, _convert_to_numpy, - _get_namespace_device_dtype_ids, _max_precision_float_dtype, - device, get_namespace, yield_mixed_namespace_input_permutations, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._testing import ( _array_api_for_tests, assert_allclose, @@ -2025,9 +2026,9 @@ def test_metrics_pos_label_error_str(metric, y_pred_threshold, dtype_y_str): def check_array_api_metric( - metric, array_namespace, device, dtype_name, a_np, b_np, **metric_kwargs + metric, array_namespace, device_name, dtype_name, a_np, b_np, **metric_kwargs ): - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) a_xp = xp.asarray(a_np, device=device) b_xp = xp.asarray(b_np, device=device) @@ -2104,7 +2105,7 @@ def _check_each_metric_matches(metric_a, metric_b, convert_a=False): def check_array_api_binary_classification_metric( - metric, array_namespace, device, dtype_name + metric, array_namespace, device_name, dtype_name ): y_true_np = np.array([0, 0, 1, 1]) y_pred_np = np.array([0, 1, 0, 1]) @@ -2116,7 +2117,7 @@ def check_array_api_binary_classification_metric( check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2129,7 +2130,7 @@ def check_array_api_binary_classification_metric( check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2139,7 +2140,7 @@ def check_array_api_binary_classification_metric( def check_array_api_multiclass_classification_metric( - metric, array_namespace, device, dtype_name + metric, array_namespace, device_name, dtype_name ): y_true_np = np.array([0, 1, 2, 3]) y_pred_np = np.array([0, 1, 0, 2]) @@ -2169,7 +2170,7 @@ def check_array_api_multiclass_classification_metric( check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2182,7 +2183,7 @@ def check_array_api_multiclass_classification_metric( check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2192,7 +2193,7 @@ def check_array_api_multiclass_classification_metric( def check_array_api_multilabel_classification_metric( - metric, array_namespace, device, dtype_name + metric, array_namespace, device_name, dtype_name ): y_true_np = np.array([[1, 1], [0, 1], [0, 0]], dtype=dtype_name) y_pred_np = np.array([[1, 1], [1, 1], [1, 1]], dtype=dtype_name) @@ -2209,7 +2210,7 @@ def check_array_api_multilabel_classification_metric( check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2222,7 +2223,7 @@ def check_array_api_multilabel_classification_metric( check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2231,7 +2232,7 @@ def check_array_api_multilabel_classification_metric( ) -def check_array_api_regression_metric(metric, array_namespace, device, dtype_name): +def check_array_api_regression_metric(metric, array_namespace, device_name, dtype_name): func_name = metric.func.__name__ if isinstance(metric, partial) else metric.__name__ if func_name == "mean_poisson_deviance" and sp_version < parse_version("1.14.0"): pytest.skip( @@ -2250,7 +2251,7 @@ def check_array_api_regression_metric(metric, array_namespace, device, dtype_nam check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2265,7 +2266,7 @@ def check_array_api_regression_metric(metric, array_namespace, device, dtype_nam check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2274,7 +2275,7 @@ def check_array_api_regression_metric(metric, array_namespace, device, dtype_nam def check_array_api_regression_metric_multioutput( - metric, array_namespace, device, dtype_name + metric, array_namespace, device_name, dtype_name ): y_true_np = np.array([[1, 3, 2], [1, 2, 2]], dtype=dtype_name) y_pred_np = np.array([[1, 4, 4], [1, 1, 1]], dtype=dtype_name) @@ -2282,7 +2283,7 @@ def check_array_api_regression_metric_multioutput( check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2294,7 +2295,7 @@ def check_array_api_regression_metric_multioutput( check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2304,7 +2305,7 @@ def check_array_api_regression_metric_multioutput( check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2314,7 +2315,7 @@ def check_array_api_regression_metric_multioutput( check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=y_true_np, b_np=y_pred_np, @@ -2322,7 +2323,7 @@ def check_array_api_regression_metric_multioutput( ) -def check_array_api_metric_pairwise(metric, array_namespace, device, dtype_name): +def check_array_api_metric_pairwise(metric, array_namespace, device_name, dtype_name): X_np = np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]], dtype=dtype_name) Y_np = np.array([[0.2, 0.3, 0.4], [0.5, 0.6, 0.7]], dtype=dtype_name) @@ -2332,7 +2333,7 @@ def check_array_api_metric_pairwise(metric, array_namespace, device, dtype_name) check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=X_np, b_np=Y_np, @@ -2343,7 +2344,7 @@ def check_array_api_metric_pairwise(metric, array_namespace, device, dtype_name) check_array_api_metric( metric, array_namespace, - device, + device_name, dtype_name, a_np=X_np, b_np=Y_np, @@ -2511,13 +2512,14 @@ def yield_metric_checker_combinations(metric_checkers=array_api_metric_checkers) @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("metric, check_func", yield_metric_checker_combinations()) -def test_array_api_compliance(metric, array_namespace, device, dtype_name, check_func): - check_func(metric, array_namespace, device, dtype_name) +def test_array_api_compliance( + metric, array_namespace, device_name, dtype_name, check_func +): + check_func(metric, array_namespace, device_name, dtype_name) def _check_output(out_np, out_xp, xp_to, y2_xp): @@ -2526,7 +2528,7 @@ def _check_output(out_np, out_xp, xp_to, y2_xp): elif hasattr(out_np, "shape"): assert hasattr(out_xp, "shape") assert get_namespace(out_xp)[0] == xp_to - assert device(out_xp) == device(y2_xp) + assert array_api_device(out_xp) == array_api_device(y2_xp) # `classification_report` returns str (with default `output_dict=False`) elif isinstance(out_np, str): assert isinstance(out_xp, str) @@ -2553,8 +2555,12 @@ def test_mixed_array_api_namespace_input_compliance( If the output is a tuple, checks that each element, whether float or array, is correct, as detailed above. """ - xp_to = _array_api_for_tests(to_ns_and_device.xp, to_ns_and_device.device) - xp_from = _array_api_for_tests(from_ns_and_device.xp, from_ns_and_device.device) + xp_to, device_to = _array_api_for_tests( + to_ns_and_device.xp, device_name=to_ns_and_device.device + ) + xp_from, device_from = _array_api_for_tests( + from_ns_and_device.xp, device_name=from_ns_and_device.device + ) metric = ALL_METRICS[metric_name] @@ -2593,21 +2599,19 @@ def _get_dtype(data, xp, device): for data_case in data_cases: y1, y2 = data_all[data_case] - dtype = _get_dtype(y1, xp_from, from_ns_and_device.device) - y1_xp = xp_from.asarray(y1, device=from_ns_and_device.device, dtype=dtype) + dtype = _get_dtype(y1, xp_from, device_from) + y1_xp = xp_from.asarray(y1, device=device_from, dtype=dtype) metric_kwargs_xp = metric_kwargs_np = {} if metric_name not in METRICS_WITHOUT_SAMPLE_WEIGHT: # use `from_ns_and_device` for `sample_weight` as well sample_weight_np = np.array(sample_weight) metric_kwargs_np = {"sample_weight": sample_weight_np} - sample_weight_xp = xp_from.asarray( - sample_weight_np, device=from_ns_and_device.device - ) + sample_weight_xp = xp_from.asarray(sample_weight_np, device=device_from) metric_kwargs_xp = {"sample_weight": sample_weight_xp} - dtype = _get_dtype(y2, xp_to, to_ns_and_device.device) - y2_xp = xp_to.asarray(y2, device=to_ns_and_device.device, dtype=dtype) + dtype = _get_dtype(y2, xp_to, device_to) + y2_xp = xp_to.asarray(y2, device=device_to, dtype=dtype) metric_xp = metric(y1_xp, y2_xp, **metric_kwargs_xp) metric_np = metric(y1, y2, **metric_kwargs_np) @@ -2657,9 +2661,8 @@ def test_array_api_classification_string_input(metric_name): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) # All continuous classification metrics, minus multilabel ranking metrics # (`METRIC_UNDEFINED_BINARY`), which take label indicator input (and thus never @@ -2675,7 +2678,7 @@ def test_array_api_classification_string_input(metric_name): ), ) def test_array_api_classification_mixed_string_numeric_input( - metric_name, array_namespace, device, dtype_name + metric_name, array_namespace, device_name, dtype_name ): """Check string inputs and numeric inputs from mixed namespace and devices accepted. @@ -2683,7 +2686,7 @@ def test_array_api_classification_mixed_string_numeric_input( a mix of string and numeric inputs (numeric input should be able to be of any supported namespace/device), with array API dispatch enabled. """ - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) metric = ALL_METRICS[metric_name] # Binary diff --git a/sklearn/metrics/tests/test_pairwise.py b/sklearn/metrics/tests/test_pairwise.py index b6e96e76c2465..80d779be8269b 100644 --- a/sklearn/metrics/tests/test_pairwise.py +++ b/sklearn/metrics/tests/test_pairwise.py @@ -50,7 +50,6 @@ from sklearn.preprocessing import normalize from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, get_namespace, xpx, yield_namespace_device_dtype_combinations, @@ -152,14 +151,13 @@ def test_pairwise_distances_for_dense_data(global_dtype): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("metric", ["cosine", "euclidean", "manhattan"]) -def test_pairwise_distances_array_api(array_namespace, device, dtype_name, metric): +def test_pairwise_distances_array_api(array_namespace, device_name, dtype_name, metric): # Test array API support in pairwise_distances. - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) rng = np.random.RandomState(0) # Euclidean distance should be equivalent to calling the function. @@ -390,9 +388,8 @@ def test_pairwise_parallel(func, metric, kwds, dtype): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "func, metric, kwds", @@ -405,9 +402,9 @@ def test_pairwise_parallel(func, metric, kwds, dtype): ], ) def test_pairwise_parallel_array_api( - func, metric, kwds, array_namespace, device, dtype_name + func, metric, kwds, array_namespace, device_name, dtype_name ): - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) rng = np.random.RandomState(0) X_np = np.array(5 * rng.random_sample((5, 4)), dtype=dtype_name) Y_np = np.array(5 * rng.random_sample((3, 4)), dtype=dtype_name) @@ -482,17 +479,16 @@ def test_pairwise_kernels(metric, csr_container): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "metric", ["rbf", "sigmoid", "polynomial", "linear", "laplacian", "chi2", "additive_chi2"], ) -def test_pairwise_kernels_array_api(metric, array_namespace, device, dtype_name): +def test_pairwise_kernels_array_api(metric, array_namespace, device_name, dtype_name): # Test array API support in pairwise_kernels. - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) rng = np.random.RandomState(0) X_np = 10 * rng.random_sample((5, 4)) diff --git a/sklearn/mixture/tests/test_gaussian_mixture.py b/sklearn/mixture/tests/test_gaussian_mixture.py index 794a4dfc070ce..ef13457d1caae 100644 --- a/sklearn/mixture/tests/test_gaussian_mixture.py +++ b/sklearn/mixture/tests/test_gaussian_mixture.py @@ -32,11 +32,12 @@ ) from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, - device, get_namespace, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._testing import ( _array_api_for_tests, assert_allclose, @@ -1486,32 +1487,31 @@ def test_gaussian_mixture_all_init_does_not_estimate_gaussian_parameters( @pytest.mark.parametrize("init_params", ["random", "random_from_data"]) @pytest.mark.parametrize("covariance_type", ["full", "tied", "diag", "spherical"]) @pytest.mark.parametrize( - "array_namespace, device_, dtype", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("use_gmm_array_constructor_arguments", [False, True]) def test_gaussian_mixture_array_api_compliance( init_params, covariance_type, array_namespace, - device_, - dtype, + device_name, + dtype_name, use_gmm_array_constructor_arguments, ): """Test that array api works in GaussianMixture.fit().""" - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) rng = np.random.RandomState(0) rand_data = RandomData(rng) X = rand_data.X[covariance_type] - X = X.astype(dtype) + X = X.astype(dtype_name) if use_gmm_array_constructor_arguments: additional_kwargs = { - "means_init": rand_data.means.astype(dtype), - "precisions_init": rand_data.precisions[covariance_type].astype(dtype), - "weights_init": rand_data.weights.astype(dtype), + "means_init": rand_data.means.astype(dtype_name), + "precisions_init": rand_data.precisions[covariance_type].astype(dtype_name), + "weights_init": rand_data.weights.astype(dtype_name), } else: additional_kwargs = {} @@ -1525,20 +1525,20 @@ def test_gaussian_mixture_array_api_compliance( ) gmm.fit(X) - X_xp = xp.asarray(X, device=device_) + X_xp = xp.asarray(X, device=device) with sklearn.config_context(array_api_dispatch=True): gmm_xp = sklearn.clone(gmm) for param_name, param_value in additional_kwargs.items(): - arg_xp = xp.asarray(param_value, device=device_) + arg_xp = xp.asarray(param_value, device=device) setattr(gmm_xp, param_name, arg_xp) gmm_xp.fit(X_xp) assert get_namespace(gmm_xp.means_)[0] == xp assert get_namespace(gmm_xp.covariances_)[0] == xp - assert device(gmm_xp.means_) == device(X_xp) - assert device(gmm_xp.covariances_) == device(X_xp) + assert array_api_device(gmm_xp.means_) == array_api_device(X_xp) + assert array_api_device(gmm_xp.covariances_) == array_api_device(X_xp) predict_xp = gmm_xp.predict(X_xp) predict_proba_xp = gmm_xp.predict_proba(X_xp) @@ -1557,15 +1557,15 @@ def test_gaussian_mixture_array_api_compliance( ] for result in results: assert get_namespace(result)[0] == xp - assert device(result) == device(X_xp) + assert array_api_device(result) == array_api_device(X_xp) for score in [score_xp, aic_xp, bic_xp]: assert isinstance(score, float) # Define specific rtol to make tests pass - default_rtol = 1e-4 if dtype == "float32" else 1e-7 - increased_atol = 5e-4 if dtype == "float32" else 0 - increased_rtol = 1e-3 if dtype == "float32" else 1e-7 + default_rtol = 1e-4 if dtype_name == "float32" else 1e-7 + increased_atol = 5e-4 if dtype_name == "float32" else 0 + increased_rtol = 1e-3 if dtype_name == "float32" else 1e-7 # Check fitted attributes assert_allclose(gmm.means_, _convert_to_numpy(gmm_xp.means_, xp=xp)) @@ -1617,12 +1617,11 @@ def test_gaussian_mixture_array_api_compliance( @skip_if_array_api_compat_not_configured @pytest.mark.parametrize("init_params", ["kmeans", "k-means++"]) @pytest.mark.parametrize( - "array_namespace, device_, dtype", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) def test_gaussian_mixture_raises_where_array_api_not_implemented( - init_params, array_namespace, device_, dtype + init_params, array_namespace, device_name, dtype_name ): X, _ = make_blobs( n_samples=100, diff --git a/sklearn/model_selection/tests/test_search.py b/sklearn/model_selection/tests/test_search.py index d652a7fdce1f3..256cb5b9e057f 100644 --- a/sklearn/model_selection/tests/test_search.py +++ b/sklearn/model_selection/tests/test_search.py @@ -83,7 +83,6 @@ ) from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor from sklearn.utils._array_api import ( - _get_namespace_device_dtype_ids, yield_namespace_device_dtype_combinations, ) from sklearn.utils._mocking import CheckingClassifier, MockDataFrame @@ -2863,19 +2862,20 @@ def test_cv_results_multi_size_array(): @pytest.mark.parametrize( - "array_namespace, device, dtype", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("SearchCV", [GridSearchCV, RandomizedSearchCV]) -def test_array_api_search_cv_classifier(SearchCV, array_namespace, device, dtype): - xp = _array_api_for_tests(array_namespace, device) +def test_array_api_search_cv_classifier( + SearchCV, array_namespace, device_name, dtype_name +): + xp, device = _array_api_for_tests(array_namespace, device_name) X = np.arange(100).reshape((10, 10)) - X_np = X.astype(dtype) + X_np = X.astype(dtype_name) X_xp = xp.asarray(X_np, device=device) - # y should always be an integer, no matter what `dtype` is + # y should always be an integer, no matter what `dtype_name` is y_np = np.array([0] * 5 + [1] * 5) y_xp = xp.asarray(y_np, device=device) diff --git a/sklearn/model_selection/tests/test_split.py b/sklearn/model_selection/tests/test_split.py index 052273cf4734f..d9f4eadf37a4b 100644 --- a/sklearn/model_selection/tests/test_split.py +++ b/sklearn/model_selection/tests/test_split.py @@ -43,7 +43,6 @@ from sklearn.tests.metadata_routing_common import assert_request_is_empty from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, get_namespace, yield_namespace_device_dtype_combinations, ) @@ -1342,9 +1341,8 @@ def test_train_test_split_default_test_size(train_size, exp_train, exp_test): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "shuffle,stratify", @@ -1356,9 +1354,9 @@ def test_train_test_split_default_test_size(train_size, exp_train, exp_test): ), ) def test_array_api_train_test_split( - shuffle, stratify, array_namespace, device, dtype_name + shuffle, stratify, array_namespace, device_name, dtype_name ): - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) X = np.arange(100).reshape((10, 10)) y = np.arange(10) diff --git a/sklearn/model_selection/tests/test_validation.py b/sklearn/model_selection/tests/test_validation.py index 1ac11d8ccf716..76529c51d13de 100644 --- a/sklearn/model_selection/tests/test_validation.py +++ b/sklearn/model_selection/tests/test_validation.py @@ -85,7 +85,6 @@ from sklearn.utils._array_api import ( _atol_for_type, _convert_to_numpy, - _get_namespace_device_dtype_ids, yield_namespace_device_dtype_combinations, ) from sklearn.utils._mocking import CheckingClassifier, MockDataFrame @@ -2713,17 +2712,16 @@ def test_learning_curve_exploit_incremental_learning_routing(): ) @pytest.mark.parametrize("cv", [None, 3, 5]) @pytest.mark.parametrize( - "namespace, device_, dtype_name", + "namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) def test_cross_val_predict_array_api_compliance( - estimator, cv, namespace, device_, dtype_name + estimator, cv, namespace, device_name, dtype_name ): """Test that `cross_val_predict` functions correctly with the array API with both a classifier and a regressor.""" - xp = _array_api_for_tests(namespace, device_) + xp, device = _array_api_for_tests(namespace, device_name) if is_classifier(estimator): X, y = make_classification( n_samples=1000, n_features=5, n_classes=3, n_informative=3, random_state=42 @@ -2735,8 +2733,8 @@ def test_cross_val_predict_array_api_compliance( X_np = X.astype(dtype_name) y_np = y.astype(dtype_name) - X_xp = xp.asarray(X_np, device=device_) - y_xp = xp.asarray(y_np, device=device_) + X_xp = xp.asarray(X_np, device=device) + y_xp = xp.asarray(y_np, device=device) with config_context(array_api_dispatch=True): pred_xp = cross_val_predict(estimator, X_xp, y_xp, cv=cv) diff --git a/sklearn/preprocessing/tests/test_data.py b/sklearn/preprocessing/tests/test_data.py index 0d0c90e4cb577..704ac326c8b52 100644 --- a/sklearn/preprocessing/tests/test_data.py +++ b/sklearn/preprocessing/tests/test_data.py @@ -40,7 +40,6 @@ from sklearn.utils import gen_batches, shuffle from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import ( @@ -170,22 +169,21 @@ def test_standard_scaler_sample_weight(Xw, X, sample_weight, array_constructor): @pytest.mark.parametrize(["Xw", "X", "sample_weight"], _yield_xw_x_sampleweight()) @pytest.mark.parametrize( - "namespace, dev, dtype", + "namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) def test_standard_scaler_sample_weight_array_api( - Xw, X, sample_weight, namespace, dev, dtype + Xw, X, sample_weight, namespace, device_name, dtype_name ): # N.B. The sample statistics for Xw w/ sample_weight should match # the statistics of X w/ uniform sample_weight. - xp = _array_api_for_tests(namespace, dev) + xp, device = _array_api_for_tests(namespace, device_name) - X = np.array(X).astype(dtype, copy=False) - y = np.ones(X.shape[0]).astype(dtype, copy=False) - Xw = np.array(Xw).astype(dtype, copy=False) - yw = np.ones(Xw.shape[0]).astype(dtype, copy=False) - X_test = np.array([[1.5, 2.5, 3.5], [3.5, 4.5, 5.5]]).astype(dtype, copy=False) + X = np.array(X).astype(dtype_name, copy=False) + y = np.ones(X.shape[0]).astype(dtype_name, copy=False) + Xw = np.array(Xw).astype(dtype_name, copy=False) + yw = np.ones(Xw.shape[0]).astype(dtype_name, copy=False) + X_test = np.array([[1.5, 2.5, 3.5], [3.5, 4.5, 5.5]]).astype(dtype_name, copy=False) scaler = StandardScaler() scaler.fit(X, y) @@ -194,12 +192,12 @@ def test_standard_scaler_sample_weight_array_api( scaler_w.fit(Xw, yw, sample_weight=sample_weight) # Test array-api support and correctness. - X_xp = xp.asarray(X, device=dev) - y_xp = xp.asarray(y, device=dev) - Xw_xp = xp.asarray(Xw, device=dev) - yw_xp = xp.asarray(yw, device=dev) - X_test_xp = xp.asarray(X_test, device=dev) - sample_weight_xp = xp.asarray(sample_weight, device=dev) + X_xp = xp.asarray(X, device=device) + y_xp = xp.asarray(y, device=device) + Xw_xp = xp.asarray(Xw, device=device) + yw_xp = xp.asarray(yw, device=device) + X_test_xp = xp.asarray(X_test, device=device) + sample_weight_xp = xp.asarray(sample_weight, device=device) scaler_w_xp = StandardScaler() with config_context(array_api_dispatch=True): @@ -764,9 +762,8 @@ def test_standard_check_array_of_inverse_transform(): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "check", @@ -789,16 +786,21 @@ def test_standard_check_array_of_inverse_transform(): ids=_get_check_estimator_ids, ) def test_preprocessing_array_api_compliance( - estimator, check, array_namespace, device, dtype_name + estimator, check, array_namespace, device_name, dtype_name ): name = estimator.__class__.__name__ - check(name, estimator, array_namespace, device=device, dtype_name=dtype_name) + check( + name, + estimator, + array_namespace, + device_name=device_name, + dtype_name=dtype_name, + ) @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "check", @@ -807,7 +809,7 @@ def test_preprocessing_array_api_compliance( ) @pytest.mark.parametrize("sample_weight", [True, None]) def test_standard_scaler_array_api_compliance( - check, sample_weight, array_namespace, device, dtype_name + check, sample_weight, array_namespace, device_name, dtype_name ): estimator = StandardScaler() name = estimator.__class__.__name__ @@ -815,7 +817,7 @@ def test_standard_scaler_array_api_compliance( name, estimator, array_namespace, - device=device, + device_name=device_name, dtype_name=dtype_name, check_sample_weight=sample_weight, ) @@ -2107,11 +2109,12 @@ def test_binarizer(constructor): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", yield_namespace_device_dtype_combinations() + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) -def test_binarizer_array_api_int(array_namespace, device, dtype_name): +def test_binarizer_array_api_int(array_namespace, device_name, dtype_name): # Checks that Binarizer works with integer elements and float threshold - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) for dtype_name_ in [dtype_name, "int32", "int64"]: X_np = np.reshape(np.asarray([0, 1, 2, 3, 4], dtype=dtype_name_), (-1, 1)) X_xp = xp.asarray(X_np, device=device) diff --git a/sklearn/preprocessing/tests/test_label.py b/sklearn/preprocessing/tests/test_label.py index 4172a3ad4376a..cbe08fa92f7d3 100644 --- a/sklearn/preprocessing/tests/test_label.py +++ b/sklearn/preprocessing/tests/test_label.py @@ -13,12 +13,13 @@ ) from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, _is_numpy_namespace, - device, get_namespace, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._testing import ( _array_api_for_tests, assert_array_equal, @@ -238,20 +239,21 @@ def test_label_binarizer_sparse_errors(csr_container): ], ) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", yield_namespace_device_dtype_combinations() + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) def test_label_binarizer_array_api_compliance( - y, classes, expected, array_namespace, device_, dtype_name + y, classes, expected, array_namespace, device_name, dtype_name ): """Test that :class:`LabelBinarizer` works correctly with the Array API for binary and multi-class inputs for numerical labels and non-sparse outputs. """ - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) y_np = np.asarray(y) with config_context(array_api_dispatch=True): - y = xp.asarray(y, device=device_) + y = xp.asarray(y, device=device) # `sparse_output=True` is not allowed for non-NumPy namespaces. # Similarly, if `LabelBinarizer` is fitted on a sparse matrix, @@ -272,7 +274,7 @@ def test_label_binarizer_array_api_compliance( "`LabelBinarizer` was fitted on a sparse matrix, and therefore cannot" ) with pytest.raises(ValueError, match=sparse_input_msg): - lb_sparse.inverse_transform(xp.asarray(expected, device=device_)) + lb_sparse.inverse_transform(xp.asarray(expected, device=device)) # Shouldn't raise error in both `fit` and `transform` when `sparse_output=False` lb_xp = LabelBinarizer() @@ -280,22 +282,22 @@ def test_label_binarizer_array_api_compliance( binarized = lb_xp.fit_transform(y) assert get_namespace(binarized)[0].__name__ == xp.__name__ assert "int" in str(binarized.dtype) - assert device(binarized) == device(y) + assert array_api_device(binarized) == array_api_device(y) assert_array_equal(_convert_to_numpy(binarized, xp=xp), np.asarray(expected)) fitted_classes = lb_xp.classes_ assert get_namespace(fitted_classes)[0].__name__ == xp.__name__ - assert device(fitted_classes) == device(y) + assert array_api_device(fitted_classes) == array_api_device(y) assert "int" in str(fitted_classes.dtype) assert_array_equal( _convert_to_numpy(fitted_classes, xp=xp), np.asarray(classes) ) - expected_xp = xp.asarray(expected, device=device_) + expected_xp = xp.asarray(expected, device=device) binarized_inverse = lb_xp.inverse_transform(expected_xp) assert get_namespace(binarized_inverse)[0].__name__ == xp.__name__ assert "int" in str(binarized_inverse.dtype) - assert device(binarized_inverse) == device(y) + assert array_api_device(binarized_inverse) == array_api_device(y) assert_array_equal( _convert_to_numpy(binarized_inverse, xp=xp), _convert_to_numpy(y, xp=xp) ) @@ -764,22 +766,23 @@ def test_invalid_input_label_binarize(): ], ) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", yield_namespace_device_dtype_combinations() + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) def test_label_binarize_array_api_compliance( - y, classes, expected, array_namespace, device_, dtype_name + y, classes, expected, array_namespace, device_name, dtype_name ): """Test that :func:`label_binarize` works correctly with the Array API for binary and multi-class inputs for numerical labels and non-sparse outputs. """ - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) xp_is_numpy = _is_numpy_namespace(xp) numeric_dtype = np.issubdtype(np.asarray(y).dtype, np.integer) and np.issubdtype( np.asarray(classes).dtype, np.integer ) with config_context(array_api_dispatch=True): - y = xp.asarray(y, device=device_) + y = xp.asarray(y, device=device) if numeric_dtype: # `sparse_output=True` is not allowed for non-NumPy namespaces @@ -793,7 +796,7 @@ def test_label_binarize_array_api_compliance( expected = np.asarray(expected, dtype=int) assert get_namespace(binarized)[0].__name__ == xp.__name__ - assert device(binarized) == device(y) + assert array_api_device(binarized) == array_api_device(y) assert "int" in str(binarized.dtype) assert_array_equal(_convert_to_numpy(binarized, xp=xp), expected) @@ -838,9 +841,8 @@ def test_label_encoders_do_not_have_set_output(encoder): @pytest.mark.parametrize( - "array_namespace, device, dtype", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "y", @@ -850,8 +852,10 @@ def test_label_encoders_do_not_have_set_output(encoder): np.array([3, 5, 9, 5, 9, 3]), ], ) -def test_label_encoder_array_api_compliance(y, array_namespace, device, dtype): - xp = _array_api_for_tests(array_namespace, device) +def test_label_encoder_array_api_compliance( + y, array_namespace, device_name, dtype_name +): + xp, device = _array_api_for_tests(array_namespace, device_name) xp_y = xp.asarray(y, device=device) with config_context(array_api_dispatch=True): xp_label = LabelEncoder() diff --git a/sklearn/preprocessing/tests/test_polynomial.py b/sklearn/preprocessing/tests/test_polynomial.py index b24ca11cafbfd..512fc9f342462 100644 --- a/sklearn/preprocessing/tests/test_polynomial.py +++ b/sklearn/preprocessing/tests/test_polynomial.py @@ -21,12 +21,13 @@ ) from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, _is_numpy_namespace, - device, get_namespace, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._mask import _get_mask from sklearn.utils._testing import ( _array_api_for_tests, @@ -1332,9 +1333,8 @@ def test_csr_polynomial_expansion_windows_fail(csr_container): @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("interaction_only", [True, False]) @pytest.mark.parametrize("include_bias", [True, False]) @@ -1345,14 +1345,14 @@ def test_polynomial_features_array_api_compliance( include_bias, interaction_only, array_namespace, - device_, + device_name, dtype_name, ): """Test array API compliance for PolynomialFeatures on 2 features up to degree 3.""" - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) X, _ = two_features_degree3 X_np = X.astype(dtype_name) - X_xp = xp.asarray(X_np, device=device_) + X_xp = xp.asarray(X_np, device=device) with config_context(array_api_dispatch=True): tf_np = PolynomialFeatures( degree=degree, include_bias=include_bias, interaction_only=interaction_only @@ -1365,23 +1365,22 @@ def test_polynomial_features_array_api_compliance( out_xp = tf_xp.transform(X_xp) assert_allclose(_convert_to_numpy(out_xp, xp=xp), out_np) assert get_namespace(out_xp)[0].__name__ == xp.__name__ - assert device(out_xp) == device(X_xp) + assert array_api_device(out_xp) == array_api_device(X_xp) assert out_xp.dtype == X_xp.dtype @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) def test_polynomial_features_array_api_raises_on_order_F( - array_namespace, device_, dtype_name + array_namespace, device_name, dtype_name ): """Test that PolynomialFeatures with order='F' raises ValueError on array API namespaces other than numpy.""" - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) X = np.arange(6).reshape((3, 2)).astype(dtype_name) - X_xp = xp.asarray(X, device=device_) + X_xp = xp.asarray(X, device=device) msg = "PolynomialFeatures does not support order='F' for non-numpy arrays" with config_context(array_api_dispatch=True): pf = PolynomialFeatures(order="F").fit(X_xp) diff --git a/sklearn/tests/test_calibration.py b/sklearn/tests/test_calibration.py index 62d4608b21770..9ec27e4f01a9c 100644 --- a/sklearn/tests/test_calibration.py +++ b/sklearn/tests/test_calibration.py @@ -49,11 +49,12 @@ from sklearn.tree import DecisionTreeClassifier from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, - device, get_namespace, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._mocking import CheckingClassifier from sklearn.utils._tags import get_tags from sklearn.utils._testing import ( @@ -1221,17 +1222,16 @@ def test_error_less_class_samples_than_folds(): @pytest.mark.parametrize("ensemble", [False, True]) @pytest.mark.parametrize("use_sample_weight", [False, True]) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) def test_temperature_scaling_array_api_compliance( - ensemble, use_sample_weight, array_namespace, device_, dtype_name + ensemble, use_sample_weight, array_namespace, device_name, dtype_name ): """Check that `CalibratedClassifierCV` with temperature scaling is compatible with the array API""" - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) X, y = make_classification( n_samples=1000, n_features=10, @@ -1246,13 +1246,13 @@ def test_temperature_scaling_array_api_compliance( X_train = X_train.astype(dtype_name) y_train = y_train.astype(dtype_name) - X_train_xp = xp.asarray(X_train, device=device_) - y_train_xp = xp.asarray(y_train, device=device_) + X_train_xp = xp.asarray(X_train, device=device) + y_train_xp = xp.asarray(y_train, device=device) X_cal = X_cal.astype(dtype_name) y_cal = y_cal.astype(dtype_name) - X_cal_xp = xp.asarray(X_cal, device=device_) - y_cal_xp = xp.asarray(y_cal, device=device_) + X_cal_xp = xp.asarray(X_cal, device=device) + y_cal_xp = xp.asarray(y_cal, device=device) if use_sample_weight: sample_weight = np.ones_like(y_cal) @@ -1279,7 +1279,7 @@ def test_temperature_scaling_array_api_compliance( rtol = 1e-3 if dtype_name == "float32" else 1e-7 assert get_namespace(calibrator_xp.beta_)[0].__name__ == xp.__name__ assert calibrator_xp.beta_.dtype == X_cal_xp.dtype - assert device(calibrator_xp.beta_) == device(X_cal_xp) + assert array_api_device(calibrator_xp.beta_) == array_api_device(X_cal_xp) assert_allclose( _convert_to_numpy(calibrator_xp.beta_, xp=xp), calibrator_np.beta_, @@ -1292,12 +1292,11 @@ def test_temperature_scaling_array_api_compliance( @pytest.mark.parametrize("ensemble", [False, True]) @pytest.mark.parametrize("use_sample_weight", [False, True]) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) def test_temperature_scaling_array_api_with_str_y_estimator_not_prefit( - ensemble, use_sample_weight, array_namespace, device_, dtype_name + ensemble, use_sample_weight, array_namespace, device_name, dtype_name ): """Check that `CalibratedClassifierCV` with temperature scaling is compatible with the array API when `y` is an ndarray of strings and the estimator is not @@ -1308,7 +1307,7 @@ def test_temperature_scaling_array_api_with_str_y_estimator_not_prefit( # the array API when `y` is an ndarray of strings and we fit # `LinearDiscriminantAnalysis` beforehand. In this regard # `LinearDiscriminantAnalysis` will also need modifications. - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) X, y = make_classification( n_samples=500, n_features=10, @@ -1322,7 +1321,7 @@ def test_temperature_scaling_array_api_with_str_y_estimator_not_prefit( str_mapping = np.asarray(["a", "b", "c", "d", "e"]) X = X.astype(dtype_name) y_str = str_mapping[y] - X_xp = xp.asarray(X, device=device_) + X_xp = xp.asarray(X, device=device) if use_sample_weight: sample_weight = np.ones_like(y) @@ -1351,7 +1350,7 @@ def test_temperature_scaling_array_api_with_str_y_estimator_not_prefit( rtol = 1e-3 if dtype_name == "float32" else 1e-7 assert get_namespace(calibrator_xp.beta_)[0].__name__ == xp.__name__ assert calibrator_xp.beta_.dtype == X_xp.dtype - assert device(calibrator_xp.beta_) == device(X_xp) + assert array_api_device(calibrator_xp.beta_) == array_api_device(X_xp) assert_allclose( _convert_to_numpy(calibrator_xp.beta_, xp=xp), calibrator_np.beta_, diff --git a/sklearn/tests/test_kernel_approximation.py b/sklearn/tests/test_kernel_approximation.py index 9372ddb2ca72a..4de61d14678c2 100644 --- a/sklearn/tests/test_kernel_approximation.py +++ b/sklearn/tests/test_kernel_approximation.py @@ -350,16 +350,17 @@ def test_nystroem_approximation(): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", yield_namespace_device_dtype_combinations() + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) @pytest.mark.parametrize( "kernel", list(kernel_metrics()) + [_linear_kernel, "precomputed"] ) @pytest.mark.parametrize("n_components", [2, 100]) def test_nystroem_approximation_array_api( - array_namespace, device, dtype_name, kernel, n_components + array_namespace, device_name, dtype_name, kernel, n_components ): - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) rnd = np.random.RandomState(0) n_samples = 10 # Ensure full-rank linear kernel to limit the impact of device-specific diff --git a/sklearn/tests/test_naive_bayes.py b/sklearn/tests/test_naive_bayes.py index 5a82c916db640..99dd78ce82884 100644 --- a/sklearn/tests/test_naive_bayes.py +++ b/sklearn/tests/test_naive_bayes.py @@ -17,10 +17,11 @@ ) from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, - device, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._testing import ( _array_api_for_tests, assert_allclose, @@ -995,23 +996,22 @@ def test_categorical_input_tag(Estimator): @pytest.mark.parametrize("use_str_y", [False, True]) @pytest.mark.parametrize("use_sample_weight", [False, True]) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) def test_gnb_array_api_compliance( - use_str_y, use_sample_weight, array_namespace, device_, dtype_name + use_str_y, use_sample_weight, array_namespace, device_name, dtype_name ): """Tests that :class:`GaussianNB` works correctly with array API inputs.""" - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) X_np = X.astype(dtype_name) - X_xp = xp.asarray(X_np, device=device_) + X_xp = xp.asarray(X_np, device=device) if use_str_y: y_np = np.array(["a", "a", "a", "b", "b", "b"]) y_xp_or_np = np.array(["a", "a", "a", "b", "b", "b"]) else: y_np = y.astype(dtype_name) - y_xp_or_np = xp.asarray(y_np, device=device_) + y_xp_or_np = xp.asarray(y_np, device=device) if use_sample_weight: sample_weight = np.array([1, 2, 3, 1, 2, 3]) @@ -1028,24 +1028,24 @@ def test_gnb_array_api_compliance( xp_attr = getattr(clf_xp, fitted_attr) np_attr = getattr(clf_np, fitted_attr) assert xp_attr.dtype == X_xp.dtype - assert device(xp_attr) == device(X_xp) + assert array_api_device(xp_attr) == array_api_device(X_xp) assert_allclose(_convert_to_numpy(xp_attr, xp=xp), np_attr) y_pred_xp = clf_xp.predict(X_xp) if not use_str_y: - assert device(y_pred_xp) == device(X_xp) + assert array_api_device(y_pred_xp) == array_api_device(X_xp) y_pred_xp = _convert_to_numpy(y_pred_xp, xp=xp) assert_array_equal(y_pred_xp, y_pred_np) assert y_pred_xp.dtype == y_pred_np.dtype y_pred_proba_xp = clf_xp.predict_proba(X_xp) assert y_pred_proba_xp.dtype == X_xp.dtype - assert device(y_pred_proba_xp) == device(X_xp) + assert array_api_device(y_pred_proba_xp) == array_api_device(X_xp) assert_allclose(_convert_to_numpy(y_pred_proba_xp, xp=xp), y_pred_proba_np) y_pred_log_proba_xp = clf_xp.predict_log_proba(X_xp) assert y_pred_log_proba_xp.dtype == X_xp.dtype - assert device(y_pred_log_proba_xp) == device(X_xp) + assert array_api_device(y_pred_log_proba_xp) == array_api_device(X_xp) assert_allclose( _convert_to_numpy(y_pred_log_proba_xp, xp=xp), y_pred_log_proba_np ) diff --git a/sklearn/tests/test_pipeline.py b/sklearn/tests/test_pipeline.py index c174af64ae8a8..9eba2f04ec49a 100644 --- a/sklearn/tests/test_pipeline.py +++ b/sklearn/tests/test_pipeline.py @@ -1961,12 +1961,12 @@ def test_feature_union_1d_output(): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), ) -def test_feature_union_array_api_compliance(array_namespace, device, dtype_name): +def test_feature_union_array_api_compliance(array_namespace, device_name, dtype_name): """Test that FeatureUnion with Array API-compatible transformers works.""" - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) rnd = np.random.RandomState(0) n_samples, n_features = 20, 10 X_np = rnd.uniform(size=(n_samples, n_features)).astype(dtype_name) diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 154f8666e52d3..b6cd21f6cf7cb 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -63,11 +63,11 @@ def yield_namespaces(include_numpy_namespaces=True): def yield_namespace_device_dtype_combinations(include_numpy_namespaces=True): - """Yield supported namespace, device, dtype tuples for testing. + """Yield supported namespace, device_name, dtype_name tuples for testing. Use this to test that an estimator works with all combinations. - Use in conjunction with `ids=_get_namespace_device_dtype_ids` to give - clearer pytest parametrization ID names. + Pass the yielded values to `_array_api_for_tests` which returns (xp, device) + for array allocation. Parameters ---------- @@ -79,7 +79,7 @@ def yield_namespace_device_dtype_combinations(include_numpy_namespaces=True): array_namespace : str The name of the Array API namespace. - device : str + device_name : str or None The name of the device on which to allocate the arrays. Can be None to indicate that the default value should be used. @@ -91,45 +91,21 @@ def yield_namespace_device_dtype_combinations(include_numpy_namespaces=True): include_numpy_namespaces=include_numpy_namespaces ): if array_namespace == "torch": - for device, dtype in itertools.product( + for device_name, dtype in itertools.product( ("cpu", "cuda", "xpu"), ("float64", "float32") ): - yield array_namespace, device, dtype + yield array_namespace, device_name, dtype yield array_namespace, "mps", "float32" elif array_namespace == "array_api_strict": - try: - import array_api_strict - - yield array_namespace, array_api_strict.Device("CPU_DEVICE"), "float64" - yield array_namespace, array_api_strict.Device("device1"), "float32" - except ImportError: - # Those combinations will typically be skipped by pytest if - # array_api_strict is not installed but we still need to see them in - # the test output. - yield array_namespace, "CPU_DEVICE", "float64" - yield array_namespace, "device1", "float32" + # Always yield strings for consistent parametrization; _array_api_for_tests + # creates Device objects when needed. + yield array_namespace, "CPU_DEVICE", "float64" + yield array_namespace, "device1", "float32" else: yield array_namespace, None, None -def _get_namespace_device_dtype_ids(param): - """Get pytest parametrization IDs for `yield_namespace_device_dtype_combinations`""" - # Gives clearer IDs for array-api-strict devices, see #31042 for details - try: - import array_api_strict - except ImportError: - # `None` results in the default pytest representation - return None - else: - if param == array_api_strict.Device("CPU_DEVICE"): - return "CPU_DEVICE" - if param == array_api_strict.Device("device1"): - return "device1" - if param == array_api_strict.Device("device2"): - return "device2" - - def yield_mixed_namespace_input_permutations(): """Yield mixed namespace and device inputs for testing. @@ -169,17 +145,8 @@ def yield_mixed_namespace_input_permutations(): "numpy to torch mps", ) - try: - import array_api_strict - - device = array_api_strict.Device("device1") - except ImportError: - # This case will generally be skipped when `array_api_strict` is not installed - # but we still include it so it shows in the test output. - device = None - yield ( - NamespaceAndDevice("array_api_strict", device), + NamespaceAndDevice("array_api_strict", "device1"), NamespaceAndDevice("torch", "cpu"), "array_api_strict to torch cpu", ) diff --git a/sklearn/utils/_testing.py b/sklearn/utils/_testing.py index c8e64fc7f1d63..1d89621858094 100644 --- a/sklearn/utils/_testing.py +++ b/sklearn/utils/_testing.py @@ -1302,7 +1302,25 @@ def __sklearn_tags__(self): ) -def _array_api_for_tests(array_namespace, device): +def _array_api_for_tests(array_namespace, device_name=None): + """Return (xp, device) for array API testing. + + Parameters + ---------- + array_namespace : str + The importable name of the array namespace module. + device_name : str or None, default=None + The device name for array allocation. Can be None for default device. + + Returns + ------- + xp : module + The module object for the requested array namespace. + device : object or None + The library specific device object that can be passed to + xp.asarray(..., device=device). This might be a string and not + a library specific device object. + """ try: array_mod = importlib.import_module(array_namespace) except (ModuleNotFoundError, ImportError): @@ -1319,14 +1337,15 @@ def _array_api_for_tests(array_namespace, device): # corresponding (compatibility wrapped) array namespace based on it. # This is because `cupy` is not the same as the compatibility wrapped # namespace of a CuPy array. + device = None xp = get_namespace(array_mod.asarray(1)) if ( array_namespace == "torch" - and device == "cuda" + and device_name == "cuda" and not xp.backends.cuda.is_built() ): raise SkipTest("PyTorch test requires cuda, which is not available") - elif array_namespace == "torch" and device == "mps": + elif array_namespace == "torch" and device_name == "mps": if os.getenv("PYTORCH_ENABLE_MPS_FALLBACK") != "1": # For now we need PYTORCH_ENABLE_MPS_FALLBACK=1 for all estimators to work # when using the MPS device. @@ -1339,7 +1358,7 @@ def _array_api_for_tests(array_namespace, device): "MPS is not available because the current PyTorch install was not " "built with MPS enabled." ) - elif array_namespace == "torch" and device == "xpu": # pragma: nocover + elif array_namespace == "torch" and device_name == "xpu": # pragma: nocover if not hasattr(xp, "xpu"): # skip xpu testing for PyTorch <2.4 raise SkipTest( @@ -1355,7 +1374,17 @@ def _array_api_for_tests(array_namespace, device): if cupy.cuda.runtime.getDeviceCount() == 0: raise SkipTest("CuPy test requires cuda, which is not available") - return xp + elif array_namespace == "array_api_strict": + # device_name can be a string ("CPU_DEVICE", "device1") or a Device object + # from yield_mixed_namespace_input_permutations + if device_name is not None: + device = xp.Device(device_name) + + # Right now only array_api_strict uses a library specific device + # object. For all other libraries we return a string or `None`. + # This works because strings are accepted as arguments to + # xp.asarray(..., device=) in those libraries. + return xp, device_name if device is None else device def _get_warnings_filters_info_list(): diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index 215728b2ebcc8..2c7c3656c3157 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -355,14 +355,14 @@ def _yield_array_api_checks(estimator, only_numpy=False): # array API support in their tags. for ( array_namespace, - device, + device_name, dtype_name, ) in yield_namespace_device_dtype_combinations(): yield partial( check_array_api_input, array_namespace=array_namespace, + device_name=device_name, dtype_name=dtype_name, - device=device, ) @@ -1060,7 +1060,7 @@ def check_array_api_input( name, estimator_orig, array_namespace, - device=None, + device_name=None, dtype_name="float64", check_values=False, check_sample_weight=False, @@ -1083,7 +1083,7 @@ def check_array_api_input( behavior of any estimator fed with NumPy inputs, even for estimators that do not support array API. """ - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) X, y = make_classification(n_samples=30, n_features=10, random_state=42) X = X.astype(dtype_name, copy=False) @@ -1266,7 +1266,7 @@ def check_array_api_input_and_values( name, estimator_orig, array_namespace, - device=None, + device_name=None, dtype_name="float64", check_sample_weight=False, ): @@ -1274,7 +1274,7 @@ def check_array_api_input_and_values( name, estimator_orig, array_namespace=array_namespace, - device=device, + device_name=device_name, dtype_name=dtype_name, check_values=True, check_sample_weight=check_sample_weight, diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index 13052977ac4d9..9ed3b2014c335 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -21,7 +21,6 @@ _estimator_with_converted_arrays, _expit, _fill_diagonal, - _get_namespace_device_dtype_ids, _half_multinomial_loss, _is_numpy_namespace, _isin, @@ -35,7 +34,6 @@ _nanmin, _ravel, _validate_diagonal_args, - device, get_namespace, get_namespace_and_device, indexing_dtype, @@ -45,6 +43,9 @@ yield_mixed_namespace_input_permutations, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._testing import ( SkipTest, _array_api_for_tests, @@ -154,27 +155,29 @@ def mock_getenv(key): ) def test_move_to_array_api_conversions(array_input, reference): """Check conversion between various namespace-device-pairs.""" - xp_to = _array_api_for_tests(reference.xp, reference.device) - xp_from = _array_api_for_tests(array_input[0], array_input[1]) + xp_to, device_to = _array_api_for_tests(reference.xp, device_name=reference.device) + xp_from, device_from = _array_api_for_tests( + array_input.xp, device_name=array_input.device + ) with config_context(array_api_dispatch=True): - array_in = xp_from.asarray([1, 2, 3], device=array_input.device) - device_reference = device(xp_to.asarray([1], device=reference.device)) + array_in = xp_from.asarray([1, 2, 3], device=device_from) + device_reference = array_api_device(xp_to.asarray(1, device=device_to)) array_out = move_to(array_in, xp=xp_to, device=device_reference) assert get_namespace(array_out)[0] == xp_to - assert device(array_out) == device_reference + assert array_api_device(array_out) == device_reference def test_move_to_sparse(): """Check sparse inputs are handled correctly.""" - xp_numpy = _array_api_for_tests("numpy", None) - xp_torch = _array_api_for_tests("torch", "cpu") + xp_numpy, _ = _array_api_for_tests("numpy", device_name=None) + xp_torch, device = _array_api_for_tests("torch", device_name="cpu") sparse1 = sp.csr_array([0, 1, 2, 3]) numpy_array = numpy.array([1, 2, 3]) with config_context(array_api_dispatch=True): - device_cpu = xp_torch.asarray([1]).device + device_cpu = device # sparse and None to NumPy result1, result2 = move_to(sparse1, None, xp=xp_numpy, device=None) @@ -202,9 +205,8 @@ def test_asarray_with_order(array_api): @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "weights, axis, normalize, expected", @@ -236,14 +238,14 @@ def test_asarray_with_order(array_api): ], ) def test_average( - array_namespace, device_, dtype_name, weights, axis, normalize, expected + array_namespace, device_name, dtype_name, weights, axis, normalize, expected ): - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) array_in = numpy.asarray([[1, 2, 3], [4, 5, 6]], dtype=dtype_name) - array_in = xp.asarray(array_in, device=device_) + array_in = xp.asarray(array_in, device=device) if weights is not None: weights = numpy.asarray(weights, dtype=dtype_name) - weights = xp.asarray(weights, device=device_) + weights = xp.asarray(weights, device=device) with config_context(array_api_dispatch=True): result = _average(array_in, axis=axis, weights=weights, normalize=normalize) @@ -251,19 +253,18 @@ def test_average( if np_version < parse_version("2.0.0") or np_version >= parse_version("2.1.0"): # NumPy 2.0 has a problem with the device attribute of scalar arrays: # https://github.com/numpy/numpy/issues/26850 - assert device(array_in) == device(result) + assert array_api_device(array_in) == array_api_device(result) result = _convert_to_numpy(result, xp) assert_allclose(result, expected, atol=_atol_for_type(dtype_name)) @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(include_numpy_namespaces=False), - ids=_get_namespace_device_dtype_ids, ) -def test_average_raises_with_wrong_dtype(array_namespace, device, dtype_name): - xp = _array_api_for_tests(array_namespace, device) +def test_average_raises_with_wrong_dtype(array_namespace, device_name, dtype_name): + xp, device = _array_api_for_tests(array_namespace, device_name) array_in = numpy.asarray([2, 0], dtype=dtype_name) + 1j * numpy.asarray( [4, 3], dtype=dtype_name @@ -284,9 +285,8 @@ def test_average_raises_with_wrong_dtype(array_namespace, device, dtype_name): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(include_numpy_namespaces=True), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "axis, weights, error, error_msg", @@ -314,9 +314,9 @@ def test_average_raises_with_wrong_dtype(array_namespace, device, dtype_name): ), ) def test_average_raises_with_invalid_parameters( - array_namespace, device, dtype_name, axis, weights, error, error_msg + array_namespace, device_name, dtype_name, axis, weights, error, error_msg ): - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) array_in = numpy.asarray([[1, 2, 3], [4, 5, 6]], dtype=dtype_name) array_in = xp.asarray(array_in, device=device) @@ -329,9 +329,9 @@ def test_average_raises_with_invalid_parameters( def test_device_none_if_no_input(): - assert device() is None + assert array_api_device() is None - assert device(None, "name") is None + assert array_api_device(None, "name") is None @skip_if_array_api_compat_not_configured @@ -364,22 +364,22 @@ def __init__(self, device_name): # early for different devices would prevent the np.asarray conversion to # happen. For example, `r2_score(np.ones(5), torch.ones(5))` should work # fine with array API disabled. - assert device(Array("cpu"), Array("mygpu")) is None + assert array_api_device(Array("cpu"), Array("mygpu")) is None # Test that ValueError is raised if on different devices and array API dispatch is # enabled. err_msg = "Input arrays use different devices: cpu, mygpu" with config_context(array_api_dispatch=True): with pytest.raises(ValueError, match=err_msg): - device(Array("cpu"), Array("mygpu")) + array_api_device(Array("cpu"), Array("mygpu")) # Test expected value is returned otherwise array1 = Array("device") array2 = Array("device") - assert array1.device == device(array1) - assert array1.device == device(array1, array2) - assert array1.device == device(array1, array1, array2) + assert array1.device == array_api_device(array1) + assert array1.device == array_api_device(array1, array2) + assert array1.device == array_api_device(array1, array1, array2) # TODO: add cupy to the list of libraries once the following upstream issue @@ -443,15 +443,14 @@ def test_nan_reductions(library, X, reduction, expected): @pytest.mark.parametrize( - "namespace, _device, _dtype", + "namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_ravel(namespace, _device, _dtype): - xp = _array_api_for_tests(namespace, _device) +def test_ravel(namespace, device_name, dtype_name): + xp, device = _array_api_for_tests(namespace, device_name) array = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] - array_xp = xp.asarray(array, device=_device) + array_xp = xp.asarray(array, device=device) with config_context(array_api_dispatch=True): result = _ravel(array_xp) @@ -532,12 +531,11 @@ def test_convert_estimator_to_array_api(): @pytest.mark.parametrize( - "namespace, _device, _dtype", + "namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_indexing_dtype(namespace, _device, _dtype): - xp = _array_api_for_tests(namespace, _device) +def test_indexing_dtype(namespace, device_name, dtype_name): + xp, device = _array_api_for_tests(namespace, device_name) if _IS_32BIT: assert indexing_dtype(xp) == xp.int32 @@ -546,29 +544,33 @@ def test_indexing_dtype(namespace, _device, _dtype): @pytest.mark.parametrize( - "namespace, _device, _dtype", + "namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_max_precision_float_dtype(namespace, _device, _dtype): - xp = _array_api_for_tests(namespace, _device) - expected_dtype = xp.float32 if _device == "mps" else xp.float64 - assert _max_precision_float_dtype(xp, _device) == expected_dtype +def test_max_precision_float_dtype(namespace, device_name, dtype_name): + xp, device = _array_api_for_tests(namespace, device_name) + expected_dtype = xp.float32 if device_name == "mps" else xp.float64 + assert _max_precision_float_dtype(xp, device) == expected_dtype @pytest.mark.parametrize( - "array_namespace, device, _", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("invert", [True, False]) @pytest.mark.parametrize("assume_unique", [True, False]) @pytest.mark.parametrize("element_size", [6, 10, 14]) @pytest.mark.parametrize("int_dtype", ["int16", "int32", "int64", "uint8"]) def test_isin( - array_namespace, device, _, invert, assume_unique, element_size, int_dtype + array_namespace, + device_name, + dtype_name, + invert, + assume_unique, + element_size, + int_dtype, ): - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) r = element_size // 2 element = 2 * numpy.arange(element_size).reshape((r, 2)).astype(int_dtype) test_elements = numpy.array(numpy.arange(14), dtype=int_dtype) @@ -623,19 +625,23 @@ def test_get_namespace_and_device(): @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) @pytest.mark.parametrize("axis", [0, 1, None, -1, -2]) @pytest.mark.parametrize("sample_weight_type", [None, "int", "float"]) def test_count_nonzero( - array_namespace, device_, dtype_name, csr_container, axis, sample_weight_type + array_namespace, + device_name, + dtype_name, + csr_container, + axis, + sample_weight_type, ): from sklearn.utils.sparsefuncs import count_nonzero as sparse_count_nonzero - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) array = numpy.array([[0, 3, 0], [2, -1, 0], [0, 0, 0], [9, 8, 7], [4, 0, 5]]) if sample_weight_type == "int": sample_weight = numpy.asarray([1, 2, 2, 3, 1]) @@ -646,11 +652,11 @@ def test_count_nonzero( expected = sparse_count_nonzero( csr_container(array), axis=axis, sample_weight=sample_weight ) - array_xp = xp.asarray(array, device=device_) + array_xp = xp.asarray(array, device=device) with config_context(array_api_dispatch=True): result = _count_nonzero( - array_xp, axis=axis, sample_weight=sample_weight, xp=xp, device=device_ + array_xp, axis=axis, sample_weight=sample_weight, xp=xp, device=device ) assert_allclose(_convert_to_numpy(result, xp=xp), expected) @@ -658,7 +664,7 @@ def test_count_nonzero( if np_version < parse_version("2.0.0") or np_version >= parse_version("2.1.0"): # NumPy 2.0 has a problem with the device attribute of scalar arrays: # https://github.com/numpy/numpy/issues/26850 - assert device(array_xp) == device(result) + assert array_api_device(array_xp) == array_api_device(result) @pytest.mark.parametrize( @@ -676,7 +682,7 @@ def test_count_nonzero( ) def test_validate_diagonal_args(array, value, match): """Check `_validate_diagonal_args` raises the correct errors.""" - xp = _array_api_for_tests("numpy", None) + xp, _ = _array_api_for_tests("numpy", device_name=None) with pytest.raises(ValueError, match=match): _validate_diagonal_args(array, value, xp) @@ -685,7 +691,7 @@ def test_validate_diagonal_args(array, value, match): @pytest.mark.parametrize("c_contiguity", [True, False]) def test_fill_and_add_to_diagonal(c_contiguity, function): """Check `_fill/add_to_diagonal` behaviour correct with numpy arrays.""" - xp = _array_api_for_tests("numpy", None) + xp, _ = _array_api_for_tests("numpy", device_name=None) if c_contiguity: array = numpy.zeros((3, 4)) else: @@ -718,23 +724,22 @@ def test_fill_and_add_to_diagonal(c_contiguity, function): @pytest.mark.parametrize("array", ["standard", "transposed", "non-contiguous"]) @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_fill_diagonal(array, array_namespace, device_, dtype_name): +def test_fill_diagonal(array, array_namespace, device_name, dtype_name): """Check array API `_fill_diagonal` consistent with `numpy._fill_diagonal`.""" - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) array_np = numpy.zeros((4, 5), dtype=dtype_name) if array == "transposed": - array_xp = xp.asarray(array_np.copy(), device=device_).T + array_xp = xp.asarray(array_np.copy(), device=device).T array_np = array_np.T elif array == "non-contiguous": - array_xp = xp.asarray(array_np.copy(), device=device_)[::2, ::2] + array_xp = xp.asarray(array_np.copy(), device=device)[::2, ::2] array_np = array_np[::2, ::2] else: - array_xp = xp.asarray(array_np.copy(), device=device_) + array_xp = xp.asarray(array_np.copy(), device=device) numpy.fill_diagonal(array_np, val=1) with config_context(array_api_dispatch=True): @@ -744,17 +749,16 @@ def test_fill_diagonal(array, array_namespace, device_, dtype_name): @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_add_to_diagonal(array_namespace, device_, dtype_name): +def test_add_to_diagonal(array_namespace, device_name, dtype_name): """Check `_add_to_diagonal` consistent between array API xp and numpy namespace.""" - xp = _array_api_for_tests(array_namespace, device_) - np_xp = _array_api_for_tests("numpy", None) + xp, device = _array_api_for_tests(array_namespace, device_name) + np_xp, _ = _array_api_for_tests("numpy", device_name=None) array_np = numpy.zeros((3, 4), dtype=dtype_name) - array_xp = xp.asarray(array_np.copy(), device=device_) + array_xp = xp.asarray(array_np.copy(), device=device) add_val = [1, 2, 3] _fill_diagonal(array_np, value=add_val, xp=np_xp) @@ -774,25 +778,24 @@ def test_sparse_device(csr_container, dispatch): if dispatch and os.environ.get("SCIPY_ARRAY_API") is None: raise SkipTest("SCIPY_ARRAY_API is not set: not checking array_api input") with config_context(array_api_dispatch=dispatch): - assert device(a, b) is None - assert device(a, np_arr) == expected_numpy_array_device + assert array_api_device(a, b) is None + assert array_api_device(a, np_arr) == expected_numpy_array_device assert get_namespace_and_device(a, b)[2] is None assert get_namespace_and_device(a, np_arr)[2] == expected_numpy_array_device @pytest.mark.parametrize( - "namespace, device, dtype_name", + "namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("axis", [None, 0, 1]) -def test_median(namespace, device, dtype_name, axis): +def test_median(namespace, device_name, dtype_name, axis): # Note: depending on the value of `axis`, this test will compare median # computations on arrays of even (4) or odd (5) numbers of elements, hence # will test for median computation with and without interpolation to check # that array API namespaces yield consistent results even when the median is # not mathematically uniquely defined. - xp = _array_api_for_tests(namespace, device) + xp, device = _array_api_for_tests(namespace, device_name) rng = numpy.random.RandomState(0) X_np = rng.uniform(low=0.0, high=1.0, size=(5, 4)).astype(dtype_name) @@ -811,11 +814,12 @@ def test_median(namespace, device, dtype_name, axis): @pytest.mark.parametrize( - "namespace, device, dtype_name", yield_namespace_device_dtype_combinations() + "namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) -def test_expit_logit(namespace, device, dtype_name): +def test_expit_logit(namespace, device_name, dtype_name): rtol = 1e-6 if "float32" in str(dtype_name) else 1e-12 - xp = _array_api_for_tests(namespace, device) + xp, device = _array_api_for_tests(namespace, device_name) with config_context(array_api_dispatch=True): x_np = numpy.linspace(-20, 20, 1000).astype(dtype_name) @@ -836,11 +840,12 @@ def test_expit_logit(namespace, device, dtype_name): @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", yield_namespace_device_dtype_combinations() + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) @pytest.mark.parametrize("axis", [0, 1, None]) -def test_logsumexp_like_scipy_logsumexp(array_namespace, device_, dtype_name, axis): - xp = _array_api_for_tests(array_namespace, device_) +def test_logsumexp_like_scipy_logsumexp(array_namespace, device_name, dtype_name, axis): + xp, device = _array_api_for_tests(array_namespace, device_name) array_np = numpy.asarray( [ [0, 3, 1000], @@ -851,7 +856,7 @@ def test_logsumexp_like_scipy_logsumexp(array_namespace, device_, dtype_name, ax ], dtype=dtype_name, ) - array_xp = xp.asarray(array_np, device=device_) + array_xp = xp.asarray(array_np, device=device) res_np = scipy.special.logsumexp(array_np, axis=axis) @@ -859,8 +864,8 @@ def test_logsumexp_like_scipy_logsumexp(array_namespace, device_, dtype_name, ax # if torch on CPU or array api strict on default device # check that _logsumexp works when array API dispatch is disabled - if (array_namespace == "torch" and device_ == "cpu") or ( - array_namespace == "array_api_strict" and "CPU" in str(device_) + if (array_namespace == "torch" and device_name == "cpu") or ( + array_namespace == "array_api_strict" and "CPU" in str(device_name) ): assert_allclose(_logsumexp(array_xp, axis=axis), res_np, rtol=rtol) @@ -880,7 +885,7 @@ def test_logsumexp_like_scipy_logsumexp(array_namespace, device_, dtype_name, ax ], dtype=dtype_name, ) - array_xp_2 = xp.asarray(array_np_2, device=device_) + array_xp_2 = xp.asarray(array_np_2, device=device) res_np_2 = scipy.special.logsumexp(array_np_2, axis=axis) @@ -901,17 +906,18 @@ def test_logsumexp_like_scipy_logsumexp(array_namespace, device_, dtype_name, ax ], ) def test_supported_float_types(namespace, device_, expected_types): - xp = _array_api_for_tests(namespace, device_) - float_types = supported_float_dtypes(xp, device=device_) + xp, device = _array_api_for_tests(namespace, device_name=device_) + float_types = supported_float_dtypes(xp, device=device) expected = tuple(getattr(xp, dtype_name) for dtype_name in expected_types) assert float_types == expected @pytest.mark.parametrize("use_sample_weight", [False, True]) @pytest.mark.parametrize( - "namespace, device_, dtype_name", yield_namespace_device_dtype_combinations() + "namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) -def test_half_multinomial_loss(use_sample_weight, namespace, device_, dtype_name): +def test_half_multinomial_loss(use_sample_weight, namespace, device_name, dtype_name): """Check that the array API version of :func:`_half_multinomial_loss` works correctly and matches the results produced by :class:`HalfMultinomialLoss` of the private `_loss` module. @@ -921,13 +927,13 @@ def test_half_multinomial_loss(use_sample_weight, namespace, device_, dtype_name rng = numpy.random.RandomState(42) y = rng.randint(0, n_classes, n_samples).astype(dtype_name) pred = rng.rand(n_samples, n_classes).astype(dtype_name) - xp = _array_api_for_tests(namespace, device_) - y_xp = xp.asarray(y, device=device_) - pred_xp = xp.asarray(pred, device=device_) + xp, device = _array_api_for_tests(namespace, device_name) + y_xp = xp.asarray(y, device=device) + pred_xp = xp.asarray(pred, device=device) if use_sample_weight: sample_weight = numpy.ones_like(y) sample_weight[1::2] = 2 - sample_weight_xp = xp.asarray(sample_weight, device=device_) + sample_weight_xp = xp.asarray(sample_weight, device=device) else: sample_weight, sample_weight_xp = None, None @@ -943,11 +949,12 @@ def test_half_multinomial_loss(use_sample_weight, namespace, device_, dtype_name @pytest.mark.parametrize( - "namespace, device_, dtype_name", yield_namespace_device_dtype_combinations() + "namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) -def test_matching_numpy_dtype(namespace, device_, dtype_name): - xp = _array_api_for_tests(namespace, device_) +def test_matching_numpy_dtype(namespace, device_name, dtype_name): + xp, device = _array_api_for_tests(namespace, device_name) X_np = numpy.arange(1000).astype(dtype_name) - X_xp = xp.asarray(X_np, device=device_) + X_xp = xp.asarray(X_np, device=device) ret_dtype = _matching_numpy_dtype(X_xp, xp=xp) assert ret_dtype == X_np.dtype diff --git a/sklearn/utils/tests/test_extmath.py b/sklearn/utils/tests/test_extmath.py index d506c7ced2524..db7987b4498cb 100644 --- a/sklearn/utils/tests/test_extmath.py +++ b/sklearn/utils/tests/test_extmath.py @@ -15,7 +15,6 @@ from sklearn.utils._arpack import _init_arpack_v0 from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, _max_precision_float_dtype, get_namespace, yield_namespace_device_dtype_combinations, @@ -703,18 +702,17 @@ def test_incremental_weighted_mean_and_variance_simple(dtype, as_list): @pytest.mark.parametrize( - "array_namespace, device, dtype", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) def test_incremental_weighted_mean_and_variance_array_api( - array_namespace, device, dtype + array_namespace, device_name, dtype_name ): - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) rng = np.random.RandomState(42) mult = 10 - X = rng.rand(1000, 20).astype(dtype) * mult - sample_weight = rng.rand(X.shape[0]).astype(dtype) * mult + X = rng.rand(1000, 20).astype(dtype_name) * mult + sample_weight = rng.rand(X.shape[0]).astype(dtype_name) * mult mean, var, _ = _incremental_mean_and_var(X, 0, 0, 0, sample_weight=sample_weight) X_xp = xp.asarray(X, device=device) @@ -1104,18 +1102,17 @@ def test_approximate_mode(): @pytest.mark.parametrize( - "array_namespace, device, dtype", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_randomized_svd_array_api_compliance(array_namespace, device, dtype): - xp = _array_api_for_tests(array_namespace, device) +def test_randomized_svd_array_api_compliance(array_namespace, device_name, dtype_name): + xp, device = _array_api_for_tests(array_namespace, device_name) rng = np.random.RandomState(0) - X = rng.normal(size=(30, 10)).astype(dtype) + X = rng.normal(size=(30, 10)).astype(dtype_name) X_xp = xp.asarray(X, device=device) n_components = 5 - atol = 1e-5 if dtype == "float32" else 0 + atol = 1e-5 if dtype_name == "float32" else 0 with config_context(array_api_dispatch=True): u_np, s_np, vt_np = randomized_svd(X, n_components, random_state=0) @@ -1131,19 +1128,20 @@ def test_randomized_svd_array_api_compliance(array_namespace, device, dtype): @pytest.mark.parametrize( - "array_namespace, device, dtype", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_randomized_range_finder_array_api_compliance(array_namespace, device, dtype): - xp = _array_api_for_tests(array_namespace, device) +def test_randomized_range_finder_array_api_compliance( + array_namespace, device_name, dtype_name +): + xp, device = _array_api_for_tests(array_namespace, device_name) rng = np.random.RandomState(0) - X = rng.normal(size=(30, 10)).astype(dtype) + X = rng.normal(size=(30, 10)).astype(dtype_name) X_xp = xp.asarray(X, device=device) size = 5 n_iter = 10 - atol = 1e-5 if dtype == "float32" else 0 + atol = 1e-5 if dtype_name == "float32" else 0 with config_context(array_api_dispatch=True): Q_np = randomized_range_finder(X, size=size, n_iter=n_iter, random_state=0) diff --git a/sklearn/utils/tests/test_indexing.py b/sklearn/utils/tests/test_indexing.py index 4d4b5a4a7bf78..958cca77d8323 100644 --- a/sklearn/utils/tests/test_indexing.py +++ b/sklearn/utils/tests/test_indexing.py @@ -11,11 +11,12 @@ from sklearn.utils import _safe_indexing, resample, shuffle from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, - device, move_to, yield_namespace_device_dtype_combinations, ) +from sklearn.utils._array_api import ( + device as array_api_device, +) from sklearn.utils._indexing import ( _determine_key_type, _get_column_indices, @@ -112,22 +113,21 @@ def test_determine_key_type_slice_error(): @skip_if_array_api_compat_not_configured @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_determine_key_type_array_api(array_namespace, device_, dtype_name): - xp = _array_api_for_tests(array_namespace, device_) +def test_determine_key_type_array_api(array_namespace, device_name, dtype_name): + xp, device = _array_api_for_tests(array_namespace, device_name) with sklearn.config_context(array_api_dispatch=True): - int_array_key = xp.asarray([1, 2, 3], device=device_) + int_array_key = xp.asarray([1, 2, 3], device=device) assert _determine_key_type(int_array_key) == "int" - bool_array_key = xp.asarray([True, False, True], device=device_) + bool_array_key = xp.asarray([True, False, True], device=device) assert _determine_key_type(bool_array_key) == "bool" try: - complex_array_key = xp.asarray([1 + 1j, 2 + 2j, 3 + 3j], device=device_) + complex_array_key = xp.asarray([1 + 1j, 2 + 2j, 3 + 3j], device=device) except TypeError: # Complex numbers are not supported by all Array API libraries. complex_array_key = None @@ -139,9 +139,8 @@ def test_determine_key_type_array_api(array_namespace, device_, dtype_name): @skip_if_array_api_compat_not_configured @pytest.mark.parametrize( - "array_namespace, device_, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize( "indexing_key", @@ -157,17 +156,17 @@ def test_determine_key_type_array_api(array_namespace, device_, dtype_name): ) @pytest.mark.parametrize("axis", [0, 1]) def test_safe_indexing_array_api_support( - array_namespace, device_, dtype_name, indexing_key, axis + array_namespace, device_name, dtype_name, indexing_key, axis ): - xp = _array_api_for_tests(array_namespace, device_) + xp, device = _array_api_for_tests(array_namespace, device_name) array_to_index_np = np.arange(16).reshape(4, 4) expected_result = _safe_indexing(array_to_index_np, indexing_key, axis=axis) - array_to_index_xp = move_to(array_to_index_np, xp=xp, device=device_) + array_to_index_xp = move_to(array_to_index_np, xp=xp, device=device) with sklearn.config_context(array_api_dispatch=True): indexed_array_xp = _safe_indexing(array_to_index_xp, indexing_key, axis=axis) - assert device(indexed_array_xp) == device(array_to_index_xp) + assert array_api_device(indexed_array_xp) == array_api_device(array_to_index_xp) assert indexed_array_xp.dtype == array_to_index_xp.dtype assert_allclose(_convert_to_numpy(indexed_array_xp, xp=xp), expected_result) diff --git a/sklearn/utils/tests/test_multiclass.py b/sklearn/utils/tests/test_multiclass.py index 825258ac3ea6f..1c1ae4bab5f3e 100644 --- a/sklearn/utils/tests/test_multiclass.py +++ b/sklearn/utils/tests/test_multiclass.py @@ -9,7 +9,6 @@ from sklearn.model_selection import ShuffleSplit from sklearn.svm import SVC from sklearn.utils._array_api import ( - _get_namespace_device_dtype_ids, yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import ( @@ -404,12 +403,11 @@ def test_is_multilabel(): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_is_multilabel_array_api_compliance(array_namespace, device, dtype_name): - xp = _array_api_for_tests(array_namespace, device) +def test_is_multilabel_array_api_compliance(array_namespace, device_name, dtype_name): + xp, device = _array_api_for_tests(array_namespace, device_name) for group, group_examples in ARRAY_API_EXAMPLES.items(): dense_exp = group == "multilabel-indicator" diff --git a/sklearn/utils/tests/test_stats.py b/sklearn/utils/tests/test_stats.py index bdd2ba242f927..6bfaa48045fc2 100644 --- a/sklearn/utils/tests/test_stats.py +++ b/sklearn/utils/tests/test_stats.py @@ -259,7 +259,8 @@ def test_weighted_percentile_2d(global_random_seed, percentile_rank, average): @pytest.mark.parametrize( - "array_namespace, device, dtype_name", yield_namespace_device_dtype_combinations() + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) @pytest.mark.parametrize( "data, weights, percentile", @@ -289,10 +290,16 @@ def test_weighted_percentile_2d(global_random_seed, percentile_rank, average): ], ) def test_weighted_percentile_array_api_consistency( - global_random_seed, array_namespace, device, dtype_name, data, weights, percentile + global_random_seed, + array_namespace, + device_name, + dtype_name, + data, + weights, + percentile, ): """Check `_weighted_percentile` gives consistent results with array API.""" - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) # Skip test for percentile=0 edge case (#20528) on namespace/device where # xp.nextafter is broken. This is the case for torch with MPS device: diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 9bbf02ba9228d..20e3a41880b99 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -35,7 +35,6 @@ ) from sklearn.utils._array_api import ( _convert_to_numpy, - _get_namespace_device_dtype_ids, _is_numpy_namespace, yield_namespace_device_dtype_combinations, ) @@ -1037,13 +1036,12 @@ def test_check_consistent_length(): @pytest.mark.parametrize( - "array_namespace, device, _", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) -def test_check_consistent_length_array_api(array_namespace, device, _): +def test_check_consistent_length_array_api(array_namespace, device_name, dtype_name): """Test that check_consistent_length works with different array types.""" - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) with config_context(array_api_dispatch=True): check_consistent_length( @@ -1057,7 +1055,8 @@ def test_check_consistent_length_array_api(array_namespace, device, _): with pytest.raises(ValueError, match="inconsistent numbers of samples"): check_consistent_length( - xp.asarray([1, 2], device=device), xp.asarray([1], device=device) + xp.asarray([1, 2], device=device), + xp.asarray([1], device=device), ) @@ -1662,10 +1661,11 @@ def test_check_sample_weight(): @pytest.mark.parametrize( - "array_namespace,device,dtype", yield_namespace_device_dtype_combinations() + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), ) -def test_check_sample_weight_array_api(array_namespace, device, dtype): - xp = _array_api_for_tests(array_namespace, device) +def test_check_sample_weight_array_api(array_namespace, device_name, dtype_name): + xp, device = _array_api_for_tests(array_namespace, device_name) with config_context(array_api_dispatch=True): # check array order sample_weight = xp.ones(10)[::2] @@ -1684,13 +1684,14 @@ def test_check_pos_label_consistency(y_true): @pytest.mark.parametrize( - "array_namespace,device,dtype", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("y_true", [[0], [0, 1], [-1, 1], [1, 1, 1], [-1, -1, -1]]) -def test_check_pos_label_consistency_array_api(array_namespace, device, dtype, y_true): - xp = _array_api_for_tests(array_namespace, device) +def test_check_pos_label_consistency_array_api( + array_namespace, device_name, dtype_name, y_true +): + xp, device = _array_api_for_tests(array_namespace, device_name) with config_context(array_api_dispatch=True): arr = xp.asarray(y_true, device=device) assert _check_pos_label_consistency(None, arr) == 1 @@ -1705,15 +1706,14 @@ def test_check_pos_label_consistency_invalid(y_true): @pytest.mark.parametrize( - "array_namespace,device,dtype", + "array_namespace, device_name, dtype_name", yield_namespace_device_dtype_combinations(), - ids=_get_namespace_device_dtype_ids, ) @pytest.mark.parametrize("y_true", [[2, 3, 4], [-10], [0, -1]]) def test_check_pos_label_consistency_invalid_array_api( - array_namespace, device, dtype, y_true + array_namespace, device_name, dtype_name, y_true ): - xp = _array_api_for_tests(array_namespace, device) + xp, device = _array_api_for_tests(array_namespace, device_name) with config_context(array_api_dispatch=True): arr = xp.asarray(y_true, device=device) with pytest.raises(ValueError, match="y_true takes value in"): From d0f207cfe794de451c66b56fb5c7a85a3e7ca717 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 23 Mar 2026 05:02:36 -0400 Subject: [PATCH 297/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33606) Co-authored-by: Lock file bot <noreply@github.com> --- .../pylatest_free_threaded_linux-64_conda.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index 25a0dcd381517..f41d4fc00e08a 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -6,7 +6,10 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#325 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 @@ -16,19 +19,16 @@ https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 @@ -50,7 +50,7 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314hd4f4903_1.conda#f626ab4f8adec5ea04a13558822e92f9 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314hd4f4903_0.conda#ee2b2bb9e96a9cd64d68492842559adf https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.3-h92d6c8b_1.conda#817a41a5e7c547bda68fd981fb72b1ec https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 From f358dc7db28c830e67acbee56970ad3915b0d0f9 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 23 Mar 2026 05:03:05 -0400 Subject: [PATCH 298/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33607) Co-authored-by: Lock file bot <noreply@github.com> --- .../pylatest_pip_scipy_dev_linux-64_conda.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index ecebd17088beb..7983090053384 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -6,7 +6,10 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 @@ -15,17 +18,14 @@ https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f @@ -33,7 +33,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa # pip charset-normalizer @ https://files.pythonhosted.org/packages/76/7e/bc8911719f7084f72fd545f647601ea3532363927f807d296a8c88a62c0d/charset_normalizer-3.4.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=7bda6eebafd42133efdca535b04ccb338ab29467b3f7bf79569883676fc628db -# pip coverage @ https://files.pythonhosted.org/packages/06/90/2cdab0974b9b5bbc1623f7876b73603aecac11b8d95b85b5b86b32de5eab/coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129 +# pip coverage @ https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea From 09eba6c0ab16233106b607d341a9e47111ca0a43 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 23 Mar 2026 05:03:46 -0400 Subject: [PATCH 299/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33608) Co-authored-by: Lock file bot <noreply@github.com> --- ...a_forge_cuda_array-api_linux-64_conda.lock | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 9b2ad3c68b403..ccd322f4e6200 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_2.conda#253e70376a8ae74f9d99d44712b3e087 +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.26.0-ha770c72_0.conda#cb93c6e226a7bed5557601846555153d https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a66894dfd07c4510beb6b3f9672ccc0 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa @@ -23,6 +23,7 @@ https://conda.anaconda.org/conda-forge/noarch/cuda-nvvm-dev_linux-64-12.9.86-ha7 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/noarch/libnvptxcompiler-dev_linux-64-12.9.86-ha770c72_2.conda#a66a909acf08924aced622903832a937 +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_linux-64-12.9.79-h3f2d84a_0.conda#86e40eb67d83f1a58bdafdd44e5a77c6 @@ -30,6 +31,9 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2# https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libnvptxcompiler-dev-12.9.86-ha770c72_2.conda#3fd926c321c6dbf386aa14bd8b125bfb https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 +https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.2-h25fd6f3_2.conda#c2a01a08fc991620a74b32420e97868a +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 @@ -53,15 +57,16 @@ https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb9d3cd8_0.conda#db63358239cbe1ff86242406d440e44a https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f @@ -82,7 +87,7 @@ https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717 https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda#f7d7a4104082b39e3b3473fbd4a38229 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d -https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda#6f7b4302263347698fd24565fbf11310 https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 @@ -93,10 +98,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libnvjitlink-12.9.86-hecca717_2.conda#3461b0f2d5cbb7973d361f9e85241d98 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -111,29 +116,25 @@ https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7 https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.1-h1cbb8d7_1.conda#9d978822b57bafe72ebd3f8b527bba71 https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab -https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 +https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda#996583ea9c796e5b915f7d7580b51ea6 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 -https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-hc87160b_2.conda#3a7d90d34895728f0b69107602b6e189 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_1.conda#55a83761db33f82d92d7d7a4a61662e5 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.conda#af0df9bc982b5ed2c67e8f5062d1f8c1 https://conda.anaconda.org/conda-forge/linux-64/libcurand-dev-10.3.10.19-h676940d_1.conda#fc716aaff5af15b80ccbd28b3e67672c https://conda.anaconda.org/conda-forge/linux-64/libcusparse-12.5.10.65-hecca717_2.conda#890ebfaad48c887d3d82847ec9d6bc79 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da -https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 +https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-openmp_hd680484_4.conda#c0512e4f60d62ccccb4c3c8333b33608 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 @@ -148,13 +149,15 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.9-h841be55_2.conda#7e1ea1a67435a32e04305fda877acd1e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.6.0-h841be55_0.conda#d45136de07e991786e04716c3f70b036 https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.11-hf621c6d_0.conda#caf217f88155d551b4a586f2da37941a https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvcc-impl-12.9.86-h85509e4_2.conda#67458d2685e7503933efa550f3ee40f3 https://conda.anaconda.org/conda-forge/linux-64/cuda-profiler-api-12.9.79-h7938cbb_1.conda#90d09865fb37d11d510444e34ebe6a09 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcublas-dev-12.9.1.4-h676940d_1.conda#f90f4ff087ac29005c6989ea0fb2735a @@ -164,11 +167,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#4 https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2.conda#bb6e31a0daa64ede76fe8d3fff01c06f https://conda.anaconda.org/conda-forge/linux-64/libcusparse-dev-12.5.10.65-hecca717_2.conda#db94469fbd554c107acc3afd0af5d8ec -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-26.02.00-cuda12_260204_c212ab9b.conda#702a98df50c3b8be134516647a217fde -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-259.5-h6569c3e_0.conda#208dd14d53c3968afd1ebb6d5647b14e -https://conda.anaconda.org/conda-forge/linux-64/libudev1-259.5-h6569c3e_0.conda#166de8bb898bc883626e2382e5dd8621 +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-260-h6569c3e_0.conda#1db3f7f63f3ce0d0f3c8ea4fe130d5d0 +https://conda.anaconda.org/conda-forge/linux-64/libudev1-260-h6569c3e_0.conda#56bcdcefe1c46ba9d0269338c33bd575 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-openmp_hd77311e_4.conda#525e2455ed342f2aef93c59ac5db2e28 @@ -184,22 +186,21 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_ https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h536185d_1.conda#bc645a385e91cd3d9235174fcbd17e25 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.0-hac84f0a_1.conda#9cf66b4abc53e47857afbee27364102b https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.4.2-pyhc364b38_0.conda#0b582191a96267c4bd173f35deba3f7a +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.4.3-pyhc364b38_0.conda#3cfe70d38d34a49cfa358435d439375f https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py313hc8edb43_0.conda#b81883b9dbf5069821c2fb09a8ba1407 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-dev-11.7.5.82-h676940d_2.conda#0fe12e558abf507458bcec839e29778d https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.0-h1d1128b_1.conda#66055700c90b50c0405a4e515bb4fe3c +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 @@ -211,7 +212,7 @@ https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.590.48-pyhd8ed1ab_0.conda#fda409cefdbd417f9ca4e072c39add77 +https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.595.45-pyhd8ed1ab_0.conda#bbb874843e7cc9cfe379d59499155e45 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py313h80991f8_0.conda#2d5ee4938cdde91a8967f3eea686c546 @@ -239,20 +240,19 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h37c9286_4.conda#e9c44a6e46de739827d2eae25ed2ee32 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py313h3dea7bd_0.conda#77e1fc7133e03ccd62070f2405c82ea9 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py313h3dea7bd_0.conda#acbda45380f5097ade59014704eb0ba0 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py313h3dea7bd_0.conda#e479cfdec38fb69dc81ce8806b5c75f6 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py313h86d8783_1.conda#047e3ea395eab013f918b338fecc19a0 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.0-h6083320_0.conda#71c2c966e17a65b08b995f571310fb9f https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d https://conda.anaconda.org/conda-forge/linux-64/libcufile-1.14.1.1-hbc026e6_1.conda#cab1818eada3952ed09c8dcbb7c26af7 -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-h9d11ab5_1.conda#cd398eb8374fb626a710b7a35b7ffa98 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-h9692893_2.conda#c3de1cc30bc11edbc98aed352381449d +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 @@ -266,14 +266,13 @@ https://conda.anaconda.org/conda-forge/linux-64/ucx-1.20.0-hbe80e26_1.conda#ffda https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h753c7c1_1.conda#f59686fd4b442be1dc4a59c35a6c7449 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-haf8ea0b_2.conda#6f531ae41a8ac7c69c85130d16585d61 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.6-py313h929d4db_0.conda#602176b8957b10172dfea675a332d0ac https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py313h28b6081_0.conda#fe933a91c19fa88788b4204b6ba67ba2 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.1.1-h6083320_0.conda#56d73078fe51aee26b7934cb1378d464 -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_1.conda#384a1730ea66a72692e377cb45996d61 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_hb019b6b_203.conda#5e373fc37a76270b4454c02cb126ab34 https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 @@ -281,38 +280,39 @@ https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.con https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py313h7037e92_0.conda#21f1c403983c8a4e067ba6eec6b878ec https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py313hbfd7664_0.conda#1c8807728f0333228766dee685394e16 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-pl5321h16c4a6b_6.conda#3a00bff44c15ee37bfd5eb435e1b2a51 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-h5f21323_2.conda#47b0ddc79fc15341d7110a1078868326 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.6.0-cuda12_py313hacc9b55_0.conda#1986c17fb0b8184289ea7d6fc8ba4b34 https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.conda#8d3dbe5292af711edd6df92c68e55a89 https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py313h7fc6698_0.conda#41368ea5c4c7c607ac98ecab56833535 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hffdcd12_0.conda#b659a59ec7b67623dcaec02388e06fb9 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313hcd51b16_1.conda#745f9c0ffaf06cea2e68e12259ace5b5 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_hb8e8477_203.conda#6cfb64f7fc401f2c7c789214237aea24 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-h17e89b9_5.conda#6c4f73c9a7e9b51f3a8e321c3e867bb6 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-hc1a2089_5_cpu.conda#ece55298311b727b6810156aad9ccad1 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 -https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313hcd51b16_0.conda#2ae30c246bf80b1d5e57480d9069dab4 +https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda#d5a4e013a30dd8dfde9ab39f45aaf9c1 https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_203.conda#969fd0ea1b469425630712ba3513deff https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_5_cpu.conda#16e8c9aa6a76282ddfc0fc5e7d5e7ae3 -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_5_cpu.conda#50b3355129c86b3fe13a58e2fc4e959a -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_9_cpu.conda#b3ba3597c481a636fc161185819cf6b1 +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_9_cpu.conda#2dccf1b6cf9dba8857050740dbc0497e https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_5_cpu.conda#9010a95bfa086bd3ba8697ed64b99264 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py313h98bfbea_0_cpu.conda#d2b771a9050c52941a61a72f2d161c64 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_5_cpu.conda#368ee0f69d66d97fa9726e0a2d43c068 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_9_cpu.conda#9c5282b7aaf2261d3dbe5a61d24d5337 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_5_cpu.conda#823d932334271476a5195ee86696e647 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_9_cpu.conda#d5338f154126253750e8ccc539386b92 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.02.00-cuda12_260204_a2f5a8b7.conda#361cae27e77618c6ba9f943807471f9f https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.02.00-cuda12_py313_260204_c212ab9b.conda#14933b753ec82f9d5a61d7cb4b5e2e71 https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.02.00-cuda12_py313_260204_a2f5a8b7.conda#c46807878ad576379e7be3acc187d13a From f3cdf080c901a0cec84f652e1aeb65d587c9631b Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 23 Mar 2026 05:04:28 -0400 Subject: [PATCH 300/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33609) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/circle/doc_linux-64_conda.lock | 78 ++++++++-------- .../doc_min_dependencies_linux-64_conda.lock | 89 +++++++++---------- build_tools/github/debian_32bit_lock.txt | 2 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 74 +++++++-------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 10 +-- .../pylatest_conda_forge_osx-arm64_conda.lock | 12 +-- ...st_pip_openblas_pandas_linux-64_conda.lock | 14 +-- ...n_conda_forge_arm_linux-aarch64_conda.lock | 36 ++++---- ...nblas_min_dependencies_linux-64_conda.lock | 61 +++++++------ ...e_openblas_ubuntu_2204_linux-64_conda.lock | 24 ++--- ...min_conda_forge_openblas_win-64_conda.lock | 14 +-- 11 files changed, 206 insertions(+), 208 deletions(-) diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 4a933c56a548d..0604a6981221e 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -15,13 +15,17 @@ https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb +https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_102.conda#8165352fdce2d2025bf884dc0ee85700 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed @@ -36,25 +40,28 @@ https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda#7af961ef4aa2c1136e11dd43ded245ab https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.8.1-h1fbca29_0.conda#d83958768626b3c8471ce032e28afcd3 +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda#a77f85f77be52ff59391544bfe73390a +https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_102.conda#212fe5f1067445544c99dc1c847d032c +https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_102.conda#2a307a17309d358c9b42afdd3199ddcc https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.3-hecca717_0.conda#937ca49a245fcf2b88d51b6b52959426 https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717_0.conda#dbe3ec0f120af456b3477743ffd99b74 https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d -https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.5-h088129d_0.conda#86f7414544ae606282352fa1e116b41f @@ -62,9 +69,9 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -76,20 +83,18 @@ https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.1-hecca717_0.conda#2a2170a3e5c9a354d09e4be718c43235 -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab -https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 +https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda#996583ea9c796e5b915f7d7580b51ea6 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_5.conda#6a0eb48e58684cca4d7acc8b7a0fd3c7 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.1-hc31b594_0.conda#68ceffc6cadae61846a207cae60de094 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 @@ -103,15 +108,19 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_101.conda#83aa53cb3f5fc849851a84d777a60551 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.0-hcfa2d63_0.conda#e226d3dbe1e2482fd8e15cb924fd1e7c +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c @@ -125,15 +134,14 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0. https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda#755b096086851e1193f3b10347415d7c https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a -https://conda.anaconda.org/conda-forge/noarch/attrs-25.4.0-pyhcf101f3_1.conda#537296d57ea995666c68c821b00e360b +https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda#c6b0543676ecb1fb2d7643941fe375f2 https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a -https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_101.conda#9902aeb08445c03fb31e01beeb173988 -https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_101.conda#dec96579f9a7035a59492bf6ee613b53 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2#576d629e47797577ab0f1b351297ef4a +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda#beb628209b2b354b98203066f90b3287 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda#49ee13eb9b8f44d63879c69b8a40a74b https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.15-py311hd8ed1ab_0.conda#bf0d09d5c2b61aaf7b11c551c8545cfa @@ -143,13 +151,13 @@ https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar. https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 https://conda.anaconda.org/conda-forge/noarch/doit-0.37.0-pyhcf101f3_0.conda#37b3d4c558f2bb2b5378c43f4d6f1fb5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 -https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 +https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/noarch/json5-0.13.0-pyhd8ed1ab_0.conda#8d5f66ebf832c4ce28d5c37a0e76605c https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda#cd2214824e36b0180141d422aba01938 @@ -216,17 +224,16 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0 https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda#7c5ebdc286220e8021bf55e6384acd67 +https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.0-h6083320_0.conda#71c2c966e17a65b08b995f571310fb9f +https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 @@ -241,7 +248,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b11e360fc4de2b0035fc8aaa74f17fd6 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py311h2e04523_1.conda#a8105076864776eceae69d64d30e24d7 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py311h2e04523_0.conda#cfc8f864dea571677095ebae8e6f0c07 https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda#3e9427ee186846052e81fadde8ebe96a https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 @@ -263,11 +270,9 @@ https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda#f11a319b9700b203aa14c295858782b6 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311h724c32c_4.conda#d04e508f5a03162c8bab4586a65d00bf +https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 +https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.1.1-h6083320_0.conda#56d73078fe51aee26b7934cb1378d464 https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 @@ -281,38 +286,33 @@ https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.con https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-pl5321h16c4a6b_6.conda#3a00bff44c15ee37bfd5eb435e1b2a51 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 -https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 +https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.1-pyhcf101f3_0.conda#4552b601cf622dea2bb5075baccc2c5b https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py311hf27b23e_1.conda#69d2caeedece7a008151c6917525403d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-h17e89b9_5.conda#6c4f73c9a7e9b51f3a8e321c3e867bb6 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.3.3-pyhd8ed1ab_0.conda#cecacab21bc8f4ed17fac11bc8b08cf0 https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 -https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 -https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda#8368d58342d0825f0843dc6acdd0c483 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py311hf27b23e_0.conda#d47160bd36bce78bc139d5e992ff81ce https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py311h2a99c40_0.conda#557f5d7ca735d89d706742bc19cd7e26 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 -https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyhe01879c_0.conda#31e11c30bbee1682a55627f953c6725a https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.1-pyhbbac1ac_0.conda#d8f030e3730713c93a358fdb46f08281 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.0-pyhcf101f3_0.conda#b14079a39ae60ac7ad2ec3d9eab075ca diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index aac2f024ad9af..fe4c561a7d1d7 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -16,14 +16,18 @@ https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb +https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_102.conda#8165352fdce2d2025bf884dc0ee85700 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda#f9f81ea472684d75b9dd8d0b328cf655 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 @@ -42,24 +46,27 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.8.1-h1fbca29_0.conda#d83958768626b3c8471ce032e28afcd3 +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-hb03c661_1.conda#9bb149f49de3f322fca007283eaa2725 +https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_102.conda#212fe5f1067445544c99dc1c847d032c +https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_102.conda#2a307a17309d358c9b42afdd3199ddcc https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.3-hecca717_0.conda#937ca49a245fcf2b88d51b6b52959426 https://conda.anaconda.org/conda-forge/linux-64/dav1d-1.2.1-hd590300_0.conda#418c6ca5929a611cbd69204907a83995 https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda#3bf7b9fd5a7136126e0234db4b87c8b6 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d -https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda#5aeabe88534ea4169d4c49998f293d6c https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 @@ -70,9 +77,9 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c @@ -87,20 +94,18 @@ https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/svt-av1-4.0.1-hecca717_0.conda#2a2170a3e5c9a354d09e4be718c43235 -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zfp-1.0.1-h909a3a2_5.conda#6a0eb48e58684cca4d7acc8b7a0fd3c7 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#346722a0be40f6edc53f12640d301338 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.1-hc31b594_0.conda#68ceffc6cadae61846a207cae60de094 -https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 +https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 @@ -114,17 +119,21 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_101.conda#83aa53cb3f5fc849851a84d777a60551 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 -https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c +https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda#b52b769cd13f7adaa6ccdc68ef801709 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.0-hcfa2d63_0.conda#e226d3dbe1e2482fd8e15cb924fd1e7c -https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda#1d4c18d75c51ed9d00092a891a547a7d +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda#8ee3cb7f64be0e8c4787f3a4dbe024e6 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -138,36 +147,34 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_ https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda#def531a3ac77b7fb8c21d17bb5d0badb https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a -https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_101.conda#9902aeb08445c03fb31e01beeb173988 -https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_101.conda#dec96579f9a7035a59492bf6ee613b53 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda#beb628209b2b354b98203066f90b3287 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda#49ee13eb9b8f44d63879c69b8a40a74b https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 -https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 +https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 @@ -197,23 +204,22 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c +https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.7.0-pyhe01879c_1.conda#63ccfdc3a3ce25b027b8767eb722fca8 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.0-h6083320_0.conda#71c2c966e17a65b08b995f571310fb9f +https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda#9f6a8664f1fe752f79473eeb9bf33a60 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 @@ -223,38 +229,32 @@ https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 +https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 +https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.1.1-h6083320_0.conda#56d73078fe51aee26b7934cb1378d464 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.5-pyhd8ed1ab_0.conda#4c8327180586e7b1cd8b6815fc8827f1 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 +https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 -https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 +https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e +https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad -https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 -https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 -https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f -https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed -https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e +https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h0c412b5_8.conda#80e27e7982af989ebc2e0f0d57c75ea7 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 -https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-hc240232_7.conda#fa3bbe293d907990f3ca5b8b9d4b10f0 +https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 @@ -262,7 +262,6 @@ https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda# https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.conda#643f8cb35133eb1be4919fb953f0a25f https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 -https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.8.0-py311h9f3472d_0.conda#17334e5c12abdf2db6b25bd4187cd3e4 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c diff --git a/build_tools/github/debian_32bit_lock.txt b/build_tools/github/debian_32bit_lock.txt index 01f4ab19cfc44..020ed7fdeffc6 100644 --- a/build_tools/github/debian_32bit_lock.txt +++ b/build_tools/github/debian_32bit_lock.txt @@ -4,7 +4,7 @@ # # pip-compile --output-file=build_tools/github/debian_32bit_lock.txt build_tools/github/debian_32bit_requirements.txt # -coverage[toml]==7.13.4 +coverage[toml]==7.13.5 # via pytest-cov cython==3.2.4 # via -r build_tools/github/debian_32bit_requirements.txt diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock index 57c50f5e345ee..324d87c4de830 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -6,7 +6,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.21.0-ha770c72_2.conda#253e70376a8ae74f9d99d44712b3e087 +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.26.0-ha770c72_0.conda#cb93c6e226a7bed5557601846555153d https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_463.conda#291727757c8a8613312aaa4b52e82ad8 https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa @@ -15,11 +15,15 @@ https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad65 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 +https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.2-h25fd6f3_2.conda#c2a01a08fc991620a74b32420e97868a +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 @@ -38,15 +42,16 @@ https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f @@ -59,7 +64,7 @@ https://conda.anaconda.org/conda-forge/linux-64/double-conversion-3.4.0-hecca717 https://conda.anaconda.org/conda-forge/linux-64/fmt-12.1.0-hff5e90c_0.conda#f7d7a4104082b39e3b3473fbd4a38229 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d -https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20260107.1-cxx17_h7b12aa8_0.conda#6f7b4302263347698fd24565fbf11310 https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.conda#366b40a69f0ad6072561c1d09301c886 @@ -68,9 +73,9 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -83,23 +88,19 @@ https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7 https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.1-h1cbb8d7_1.conda#9d978822b57bafe72ebd3f8b527bba71 https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab -https://conda.anaconda.org/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda#035da2e4f5770f036ff704fa17aace24 +https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda#996583ea9c796e5b915f7d7580b51ea6 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 -https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-hc87160b_2.conda#3a7d90d34895728f0b69107602b6e189 https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da -https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 +https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 @@ -112,15 +113,16 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.5.9-h841be55_2.conda#7e1ea1a67435a32e04305fda877acd1e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.6.0-h841be55_0.conda#d45136de07e991786e04716c3f70b036 https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.11-hf621c6d_0.conda#caf217f88155d551b4a586f2da37941a https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa @@ -139,16 +141,15 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.0-hac84f0a_1.con https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda#beb628209b2b354b98203066f90b3287 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda#49ee13eb9b8f44d63879c69b8a40a74b https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda#3bb89e4f795e5414addaa531d6b1500a https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.2-py314h42812f9_0.conda#511748f9debe034ff88eef99bc215fd3 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e @@ -157,7 +158,7 @@ https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.0-h1d1128b_1.conda#66055700c90b50c0405a4e515bb4fe3c +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 @@ -198,18 +199,17 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h37c9286_4.conda#e9c44a6e46de739827d2eae25ed2ee32 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py314h67df5f8_0.conda#6c7efc167cee337d9c41200506d022b8 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.0-h6083320_0.conda#71c2c966e17a65b08b995f571310fb9f https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.39.0-h9d11ab5_1.conda#cd398eb8374fb626a710b7a35b7ffa98 -https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.21.0-h9692893_2.conda#c3de1cc30bc11edbc98aed352381449d +https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff @@ -222,52 +222,52 @@ https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h753c7c1_1.conda#f59686fd4b442be1dc4a59c35a6c7449 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-haf8ea0b_2.conda#6f531ae41a8ac7c69c85130d16585d61 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.1.1-h6083320_0.conda#56d73078fe51aee26b7934cb1378d464 -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.39.0-hdbdcf42_1.conda#384a1730ea66a72692e377cb45996d61 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.58.0-pyhcf101f3_0.conda#3b886c49cf44aa133d0eb07e4d0cac89 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-pl5321h16c4a6b_6.conda#3a00bff44c15ee37bfd5eb435e1b2a51 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-h5f21323_2.conda#47b0ddc79fc15341d7110a1078868326 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.38.1-py310hffdcd12_0.conda#b659a59ec7b67623dcaec02388e06fb9 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py314h3987850_1.conda#572aaa4811844ba16c265647f06e1106 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-h17e89b9_5.conda#6c4f73c9a7e9b51f3a8e321c3e867bb6 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-hc1a2089_5_cpu.conda#ece55298311b727b6810156aad9ccad1 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 -https://conda.anaconda.org/conda-forge/noarch/polars-1.38.1-pyh6a1acc5_0.conda#b20de145c676cbae6138ac478cdb137b -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py314h3987850_0.conda#071ad1489776fd8bdf85d811c37c9b1d +https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda#d5a4e013a30dd8dfde9ab39f45aaf9c1 https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_5_cpu.conda#16e8c9aa6a76282ddfc0fc5e7d5e7ae3 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_9_cpu.conda#b3ba3597c481a636fc161185819cf6b1 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_5_cpu.conda#50b3355129c86b3fe13a58e2fc4e959a +https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_9_cpu.conda#2dccf1b6cf9dba8857050740dbc0497e https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h7058990_103.conda#2df90510834746b1f52c5299bc99a81f -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py314h2b28147_1.conda#4ea6b620fdf24a1a0bc4f1c7134dfafb +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_5_cpu.conda#9010a95bfa086bd3ba8697ed64b99264 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py314hb4ffadd_0.conda#23fc526360815090f6bfcd7c6c8e4954 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py314h969be7f_0_cpu.conda#97c21b0d5952f4e0f80bb790df1a5c88 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h6018c46_103.conda#a3c40f317db763f9631d078d0fb2759e https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_5_cpu.conda#368ee0f69d66d97fa9726e0a2d43c068 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_9_cpu.conda#9c5282b7aaf2261d3dbe5a61d24d5337 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_103.conda#54ad123774a53ce33aa7e99b6e53b4a6 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_5_cpu.conda#823d932334271476a5195ee86696e647 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_9_cpu.conda#d5338f154126253750e8ccc539386b92 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py314hdafbbf9_0.conda#860f29e99f5b5f15b0d6a21166588bab diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 80c3b36385ffb..dac2348906f9c 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda#4173ac3b19ec0a4f400b4f782910368b https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d -https://conda.anaconda.org/conda-forge/osx-64/icu-78.2-h14c5de8_0.conda#30334add4de016489b731c6662511684 +https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda#627eca44e62e2b665eeec57a984a7f00 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.1-h19cb2f5_0.conda#799141ac68a99265f04bcee196b2df51 https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 @@ -18,7 +18,7 @@ https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.2-h8616949_0.con https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda#688a0c3d57fa118b9c97bf7e471ab46c https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda#ec88ba8a245855935b871a7324373105 https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda#7bb6608cf1f83578587297a158a6630b -https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda#003a54a4e32b02f7355b50a837e699da +https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda#30439ff30578e504ee5e0b390afc8c65 https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.0-h0d3cbff_0.conda#3921780bab286f2439ba483c22b90345 https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda#ced34dd9929f491ca6dab6a2927aff25 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 @@ -42,7 +42,7 @@ https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda#6e6efb7 https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.3-h8bce59a_1.conda#b3ecb6480fd46194e3f7dd0ff4445dff https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf -https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.1-h894318c_0.conda#914b70b4746a94f78a34262416ba69d0 +https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.2-h894318c_0.conda#e77ab67215939f46bb6ec8226a242e6a https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.2-h58fbd8d_0.conda#2e6760656fde7df787fdef045d0fc65d https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda#9a5cb96e43f5c2296690186e15b3296f https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 @@ -75,7 +75,7 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.4-py314h3d180e3_0.conda#e9dfcd5b883e35aebe6dbe2c197dddbe https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.1-py314h4f144dc_0.conda#773e3141f292d9698e706da094ada8c1 -https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.4-py314h10d0514_0.conda#f27072a17bcb5061cd46de7d01f69028 +https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.5-py314h77fa6c7_0.conda#c5d3ea7d5f490c69a6af7c056624fca4 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.2-h694c41f_0.conda#0959d7034baef0a8274387fde505c347 @@ -95,7 +95,7 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.co https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-20_osx64_mkl.conda#51089a4865eb4aec2bc5c7468bd07f9f https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.9.0-20_osx64_mkl.conda#58f08e12ad487fac4a08f90ff0b87aec https://conda.anaconda.org/conda-forge/osx-64/liblapacke-3.9.0-20_osx64_mkl.conda#124ae8e384268a8da66f1d64114a1eda -https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.2-py314hfc4c462_1.conda#891bda68803fbbcf08d37f94981b650a +https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.3-py314h7b24d9b_0.conda#3d8057ab97e4c8fd1f781356e7be9b40 https://conda.anaconda.org/conda-forge/osx-64/blas-devel-3.9.0-20_osx64_mkl.conda#cc3260179093918b801e373c6e888e02 https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h22a2ed9_4.conda#511f02f632e1fb0555da3cb4261851d9 https://conda.anaconda.org/conda-forge/osx-64/pandas-3.0.1-py314h99bb933_0.conda#8efb0ea54eaf4aff69a0a16a5e5efb4c diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock index 05187feeac1a5..4e4ca8991769e 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock @@ -10,7 +10,7 @@ https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98d https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda#620b85a3f45526a8bc4d23fd78fc22f0 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d -https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.2-hef89b57_0.conda#114e6bfe7c5ad2525eb3597acdbf2300 +https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda#f1182c91c0de31a7abd40cedf6a5ebef https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.1-h55c6f16_0.conda#7a290d944bc0c481a55baf33fa289deb https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 @@ -23,7 +23,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda# https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda#57c4be259f5e0b99a5983799a228ae55 https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda#c0d87c3c8e075daf1daf6c31b53e8083 https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda#e5e7d467f80da752be17796b87fe6385 -https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda#369964e85dc26bfe78f41399b366c435 +https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda#bc5a5721b6439f2f62a84f2548136082 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.0-hc7d1edf_0.conda#ff0820b5588b20be3b858552ecf8ffae https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda#068d497125e4bf8a66bf707254fff5ae https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda#415816daf82e0b23a736a069a75e9da7 @@ -51,11 +51,11 @@ https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda#f https://conda.anaconda.org/conda-forge/osx-arm64/sleef-3.9.0-hb028509_0.conda#68f833178f171cfffdd18854c0e9b7f9 https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_0.conda#347261d575a245cb6111fb2cb5a79fc7 https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda#a9d86bc62f39b94c4661716624eb21b0 -https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda#e3170d898ca6cb48f1bb567afb92f775 +https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.2-h8088a28_2.conda#f1c0bce276210bed45a04949cfe8dc20 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.3-hed4e4f5_1.conda#d99c2a23a31b0172e90f456f580b695e https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c -https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.1-h414bf82_0.conda#69983a492267b903ddc6a4eac4dff5aa +https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.2-h414bf82_0.conda#baeca21071729b617b20b019f85beedf https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.2-hdfa99f5_0.conda#e726e134a392ae5d7bafa6cc4a3d5725 https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda#92df6107310b1fff92c4cc84f0de247b https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.33.5-h4a5acfd_0.conda#b839e3295b66434f20969c8b940f056a @@ -100,7 +100,7 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py314h0612a62_0.conda#83e1a2d7b0c1352870bbe9d9406135cf https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py314h6c2aa35_0.conda#4fffb3ba871bb05f34ffb705534dfef5 -https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.4-py314h6e9b3f0_0.conda#96c7bf4f2b5010d29604a62e91e634bb +https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.5-py314h6e9b3f0_0.conda#cdbafe4a3e605024e7372c9580f9d734 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.2-hce30654_0.conda#ca730d8e7d1de1f71013edfef0e08f13 @@ -133,7 +133,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01a https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_hd01ab73_4.conda#0d059c5db9d880ff37b2da53bf06509e https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-5_hbdd07e9_accelerate.conda#29c7d09cbe6d342ced64b0447e1f3792 https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.10.0-cpu_generic_hf7cc835_3.conda#98f89ad42eaba858443d31336677aed2 -https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.2-py314hae46ccb_1.conda#0f0ddf0575b98d91cda9e3ca9eaeb9a2 +https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.3-py314h1569ea8_0.conda#0fab9cf4fc5163131387f36742b50c79 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-5_h55bc449_accelerate.conda#6696b095e91860523bcc97303e11d30d https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py314hf8a3a22_4.conda#cddc851000ce131d757678c2f329eaad diff --git a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock index 48ebb67c1667c..96abccca3836d 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -6,7 +6,10 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#9430 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 @@ -15,17 +18,14 @@ https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f @@ -33,7 +33,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa # pip charset-normalizer @ https://files.pythonhosted.org/packages/2b/58/a199d245894b12db0b957d627516c78e055adc3a0d978bc7f65ddaf7c399/charset_normalizer-3.4.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=530e8cebeea0d76bdcf93357aa5e41336f48c3dc709ac52da2bb167c5b8271d9 -# pip coverage @ https://files.pythonhosted.org/packages/e4/dc/b2442d10020c2f52617828862d8b6ee337859cd8f3a1f13d607dddda9cf7/coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b +# pip coverage @ https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3 # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 # pip cython @ https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 78ed255574448..e160be9560933 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -8,6 +8,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77 https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.conda#9e115653741810778c9a915a2f8439e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda#4faa39bf919939602e594253bd673958 +https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda#502006882cf5461adced436e410046d1 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda#468fd3bb9e1f671d36c2cbc677e56f1d @@ -15,7 +16,9 @@ https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda#cf105bce884e4ef8c8ccdca9fe6695e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 +https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab +https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda#a21644fc4a83da26452a718dc9468d5f https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda#552567ea2b61e3a3035759b2fdb3f9a6 https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.3-he30d5cf_0.conda#4a98cbc4ade694520227402ff8880630 https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda#840d8fc0d7b3209be93080bc20e07f2d @@ -31,29 +34,30 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5c https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda#96944e3c92386a12755b94619bae0b35 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 +https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda#be4088903b94ea297975689b3c3aeb27 https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda#cf2861212053d05f27ec49c3784ff8bb https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af -https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.1-h86ecc28_2.conda#08aad7cbe9f5a6b460d0976076b6ae64 https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda#182afabe009dc78d8b73100255ee6868 https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda#25f5885f11e8b1f075bccf4a2da91c60 https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda#bb5a90c93e3bac3d5690acf76b4a6386 +https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda#7fc6affb9b01e567d2ef1d05b84aa6ed https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libice-1.1.2-h86ecc28_0.conda#c8d8ec3e00cd0fd8a231789b91a7c5b7 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda#1c246e1105000c3660558459e2fd6d43 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda#bff06dcde4a707339d66d45d96ceb2e2 https://conda.anaconda.org/conda-forge/linux-aarch64/xxhash-0.8.3-hd794028_0.conda#f2accdfbd632e2be9a63bed23cb08045 https://conda.anaconda.org/conda-forge/linux-aarch64/double-conversion-3.4.0-hfae3067_0.conda#9fd794eaf983eabf975ead524540b4be https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda#4aa540e9541cc9d6581ab23ff2043f13 -https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.2-hcab7f73_0.conda#998ee7d53e32f7ab57fc35707285527e +https://conda.anaconda.org/conda-forge/linux-aarch64/icu-78.3-hcab7f73_0.conda#546da38c2fa9efacf203e2ad3f987c59 https://conda.anaconda.org/conda-forge/linux-aarch64/lerc-4.1.0-h52b7260_0.conda#d13423b06447113a90b5b1366d4da171 https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf_1.conda#47e5b71b77bb8b47b4ecf9659492977f https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda#6553a5d017fe14859ea8a4e6ea5def8f https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda#2079727b538f6dd16f3fa579d4c3c53f https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda#fb640d776fc92b682a14e001980825b1 +https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.2-hdae7a39_0.conda#69d1cdfdabb66464cbde17890e8be3b9 https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda#41f261f5e4e2e8cbd236c2f1f15dae1b https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.3.0-h5ad3122_1.conda#c11818b31f7c054ce220041b2459aacb https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda#be4088903b94ea297975689b3c3aeb27 https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_18.conda#699d294376fe18d80b7ce7876c3a875d https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda#b4df5d7d4b63579d081fd3a4cf99740e @@ -61,16 +65,13 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.con https://conda.anaconda.org/conda-forge/linux-aarch64/pcre2-10.47-hf841c20_0.conda#1a30c42e32ca0ea216bd0bfe6f842f0b https://conda.anaconda.org/conda-forge/linux-aarch64/pixman-0.46.4-h7ac5ae9_1.conda#1587081d537bd4ae77d1c0635d465ba5 https://conda.anaconda.org/conda-forge/linux-aarch64/readline-8.3-hb682ff5_0.conda#3d49cad61f829f4f0e0611547a9cda12 -https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda#7fc6affb9b01e567d2ef1d05b84aa6ed -https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.24.0-h4f8a99f_1.conda#f6966cb1f000c230359ae98c29e37d87 +https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.25.0-h4f8a99f_0.conda#0a7a9548726f98d5869fd4c43e110f0f https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda#2d1409c50882819cb1af2de82e2b7208 https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda#f731af71c723065d91b4c01bb822641b -https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 -https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.1-h185addb_0.conda#dd42f9e00baaecee065571c4b522373b +https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.2-h185addb_0.conda#728e129e280ddc3b4885fd3bc64a9f58 https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda#d9ca108bd680ea86a963104b6b3e95ca -https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_101.conda#35b2ae7fadf364b8e5fb8185aaeb80e5 -https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.2-hdae7a39_0.conda#69d1cdfdabb66464cbde17890e8be3b9 +https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.2-h8af1aa0_0.conda#93bce8dee6a0a4906331db294ec250fe https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_1.conda#4ac4372fc4d7f20630a91314cdac8afd https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda#77891484f18eca74b8ad83694da9815e @@ -85,10 +86,11 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.13-h63a1b12 https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-hd651790_1.conda#5c933384d588a06cd8dac78ca2864aab https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.28-h6598af7_1.conda#f4fbf4001970e3e58984281a12c99969 https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda#a4b6b82427d15f0489cef0df2d82f926 +https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda#0fed1ff55f4938a65907f3ecf62609db +https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.2-h8af1aa0_0.conda#9cb47d7bbb36646c44d7cf1cb8047887 https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda#bb960f01525b5e001608afef9d47b79c https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda#5afcea37a46f76ec1322943b3c4dfdc0 https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h4f2b762_6.conda#67828c963b17db7dc989fe5d509ef04a -https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.2-h8af1aa0_0.conda#93bce8dee6a0a4906331db294ec250fe https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda#19de96909ee1198e2853acd8aba89f6c https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.30-pthreads_h3a8cbd8_4.conda#e3f245ed352bd66d181b73a78d886038 @@ -99,12 +101,11 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xkeyboard-config-2.47-he30d https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.7-he30d5cf_0.conda#fb42b683034619915863d68dd9df03a3 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5cf_0.conda#e8b4056544341daf1d415eaeae7a040c https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda#ae2c2dd0e2d38d249887727db2af960e +https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.4-py311hdc11669_0.conda#931a90956062cc7219c6bce6c6ccfe7f https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda#0fed1ff55f4938a65907f3ecf62609db -https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.2-h8af1aa0_0.conda#9cb47d7bbb36646c44d7cf1cb8047887 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.5.0-py311h229e7f7_0.conda#aeade47300d466d9d6ba01daaca31a86 https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda#0b2f1143ae2d0aa4c991959d0daaf256 @@ -136,32 +137,31 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdamage-1.1.6-h86ec https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda#eeee3bdb31c6acde2b81ad1b8c287087 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda#1f64c613f0b8d67e9fb0e165d898fb6b https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.7-he30d5cf_0.conda#b15ca02584678f38df6e114c32f93959 -https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad -https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.4-py311h2dad8b0_0.conda#6fcc144f2f5c3537297288e61d09e8f2 +https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.5-py311h2dad8b0_0.conda#d3bcad889948820993ded0b13c2ae906 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.62.0-py311h164a683_0.conda#d3ef6350930100e30aaf0ecdf4e4dd3a +https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-13.2.0-h1134a53_0.conda#68508785d05856e4a053bf3d152fba95 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp22.1-22.1.0-default_he95a3c9_0.conda#1519a50e2f4caca01098a33d39f45f5c https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.0-default_h94a09a5_0.conda#4e1023aa62d0919a4014954d57bcb786 https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-5_hb558247_openblas.conda#8046d5ae90150f00c8b40455d9b2e180 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.3-h7d4fc67_0.conda#7eb18b198b1d35da9352062c69c4ee64 https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.341.0-h8b8848b_0.conda#06bb91a87fb97ea09398d2e121e00c39 -https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.2-py311h669026d_1.conda#6b411688a868a37d95abfb99ebc8b88e +https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py311h669026d_0.conda#23c6d37dec83159283cfeee4fceebf84 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-5_h9678261_openblas.conda#33a0e650392a79b56ae0bfa3db02ddbf https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311h04741b4_4.conda#1eeea54b0c520a475db39f8c711de661 -https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-13.1.1-h1134a53_0.conda#46a7a399537501c4501be18a9f871976 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.10.2-pl5321h598db47_6.conda#a2be7073b12891aab9fa91ca005c5a6b https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.1-py311h399493a_0.conda#be28b3d39c6942f89652b505e85ae3d6 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.305-openblas.conda#2efe635198609d0d2a122c6a0923b8f8 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 +https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.10.2-py311hb02cd75_1.conda#3db17f3d74ea130f9c0058f0567d5f44 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.10.2-h4f79d1e_5.conda#c5a6c2e22d9e1a1ef8870a5997fe2eda -https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.10.2-py311hb02cd75_0.conda#b9c3166811022d7f8f984816b644f7d4 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.8-py311hfecb2dc_0.conda#3920b856b59a909812f1913b96adaad8 diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index f5dcc72ab6889..9058684192285 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -11,11 +11,15 @@ https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad65 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 +https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.2-h25fd6f3_2.conda#c2a01a08fc991620a74b32420e97868a +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 @@ -37,14 +41,15 @@ https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb03c661_3.conda# https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f @@ -54,7 +59,7 @@ https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-hb03c661_1.conda#9bb1 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.8.23-hd590300_0.conda#cc4f06f7eedb1523f3b83fd0fb3942ff https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d -https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.0.9-h166bdaf_9.conda#61641e239f96eae2b8492dc7e755828c @@ -63,9 +68,9 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c @@ -78,28 +83,24 @@ https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/s2n-1.3.46-h06160fa_0.conda#413d96a0b655c8f8aacc36473a2dbb04 -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 -https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.1-hb9d3cd8_2.conda#c9f075ab2f33b3bbee9e62d4ad0a6cd8 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda#580a52a05f5be28ce00764149017c6d4 https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1.conda#f883d61afbc95c50f7b3f62546da4235 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 -https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.3-h659f571_0.conda#3f43953b7d3fb3aaa1d0d0723d91e368 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd +https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda#d1db1b8be7c3a8983dcbbbfe4f0765de https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.conda#081aa22f4581c08e4372b0b6c2f8478e https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.conda#1f0a03af852a9659ed2bf08f2f1704fd https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da -https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.67.0-had1ee68_0.conda#b499ce4b026493a13774bcf0f4c33849 +https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 @@ -117,17 +118,18 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.13.27-h3870b5a_0.conda#b868db6b48436bdbda71aa8576f4a44d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.conda#d47dee1856d9cb955b8076eeff304a5b -https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hd9c7081_0.conda#cae723309a49399d2949362f4ab5c9e4 +https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda#b52b769cd13f7adaa6ccdc68ef801709 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-hb8b1518_5.conda#d4a250da4737ee127fb1fa6452a9002e -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.18.0-h4e3cde8_0.conda#0a5563efed19ca4461cf927419b6eb73 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.10-hd0affe5_4.conda#1d4c18d75c51ed9d00092a891a547a7d +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda#8ee3cb7f64be0e8c4787f3a4dbe024e6 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -143,14 +145,13 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.3.1-h1e0337 https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.7.10-h9ab9c9b_2.conda#cf49873da2e59f876a2ad4794b05801b https://conda.anaconda.org/conda-forge/linux-64/brotli-1.0.9-h166bdaf_9.conda#4601544b4982ba1861fa9b9c607b2c06 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.0.9-py311ha362b79_9.conda#ced5340f5dc6cff43a80deac8d0e398f +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda#beb628209b2b354b98203066f90b3287 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda#49ee13eb9b8f44d63879c69b8a40a74b https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -159,13 +160,12 @@ https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-he970967_0.conda#2e5bf4f1da39c0b32778561c3c4e5878 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 @@ -189,29 +189,29 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.0-h435f46f_0.conda#c7726f96aab024855ede05e0ca6e94a0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.8.13-hd4f18eb_5.conda#860fb8c0efec64a4a678eb2ea066ff65 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.4-py311h3778330_0.conda#6b1b19bdc407007d5e41079eab797ddc +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py311h3778330_0.conda#e32c4e7639b1c1b5680fabdaa6081e56 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.0-h6083320_0.conda#71c2c966e17a65b08b995f571310fb9f https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.2-hb80d175_0.conda#fa63c385ddb50957d93bdb394e355be8 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.1.1-h6083320_0.conda#56d73078fe51aee26b7934cb1378d464 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 +https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 @@ -219,23 +219,22 @@ https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1 https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.20.2-h2a5cb19_18.conda#7313674073496cec938f73b71163bc31 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-20_linux64_openblas.conda#9932a1d4e9ecf2d35fb19475446e361e https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 +https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h7b9373a_16.conda#54db1af780a69493a2e0675113a027f9 https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 -https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 +https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h0c412b5_8.conda#80e27e7982af989ebc2e0f0d57c75ea7 https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 -https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-hc240232_7.conda#fa3bbe293d907990f3ca5b8b9d4b10f0 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.0-py311h39c9aba_9_cpu.conda#c35fe329bcc51a1a3a254c990ba8f738 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.0-py311h39c9aba_9_cpu.conda#c35fe329bcc51a1a3a254c990ba8f738 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b # pip pytz @ https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl#sha256=f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a # pip pandas @ https://files.pythonhosted.org/packages/fa/fe/c81ad3991f2c6aeacf01973f1d37b1dc76c0682f312f104741602a9557f1/pandas-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=e252a9e49b233ff96e2815c67c29702ac3a062098d80a170c506dff3470fd060 diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index d7ea66215a420..763d14eebab18 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -6,7 +6,10 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de +https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 +https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 @@ -17,37 +20,34 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18. https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda#edb0dca6bc32e4f4789199455a1dbeb8 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e +https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.2-h33c6efd_0.conda#186a18e3ba246eccfc7cff00cd19a870 +https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.1-hedf47ba_0.conda#876d0d4cdb6bef3957a91fb4271ac346 -https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_101.conda#12bd9a3f089ee6c9266a37dab82afabd -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f @@ -56,7 +56,7 @@ https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1 https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.5-pyhd8ed1ab_0.conda#beb628209b2b354b98203066f90b3287 +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda#49ee13eb9b8f44d63879c69b8a40a74b https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 @@ -64,7 +64,7 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 -https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2#7de5386c8fea29e76b303f37dde4c352 +https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 @@ -88,7 +88,7 @@ https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc4 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.2-py311h2e04523_1.conda#a8105076864776eceae69d64d30e24d7 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py311h2e04523_0.conda#cfc8f864dea571677095ebae8e6f0c07 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f diff --git a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock index e4249e00804f0..fe77ea4ada29f 100644 --- a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock @@ -21,7 +21,7 @@ https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda#1e610f24 https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda#4cb8e6b48f67de0b018719cdf1136306 https://conda.anaconda.org/conda-forge/win-64/double-conversion-3.4.0-hac47afa_0.conda#3d3caf4ccc6415023640af4b1b33060a https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda#b785694dd3ec77a011ccf0c24725382b -https://conda.anaconda.org/conda-forge/win-64/icu-78.2-h637d24d_0.conda#0ee3bb487600d5e71ab7d28951b2016a +https://conda.anaconda.org/conda-forge/win-64/icu-78.3-h637d24d_0.conda#0097b24800cb696915c3dbd1f5335d3f https://conda.anaconda.org/conda-forge/win-64/lerc-4.1.0-hd936e49_0.conda#54b231d595bc1ff9bff668dd443ee012 https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda#444b0a45bbd1cb24f82eedb56721b9c4 https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e @@ -35,7 +35,7 @@ https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.30-pthreads_h877e4 https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda#8830689d537fda55f990620680934bb1 https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.341.0-h477610d_0.conda#804880b2674119b84277d6c16b01677d https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda#f9bbae5e2537e3b06e0f7310ba76c893 -https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda#41fbfac52c601159df6c01f875de31b9 +https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda#dbabbd6234dea34040e631f87676292f https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda#7ecb9f2f112c66f959d2bb7dbdb89b67 https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda#eb585509b815415bc964b2c7e11c7eb3 https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda#08c8fa3b419df480d985e304f7884d35 @@ -86,14 +86,14 @@ https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py311h3485c13_0.cond https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.1-py311h3485c13_0.conda#e6badeb53d9bc5cccebe46a62c5a7336 https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda#bc58fdbced45bb096364de0fba1637af -https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.4-py311h3f79411_0.conda#95b58888be94ced8132fce6dd0ff5d13 +https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.5-py311h3f79411_0.conda#32eaff69a4a2426c01748784090a5e76 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/win-64/lcms2-2.18-hf2c6c5f_0.conda#b6c68d6b829b044cd17a41e0a8a23ca1 https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.2-h57928b3_0.conda#153d52fd0e4ba2a5bd5bb4f4afa41417 https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-5_hbb0e6ff_openblas.conda#b96fdd694dc8b7a5869613121c40d086 https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 -https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.2-py311h80b3fa1_1.conda#a824c6667179120c458beb9e9394932f +https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.3-py311h65cb7f3_0.conda#e37a9cfab4d96b7945119a3095087648 https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h0e57b4f_0.conda#e723ab7cc2794c954e1b22fde51c16e4 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -113,7 +113,7 @@ https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda#52ea https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/win-64/harfbuzz-13.1.1-h5a1b470_0.conda#987061cd0ee71af3493e5dbc6cbde56b -https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.10.2-h35725d6_5.conda#193fcaa5c64aa817cd8cde92afbc9d4e -https://conda.anaconda.org/conda-forge/win-64/pyside6-6.10.2-py311he824864_0.conda#de20381acf972a7a48692efd4614e53e +https://conda.anaconda.org/conda-forge/win-64/harfbuzz-13.2.0-h5a1b470_0.conda#92901fd2086b94a243abc5da33cfa87d +https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.10.2-pl5321hfcac499_6.conda#d5a2b237ad30f01d4f9474313c1ef1c4 +https://conda.anaconda.org/conda-forge/win-64/pyside6-6.10.2-py311he824864_1.conda#980f3c2f9a93d8b68990133a76d2b667 https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py311h1ea47a8_0.conda#64fe28aa2486e41918239d385336e88e From 9371975cb9b787b01401ba7ec27911777b57e5ce Mon Sep 17 00:00:00 2001 From: sauravyadav1008 <sauravyadav1008@gmail.com> Date: Mon, 23 Mar 2026 20:27:52 +0530 Subject: [PATCH 301/462] CI: Restrict all-tests job to run only in main repository (#33571) --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 146af926287ef..0af5c5ee92676 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -482,7 +482,7 @@ jobs: check-job-statuses: name: Check all job statuses runs-on: ubuntu-latest - if: always() + if: always() && github.repository == 'scikit-learn/scikit-learn' needs: [lint, unit-tests, debian-32bit, free-threaded, scipy-dev] steps: - uses: re-actors/alls-green@release/v1 From 78b2428198d0078d587e84ef89e7c273eff091cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= <deamarialeon@gmail.com> Date: Mon, 23 Mar 2026 20:49:46 +0100 Subject: [PATCH 302/462] FIX rounding float numbers in fitted attributes HTML display (#33615) --- sklearn/utils/_repr_html/fitted_attributes.py | 2 +- .../utils/_repr_html/tests/test_attributes.py | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/sklearn/utils/_repr_html/fitted_attributes.py b/sklearn/utils/_repr_html/fitted_attributes.py index 9941140bd033b..9375baad5a811 100644 --- a/sklearn/utils/_repr_html/fitted_attributes.py +++ b/sklearn/utils/_repr_html/fitted_attributes.py @@ -36,7 +36,7 @@ def _read_fitted_attr(value): r.maxstring = 9 if isinstance(value, float): - value = round(value, 3) + return f"{value:.4g}" return html.escape(r.repr(value)) diff --git a/sklearn/utils/_repr_html/tests/test_attributes.py b/sklearn/utils/_repr_html/tests/test_attributes.py index bdfc54a713805..e599269e7e96e 100644 --- a/sklearn/utils/_repr_html/tests/test_attributes.py +++ b/sklearn/utils/_repr_html/tests/test_attributes.py @@ -4,7 +4,11 @@ import pytest from sklearn import config_context -from sklearn.utils._repr_html.fitted_attributes import AttrsDict, _fitted_attr_html_repr +from sklearn.utils._repr_html.fitted_attributes import ( + AttrsDict, + _fitted_attr_html_repr, + _read_fitted_attr, +) fitted_attrs = AttrsDict( fitted_attrs={ @@ -167,3 +171,15 @@ def test_pandas_series_fitted_attr(): r"\s*</div>" ) assert re.search(expected_html_fitted_attr, html_fitted_attr_out, flags=re.DOTALL) + + +@pytest.mark.parametrize( + "value, expected", + [ + (123.456, "123.5"), + (0.00123456, "0.001235"), + (1234567.0, "1.235e+06"), + ], +) +def test_read_fitted_attr_float_formatting(value, expected): + assert _read_fitted_attr(value) == expected From 6073302234448436344310b0ce564bcd088f173b Mon Sep 17 00:00:00 2001 From: Nikita <vokelood@gmail.com> Date: Tue, 24 Mar 2026 13:26:53 +0300 Subject: [PATCH 303/462] MNT Clean up deprecations for 1.9: default n_init in MDS (#33595) Co-authored-by: Tim Head <betatim@gmail.com> --- sklearn/manifold/_mds.py | 35 +++++++----------------------- sklearn/manifold/tests/test_mds.py | 20 ----------------- 2 files changed, 8 insertions(+), 47 deletions(-) diff --git a/sklearn/manifold/_mds.py b/sklearn/manifold/_mds.py index 72116d048a2b2..a5d3ac81c1d55 100644 --- a/sklearn/manifold/_mds.py +++ b/sklearn/manifold/_mds.py @@ -195,14 +195,13 @@ def _smacof_single( return X, stress, it + 1 -# TODO(1.9): change default `n_init` to 1, see PR #31117 @validate_params( { "dissimilarities": ["array-like"], "metric": ["boolean"], "n_components": [Interval(Integral, 1, None, closed="left")], "init": ["array-like", None], - "n_init": [Interval(Integral, 1, None, closed="left"), StrOptions({"warn"})], + "n_init": [Interval(Integral, 1, None, closed="left")], "n_jobs": [Integral, None], "max_iter": [Interval(Integral, 1, None, closed="left")], "verbose": ["verbose"], @@ -219,7 +218,7 @@ def smacof( metric=True, n_components=2, init=None, - n_init="warn", + n_init=1, n_jobs=None, max_iter=300, verbose=0, @@ -268,14 +267,14 @@ def smacof( Starting configuration of the embedding to initialize the algorithm. By default, the algorithm is initialized with a randomly chosen array. - n_init : int, default=8 + n_init : int, default=1 Number of times the SMACOF algorithm will be run with different initializations. The final results will be the best output of the runs, determined by the run with the smallest final stress. If ``init`` is provided, this option is overridden and a single run is performed. .. versionchanged:: 1.9 - The default value for `n_iter` will change from 8 to 1 in version 1.9. + The default value for `n_iter` changed from 8 to 1. n_jobs : int, default=None The number of jobs to use for the computation. If multiple @@ -364,13 +363,6 @@ def smacof( 3.2e-05 """ - if n_init == "warn": - warnings.warn( - "The default value of `n_init` will change from 8 to 1 in 1.9.", - FutureWarning, - ) - n_init = 8 - dissimilarities = check_array(dissimilarities) random_state = check_random_state(random_state) @@ -433,7 +425,6 @@ def smacof( return best_pos, best_stress -# TODO(1.9): change default `n_init` to 1, see PR #31117 # TODO(1.10): change default `init` to "classical_mds", see PR #32229 # TODO(1.10): drop support for boolean `metric`, see PR #32229 # TODO(1.10): drop support for `dissimilarity`, see PR #32229 @@ -455,13 +446,13 @@ class MDS(BaseEstimator): .. versionchanged:: 1.8 The parameter `metric` was renamed into `metric_mds`. - n_init : int, default=4 + n_init : int, default=1 Number of times the SMACOF algorithm will be run with different initializations. The final results will be the best output of the runs, determined by the run with the smallest final stress. .. versionchanged:: 1.9 - The default value for `n_init` will change from 4 to 1 in version 1.9. + The default value for `n_init` changed from 4 to 1. init : {'random', 'classical_mds'}, default='random' The initialization approach. If `random`, random initialization is used. @@ -654,7 +645,7 @@ def __init__( n_components=2, *, metric_mds=True, - n_init="warn", + n_init=1, init="warn", max_iter=300, verbose=0, @@ -740,16 +731,6 @@ def fit_transform(self, X, y=None, init=None): X transformed in the new space. """ - if self.n_init == "warn": - warnings.warn( - "The default value of `n_init` will change from 4 to 1 in 1.9. " - "To suppress this warning, provide some value of `n_init`.", - FutureWarning, - ) - self._n_init = 4 - else: - self._n_init = self.n_init - if self.init == "warn": warnings.warn( "The default value of `init` will change from 'random' to " @@ -823,7 +804,7 @@ def fit_transform(self, X, y=None, init=None): metric=self._metric_mds, n_components=self.n_components, init=init_array, - n_init=self._n_init, + n_init=self.n_init, n_jobs=self.n_jobs, max_iter=self.max_iter, verbose=self.verbose, diff --git a/sklearn/manifold/tests/test_mds.py b/sklearn/manifold/tests/test_mds.py index f703a38ac7fd0..1e5fe94a0a87b 100644 --- a/sklearn/manifold/tests/test_mds.py +++ b/sklearn/manifold/tests/test_mds.py @@ -242,19 +242,6 @@ def test_convergence_does_not_depend_on_scale(metric_mds): assert_equal(n_iter1, n_iter2) -# TODO(1.9): delete this test -def test_future_warning_n_init(): - X = np.array([[1, 1], [1, 4], [1, 5], [3, 3]]) - sim = np.array([[0, 5, 3, 4], [5, 0, 2, 2], [3, 2, 0, 1], [4, 2, 1, 0]]) - - with pytest.warns(FutureWarning): - mds.smacof(sim) - - with pytest.warns(FutureWarning): - mds.MDS(init="random").fit(X) - - -# TODO(1.9): delete the n_init warning check # TODO(1.10): delete this test def test_future_warning_init_and_metric(): X = np.array([[1, 1], [1, 4], [1, 5], [3, 3]]) @@ -276,11 +263,6 @@ def test_future_warning_init_and_metric(): with pytest.warns(FutureWarning, match="The default value of `init`"): mds.MDS(metric="euclidean", n_init=1).fit(X) - # TODO (1.9): delete this check - # n_init=1 will become default in the future - with pytest.warns(FutureWarning, match="The default value of `n_init`"): - mds.MDS(metric="euclidean", init="random").fit(X) - # providing both metric and dissimilarity raises an error with pytest.raises(ValueError, match="provided both `dissimilarity`"): mds.MDS( @@ -288,8 +270,6 @@ def test_future_warning_init_and_metric(): ).fit(X) -# TODO(1.9): remove warning filter -@pytest.mark.filterwarnings("ignore::FutureWarning") def test_classical_mds_init_to_mds(): X, _ = load_iris(return_X_y=True) From cb4ce6d5257378052fbe664b710084b2bb39fd56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= <deamarialeon@gmail.com> Date: Tue, 24 Mar 2026 11:57:09 +0100 Subject: [PATCH 304/462] FIX ColumnTransformer HTML display incorrect when all columns are transformed (#33531) --- sklearn/compose/_column_transformer.py | 17 ++++++------ .../compose/tests/test_column_transformer.py | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index 362821159aa06..5de8f78b229ba 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -1226,16 +1226,17 @@ def _hstack(self, Xs, *, n_samples): def _sk_visual_block_(self): # We can find remainder and its column only when it's fitted if hasattr(self, "transformers_"): - transformers = [ - transformer - for transformer in self.transformers_[:-1] # Exclude remainder - if not (transformer[0] == "remainder" and transformer[1] == "drop") - ] + transformers = ( + self.transformers_[:-1] + if self.transformers_ and self.transformers_[-1][0] == "remainder" + else self.transformers_ + ) # Add remainder back to fitted transformers if remainder is not drop - if self.remainder != "drop": - remainder_columns = self._remainder[2] - has_numeric_columns = remainder_columns and not all( + # and if there are remainder columns to display + remainder_columns = self._remainder[2] + if self.remainder != "drop" and remainder_columns: + has_numeric_columns = not all( isinstance(col, str) for col in remainder_columns ) # Convert indices to column names when feature names are available diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index 6f4cbd6bb2ed5..9f69a956d7c38 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -1647,6 +1647,32 @@ def test_sk_visual_block_remainder_col_names_pandas(): assert visual_block.name_details == (["col1"], ["col2"]) +def test_sk_visual_block_full_transform(): + """Check that visual_block doesn't return remainder when it has no columns + Non-regression test - https://github.com/scikit-learn/scikit-learn/issues/33513 + """ + ct = ColumnTransformer([("norm1", Normalizer(), [0, 1])], remainder="passthrough") + X = np.array([[0, 4], [3, 3]]) + ct.fit(X) + visual_block = ct._sk_visual_block_() + assert visual_block.names == ("norm1",) + assert visual_block.name_details == ([0, 1],) + assert isinstance(visual_block.estimators[0], Normalizer) + assert len(visual_block.estimators) == 1 + + +def test_sk_visual_block_int_remainder_cols_pandas(): + """Check that remainder still uses available string column names in visual block + even when transformer columns are specified by integer index. + """ + pd = pytest.importorskip("pandas") + X = pd.DataFrame({"a": [1, 2], "b": [3, 4], "c": [5, 6]}) + ct = ColumnTransformer([("scaler", StandardScaler(), [0])], remainder="passthrough") + ct.fit(X) + visual_block = ct._sk_visual_block_() + assert visual_block.name_details == ([0], ["b", "c"]) + + @pytest.mark.parametrize("explicit_colname", ["first", "second", 0, 1]) @pytest.mark.parametrize("remainder", [Trans(), "passthrough", "drop"]) def test_column_transformer_reordered_column_names_remainder( From f6aed9890cf778d0b81ece896b658230adec3bc0 Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Wed, 25 Mar 2026 09:34:20 +0100 Subject: [PATCH 305/462] Always try to use dlpack-capable `move_to` for NumPy conversions and only use `_convert_to_numpy` as a fallback (#33623) Co-authored-by: Tim Head <betatim@gmail.com> Co-authored-by: Omar Salman <omar.salman2007@gmail.com> --- .../array-api/33623.enhancement.rst | 5 +++ sklearn/_loss/tests/test_link.py | 6 ++-- sklearn/_loss/tests/test_loss.py | 4 +-- sklearn/calibration.py | 3 +- sklearn/decomposition/tests/test_pca.py | 10 +++--- sklearn/linear_model/_base.py | 4 +-- sklearn/linear_model/_glm/glm.py | 5 ++- sklearn/linear_model/_glm/tests/test_glm.py | 6 ++-- sklearn/linear_model/_linear_loss.py | 10 +++--- sklearn/linear_model/_logistic.py | 6 ++-- sklearn/linear_model/tests/test_logistic.py | 10 +++--- sklearn/linear_model/tests/test_ridge.py | 8 ++--- sklearn/metrics/_classification.py | 9 +++--- sklearn/metrics/cluster/_unsupervised.py | 4 +-- sklearn/metrics/tests/test_common.py | 4 +-- sklearn/metrics/tests/test_pairwise.py | 14 ++++----- sklearn/mixture/_base.py | 18 ++++++----- .../mixture/tests/test_gaussian_mixture.py | 31 ++++++++++--------- sklearn/model_selection/_split.py | 5 ++- sklearn/model_selection/_validation.py | 3 +- sklearn/model_selection/tests/test_split.py | 12 +++---- .../model_selection/tests/test_validation.py | 4 +-- sklearn/naive_bayes.py | 4 +-- sklearn/preprocessing/_label.py | 8 ++--- sklearn/preprocessing/tests/test_data.py | 16 +++++----- sklearn/preprocessing/tests/test_label.py | 27 ++++++++++------ .../preprocessing/tests/test_polynomial.py | 4 +-- sklearn/tests/test_calibration.py | 14 ++++----- sklearn/tests/test_kernel_approximation.py | 4 +-- sklearn/tests/test_naive_bayes.py | 14 ++++----- sklearn/tests/test_pipeline.py | 4 +-- sklearn/utils/_array_api.py | 19 ++++++++---- sklearn/utils/class_weight.py | 10 +++--- sklearn/utils/estimator_checks.py | 8 ++--- sklearn/utils/tests/test_array_api.py | 24 +++++++------- sklearn/utils/tests/test_extmath.py | 14 ++++----- sklearn/utils/tests/test_indexing.py | 9 +++--- sklearn/utils/tests/test_stats.py | 6 ++-- sklearn/utils/tests/test_validation.py | 6 ++-- sklearn/utils/validation.py | 4 +-- 40 files changed, 198 insertions(+), 178 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/33623.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/array-api/33623.enhancement.rst b/doc/whats_new/upcoming_changes/array-api/33623.enhancement.rst new file mode 100644 index 0000000000000..1aac9ec9edaf1 --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/33623.enhancement.rst @@ -0,0 +1,5 @@ +- Internal NumPy CPU conversions now always attempt a generic DLPack-based + transfer and only fallback to library-specific methods when necessary. This + should ease support for additional array API and DLPack compliant input types + without extending the ad hoc conversion helpers. + By :user:`Olivier Grisel <ogrisel>`. diff --git a/sklearn/_loss/tests/test_link.py b/sklearn/_loss/tests/test_link.py index 5177701c0619a..230538668eea0 100644 --- a/sklearn/_loss/tests/test_link.py +++ b/sklearn/_loss/tests/test_link.py @@ -11,7 +11,7 @@ _inclusive_low_high, ) from sklearn.utils._array_api import ( - _convert_to_numpy, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import _array_api_for_tests @@ -122,7 +122,7 @@ def test_link_inverse_array_api( with config_context(array_api_dispatch=True): raw_prediction_xp = xp.asarray(raw_prediction.astype(dtype_name), device=device) assert_allclose( - _convert_to_numpy(link.inverse(raw_prediction_xp), xp=xp), + move_to(link.inverse(raw_prediction_xp), xp=np, device="cpu"), link.inverse(raw_prediction), rtol=rtol, ) @@ -130,7 +130,7 @@ def test_link_inverse_array_api( y_pred = link.inverse(raw_prediction) y_pred_xp = xp.asarray(y_pred.astype(dtype_name), device=device) assert_allclose( - _convert_to_numpy(link.link(y_pred_xp), xp=xp), + move_to(link.link(y_pred_xp), xp=np, device="cpu"), link.link(y_pred), rtol=rtol, ) diff --git a/sklearn/_loss/tests/test_loss.py b/sklearn/_loss/tests/test_loss.py index 1df697c2d4598..07329c06f7249 100644 --- a/sklearn/_loss/tests/test_loss.py +++ b/sklearn/_loss/tests/test_loss.py @@ -35,7 +35,7 @@ from sklearn.utils import assert_all_finite from sklearn.utils._array_api import ( _atol_for_type, - _convert_to_numpy, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import ( @@ -1405,7 +1405,7 @@ def _assert_array_api_result( result_xp, result_np, raw_prediction_xp, xp, rtol, atol ): assert_allclose( - _convert_to_numpy(result_xp, xp=xp), result_np, rtol=rtol, atol=atol + move_to(result_xp, xp=np, device="cpu"), result_np, rtol=rtol, atol=atol ) assert result_xp.dtype == raw_prediction_xp.dtype assert array_api_device(result_xp) == array_api_device(raw_prediction_xp) diff --git a/sklearn/calibration.py b/sklearn/calibration.py index fd6832d6d1cef..7917fc0897974 100644 --- a/sklearn/calibration.py +++ b/sklearn/calibration.py @@ -33,7 +33,6 @@ from sklearn.svm import LinearSVC from sklearn.utils import Bunch, _safe_indexing, column_or_1d, get_tags, indexable from sklearn.utils._array_api import ( - _convert_to_numpy, _is_numpy_namespace, get_namespace, get_namespace_and_device, @@ -556,7 +555,7 @@ def predict(self, X): check_is_fitted(self) class_indices = xp.argmax(self.predict_proba(X), axis=1) if isinstance(self.classes_[0], str): - class_indices = _convert_to_numpy(class_indices, xp=xp) + class_indices = move_to(class_indices, xp=np, device="cpu") return self.classes_[class_indices] diff --git a/sklearn/decomposition/tests/test_pca.py b/sklearn/decomposition/tests/test_pca.py index 909fee3e6a5c5..238c1b15b2ea4 100644 --- a/sklearn/decomposition/tests/test_pca.py +++ b/sklearn/decomposition/tests/test_pca.py @@ -13,7 +13,7 @@ from sklearn.decomposition._pca import _assess_dimension, _infer_dimension from sklearn.utils._array_api import ( _atol_for_type, - _convert_to_numpy, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import device as array_device @@ -954,7 +954,7 @@ def check_array_api_get_precision( assert precision_xp.dtype == iris_xp.dtype assert_allclose( - _convert_to_numpy(precision_xp, xp=xp), + move_to(precision_xp, xp=np, device="cpu"), precision_np, rtol=rtol, atol=_atol_for_type(dtype_name), @@ -964,7 +964,7 @@ def check_array_api_get_precision( assert covariance_xp.dtype == iris_xp.dtype assert_allclose( - _convert_to_numpy(covariance_xp, xp=xp), + move_to(covariance_xp, xp=np, device="cpu"), covariance_np, rtol=rtol, atol=_atol_for_type(dtype_name), @@ -1067,11 +1067,11 @@ def test_pca_mle_array_api_compliance( est_xp.fit(X_xp, y_xp) components_xp = est_xp.components_ assert array_device(components_xp) == array_device(X_xp) - components_xp_np = _convert_to_numpy(components_xp, xp=xp) + components_xp_np = move_to(components_xp, xp=np, device="cpu") explained_variance_xp = est_xp.explained_variance_ assert array_device(explained_variance_xp) == array_device(X_xp) - explained_variance_xp_np = _convert_to_numpy(explained_variance_xp, xp=xp) + explained_variance_xp_np = move_to(explained_variance_xp, xp=np, device="cpu") assert components_xp_np.dtype == components_np.dtype assert components_xp_np.shape[1] == components_np.shape[1] diff --git a/sklearn/linear_model/_base.py b/sklearn/linear_model/_base.py index 7f57bb6293a40..1a9b19d803a62 100644 --- a/sklearn/linear_model/_base.py +++ b/sklearn/linear_model/_base.py @@ -25,12 +25,12 @@ from sklearn.utils._array_api import ( _asarray_with_order, _average, - _convert_to_numpy, _expit, _is_numpy_namespace, get_namespace, get_namespace_and_device, indexing_dtype, + move_to, supported_float_dtypes, ) from sklearn.utils._param_validation import Interval @@ -396,7 +396,7 @@ def predict(self, X): # predictions according to the namespace of `self.classes_` i.e. numpy. xp_classes, _ = get_namespace(self.classes_) if _is_numpy_namespace(xp_classes): - indices = _convert_to_numpy(indices, xp=xp) + indices = move_to(indices, xp=np, device="cpu") return xp_classes.take(self.classes_, indices, axis=0) diff --git a/sklearn/linear_model/_glm/glm.py b/sklearn/linear_model/_glm/glm.py index b29818591826c..5e3136035c7fd 100644 --- a/sklearn/linear_model/_glm/glm.py +++ b/sklearn/linear_model/_glm/glm.py @@ -24,7 +24,6 @@ from sklearn.utils import check_array from sklearn.utils._array_api import ( _average, - _convert_to_numpy, _is_numpy_namespace, _matching_numpy_dtype, get_namespace, @@ -256,10 +255,10 @@ def fit(self, X, y, sample_weight=None): loss_dtype_np = _matching_numpy_dtype(X, xp=xp) if self.warm_start and hasattr(self, "coef_"): coef_xp, _ = get_namespace(self.coef_) - coef = _convert_to_numpy(self.coef_, xp=coef_xp) + coef = move_to(self.coef_, xp=np, device="cpu") if self.fit_intercept: # LinearModelLoss needs intercept at the end of coefficient array. - intercept = _convert_to_numpy(self.intercept_, xp=coef_xp) + intercept = move_to(self.intercept_, xp=np, device="cpu") coef = np.concatenate((coef, np.array([intercept]))) coef = coef.astype(loss_dtype_np, copy=False) else: diff --git a/sklearn/linear_model/_glm/tests/test_glm.py b/sklearn/linear_model/_glm/tests/test_glm.py index 3c188511414aa..f16a1f07f7e95 100644 --- a/sklearn/linear_model/_glm/tests/test_glm.py +++ b/sklearn/linear_model/_glm/tests/test_glm.py @@ -30,7 +30,7 @@ from sklearn.model_selection import train_test_split from sklearn.utils._array_api import ( _atol_for_type, - _convert_to_numpy, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import ( @@ -1205,14 +1205,14 @@ def test_poisson_regressor_array_api_compliance( attr_xp = getattr(glm_xp, attr_name) attr_np = getattr(glm_np, attr_name) assert_allclose( - _convert_to_numpy(attr_xp, xp=xp), attr_np, rtol=rtol, atol=atol + move_to(attr_xp, xp=np, device="cpu"), attr_np, rtol=rtol, atol=atol ) assert attr_xp.dtype == X_xp.dtype assert array_api_device(attr_xp) == array_api_device(X_xp) predict_xp = glm_xp.predict(X_xp) assert_allclose( - _convert_to_numpy(predict_xp, xp=xp), + move_to(predict_xp, xp=np, device="cpu"), predict_np, rtol=rtol, atol=atol, diff --git a/sklearn/linear_model/_linear_loss.py b/sklearn/linear_model/_linear_loss.py index 644ea748e2597..1e156122d54df 100644 --- a/sklearn/linear_model/_linear_loss.py +++ b/sklearn/linear_model/_linear_loss.py @@ -9,9 +9,9 @@ from scipy import sparse from sklearn.utils._array_api import ( - _convert_to_numpy, get_namespace, get_namespace_and_device, + move_to, ) from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils.extmath import safe_sparse_dot, squared_norm @@ -355,7 +355,7 @@ def loss_gradient( grad = np.empty_like(coef, dtype=weights.dtype) X_grad = X.T @ grad_pointwise grad[:n_features] = ( - _convert_to_numpy(X_grad, xp=xp) + l2_reg_strength * weights + move_to(X_grad, xp=np, device="cpu") + l2_reg_strength * weights ) if self.fit_intercept: grad[-1] = xp.sum(grad_pointwise) @@ -367,10 +367,12 @@ def loss_gradient( # grad_pointwise.shape = (n_samples, n_classes) grad_X = grad_pointwise.T @ X grad[:, :n_features] = ( - _convert_to_numpy(grad_X, xp) + l2_reg_strength * weights + move_to(grad_X, xp=np, device="cpu") + l2_reg_strength * weights ) if self.fit_intercept: - grad[:, -1] = _convert_to_numpy(xp.sum(grad_pointwise, axis=0), xp=xp) + grad[:, -1] = move_to( + xp.sum(grad_pointwise, axis=0), xp=np, device="cpu" + ) if coef.ndim == 1: grad = grad.ravel(order="F") diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index 246016a8d14b5..1b496e02ada37 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -40,11 +40,11 @@ compute_class_weight, ) from sklearn.utils._array_api import ( - _convert_to_numpy, _is_numpy_namespace, _matching_numpy_dtype, get_namespace, get_namespace_and_device, + move_to, size, ) from sklearn.utils._param_validation import Hidden, Interval, StrOptions @@ -1328,9 +1328,9 @@ def fit(self, X, y, sample_weight=None): else: warm_start_coef = None if warm_start_coef is not None: - warm_start_coef = _convert_to_numpy(warm_start_coef, xp=xp) + warm_start_coef = move_to(warm_start_coef, xp=np, device="cpu") if self.fit_intercept: - intercept_np = _convert_to_numpy(self.intercept_, xp=xp) + intercept_np = move_to(self.intercept_, xp=np, device="cpu") warm_start_coef = np.concatenate( [warm_start_coef, intercept_np[:, None]], axis=1 ) diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index efd094c281d9c..7d8222e8fb3ba 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -38,7 +38,7 @@ from sklearn.utils import compute_class_weight, shuffle from sklearn.utils._array_api import ( _atol_for_type, - _convert_to_numpy, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import ( @@ -2786,14 +2786,14 @@ def test_logistic_regression_array_api_compliance( attr_xp = getattr(lr_xp, attr_name) attr_np = getattr(lr_np, attr_name) assert_allclose( - _convert_to_numpy(attr_xp, xp=xp), attr_np, rtol=rtol, atol=atol + move_to(attr_xp, xp=np, device="cpu"), attr_np, rtol=rtol, atol=atol ) assert attr_xp.dtype == X_xp.dtype assert array_api_device(attr_xp) == array_api_device(X_xp) predict_proba_xp = lr_xp.predict_proba(X_xp) assert_allclose( - _convert_to_numpy(predict_proba_xp, xp=xp), + move_to(predict_proba_xp, xp=np, device="cpu"), predict_proba_np, rtol=rtol, atol=atol, @@ -2803,7 +2803,7 @@ def test_logistic_regression_array_api_compliance( predict_log_proba_xp = lr_xp.predict_log_proba(X_xp) assert_allclose( - _convert_to_numpy(predict_log_proba_xp, xp=xp), + move_to(predict_log_proba_xp, xp=np, device="cpu"), preditct_log_proba_np, rtol=rtol, atol=atol, @@ -2813,7 +2813,7 @@ def test_logistic_regression_array_api_compliance( prediction_xp = lr_xp.predict(X_xp) if not use_str_y: - prediction_xp = _convert_to_numpy(prediction_xp, xp=xp) + prediction_xp = move_to(prediction_xp, xp=np, device="cpu") assert_array_equal(prediction_xp, prediction_np) diff --git a/sklearn/linear_model/tests/test_ridge.py b/sklearn/linear_model/tests/test_ridge.py index 0f44c551b57a8..af0ebfd978862 100644 --- a/sklearn/linear_model/tests/test_ridge.py +++ b/sklearn/linear_model/tests/test_ridge.py @@ -44,7 +44,7 @@ from sklearn.utils._array_api import ( _NUMPY_NAMESPACE_NAMES, _atol_for_type, - _convert_to_numpy, + move_to, yield_namespace_device_dtype_combinations, yield_namespaces, ) @@ -1429,7 +1429,7 @@ def check_array_api_attributes( assert coef_xp.dtype == X_iris_xp.dtype assert_allclose( - _convert_to_numpy(coef_xp, xp=xp), + move_to(coef_xp, xp=np, device="cpu"), coef_np, rtol=rtol, atol=_atol_for_type(dtype_name), @@ -1439,7 +1439,7 @@ def check_array_api_attributes( assert intercept_xp.dtype == X_iris_xp.dtype assert_allclose( - _convert_to_numpy(intercept_xp, xp=xp), + move_to(intercept_xp, xp=np, device="cpu"), intercept_np, rtol=rtol, atol=_atol_for_type(dtype_name), @@ -1500,7 +1500,7 @@ def test_ridge_classifier_multilabel_array_api( ridge_xp = estimator.fit(X_xp, y_xp) pred_xp = ridge_xp.predict(X_xp) assert pred_xp.shape == pred_np.shape == y.shape - assert_allclose(_convert_to_numpy(pred_xp, xp=xp), pred_np) + assert_allclose(move_to(pred_xp, xp=np, device="cpu"), pred_np) @pytest.mark.parametrize( diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 62c9424568309..3eea92e67fb69 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -31,7 +31,6 @@ from sklearn.utils._array_api import ( _average, _bincount, - _convert_to_numpy, _count_nonzero, _fill_diagonal, _find_matching_floating_dtype, @@ -538,12 +537,12 @@ def confusion_matrix( # counting operations implemented by SciPy in the coo_matrix constructor. # The final results will be converted back to the input namespace and device # for the sake of consistency with other metric functions with array API support. - y_true = _convert_to_numpy(y_true, xp) - y_pred = _convert_to_numpy(y_pred, xp) + y_true = move_to(y_true, xp=np, device="cpu") + y_pred = move_to(y_pred, xp=np, device="cpu") if sample_weight is None: sample_weight = np.ones(y_true.shape[0], dtype=np.int64) else: - sample_weight = _convert_to_numpy(sample_weight, xp) + sample_weight = move_to(sample_weight, xp=np, device="cpu") if len(sample_weight) > 0: y_type, y_true, y_pred, sample_weight = _check_targets( @@ -564,7 +563,7 @@ def confusion_matrix( if labels is None: labels = unique_labels(y_true, y_pred) else: - labels = _convert_to_numpy(labels, xp) + labels = move_to(labels, xp=np, device="cpu") n_labels = labels.size if n_labels == 0: raise ValueError("'labels' should contain at least one label.") diff --git a/sklearn/metrics/cluster/_unsupervised.py b/sklearn/metrics/cluster/_unsupervised.py index 95b7ff8ce2164..f5006cfcf9031 100644 --- a/sklearn/metrics/cluster/_unsupervised.py +++ b/sklearn/metrics/cluster/_unsupervised.py @@ -19,10 +19,10 @@ from sklearn.utils import _safe_indexing, check_random_state, check_X_y from sklearn.utils._array_api import ( _average, - _convert_to_numpy, _is_numpy_namespace, _max_precision_float_dtype, get_namespace_and_device, + move_to, xpx, ) from sklearn.utils._param_validation import Interval, StrOptions, validate_params @@ -376,7 +376,7 @@ def calinski_harabasz_score(X, labels): if _is_numpy_namespace(xp) and not is_numpy_array(X): # This is required to handle the case where `array_api_dispatch` is False but # we are still dealing with `X` as a non-NumPy array e.g. a PyTorch tensor. - X = _convert_to_numpy(X, xp=xp) + X = move_to(X, xp=np, device="cpu") else: X = xp.astype(X, _max_precision_float_dtype(xp, device_), copy=False) X, labels = check_X_y(X, labels) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index a425eeedb640d..3caf897099b0e 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -85,9 +85,9 @@ from sklearn.utils import shuffle from sklearn.utils._array_api import ( _atol_for_type, - _convert_to_numpy, _max_precision_float_dtype, get_namespace, + move_to, yield_mixed_namespace_input_permutations, yield_namespace_device_dtype_combinations, ) @@ -2061,7 +2061,7 @@ def check_array_api_metric( def _check_metric_matches(metric_a, metric_b, convert_a=False): if convert_a: - metric_a = _convert_to_numpy(xp.asarray(metric_a), xp) + metric_a = move_to(xp.asarray(metric_a), xp=np, device="cpu") assert_allclose(metric_a, metric_b, atol=_atol_for_type(dtype_name)) def _check_each_metric_matches(metric_a, metric_b, convert_a=False): diff --git a/sklearn/metrics/tests/test_pairwise.py b/sklearn/metrics/tests/test_pairwise.py index 80d779be8269b..256bee66d22af 100644 --- a/sklearn/metrics/tests/test_pairwise.py +++ b/sklearn/metrics/tests/test_pairwise.py @@ -49,8 +49,8 @@ ) from sklearn.preprocessing import normalize from sklearn.utils._array_api import ( - _convert_to_numpy, get_namespace, + move_to, xpx, yield_namespace_device_dtype_combinations, ) @@ -169,7 +169,7 @@ def test_pairwise_distances_array_api(array_namespace, device_name, dtype_name, with config_context(array_api_dispatch=True): # Test with Y=None D_xp = pairwise_distances(X_xp, metric=metric) - D_xp_np = _convert_to_numpy(D_xp, xp=xp) + D_xp_np = move_to(D_xp, xp=np, device="cpu") assert get_namespace(D_xp)[0].__name__ == xp.__name__ assert D_xp.device == X_xp.device assert D_xp.dtype == X_xp.dtype @@ -179,7 +179,7 @@ def test_pairwise_distances_array_api(array_namespace, device_name, dtype_name, # Test with Y=Y_np/Y_xp D_xp = pairwise_distances(X_xp, Y=Y_xp, metric=metric) - D_xp_np = _convert_to_numpy(D_xp, xp=xp) + D_xp_np = move_to(D_xp, xp=np, device="cpu") assert get_namespace(D_xp)[0].__name__ == xp.__name__ assert D_xp.device == X_xp.device assert D_xp.dtype == X_xp.dtype @@ -417,13 +417,13 @@ def test_pairwise_parallel_array_api( Y_np = None if y_val is None else Y_np n_job1_xp = func(X_xp, Y_xp, metric=metric, n_jobs=1, **kwds) - n_job1_xp_np = _convert_to_numpy(n_job1_xp, xp=xp) + n_job1_xp_np = move_to(n_job1_xp, xp=np, device="cpu") assert get_namespace(n_job1_xp)[0].__name__ == xp.__name__ assert n_job1_xp.device == X_xp.device assert n_job1_xp.dtype == X_xp.dtype n_job2_xp = func(X_xp, Y_xp, metric=metric, n_jobs=2, **kwds) - n_job2_xp_np = _convert_to_numpy(n_job2_xp, xp=xp) + n_job2_xp_np = move_to(n_job2_xp, xp=np, device="cpu") assert get_namespace(n_job2_xp)[0].__name__ == xp.__name__ assert n_job2_xp.device == X_xp.device assert n_job2_xp.dtype == X_xp.dtype @@ -501,7 +501,7 @@ def test_pairwise_kernels_array_api(metric, array_namespace, device_name, dtype_ with config_context(array_api_dispatch=True): # Test with Y=None K_xp = pairwise_kernels(X_xp, metric=metric) - K_xp_np = _convert_to_numpy(K_xp, xp=xp) + K_xp_np = move_to(K_xp, xp=np, device="cpu") assert get_namespace(K_xp)[0].__name__ == xp.__name__ assert K_xp.device == X_xp.device assert K_xp.dtype == X_xp.dtype @@ -511,7 +511,7 @@ def test_pairwise_kernels_array_api(metric, array_namespace, device_name, dtype_ # Test with Y=Y_np/Y_xp K_xp = pairwise_kernels(X_xp, Y=Y_xp, metric=metric) - K_xp_np = _convert_to_numpy(K_xp, xp=xp) + K_xp_np = move_to(K_xp, xp=np, device="cpu") assert get_namespace(K_xp)[0].__name__ == xp.__name__ assert K_xp.device == X_xp.device assert K_xp.dtype == X_xp.dtype diff --git a/sklearn/mixture/_base.py b/sklearn/mixture/_base.py index 30c4800b20c05..5603232c1b303 100644 --- a/sklearn/mixture/_base.py +++ b/sklearn/mixture/_base.py @@ -17,12 +17,12 @@ from sklearn.exceptions import ConvergenceWarning from sklearn.utils import check_random_state from sklearn.utils._array_api import ( - _convert_to_numpy, _is_numpy_namespace, _logsumexp, _max_precision_float_dtype, get_namespace, get_namespace_and_device, + move_to, ) from sklearn.utils._param_validation import Interval, StrOptions from sklearn.utils.validation import check_is_fitted, validate_data @@ -459,7 +459,7 @@ def sample(self, n_samples=1): _, n_features = self.means_.shape rng = check_random_state(self.random_state) n_samples_comp = rng.multinomial( - n_samples, _convert_to_numpy(self.weights_, xp) + n_samples, move_to(self.weights_, xp=np, device="cpu") ) if self.covariance_type == "full": @@ -467,8 +467,8 @@ def sample(self, n_samples=1): [ rng.multivariate_normal(mean, covariance, int(sample)) for (mean, covariance, sample) in zip( - _convert_to_numpy(self.means_, xp), - _convert_to_numpy(self.covariances_, xp), + move_to(self.means_, xp=np, device="cpu"), + move_to(self.covariances_, xp=np, device="cpu"), n_samples_comp, ) ] @@ -477,10 +477,12 @@ def sample(self, n_samples=1): X = np.vstack( [ rng.multivariate_normal( - mean, _convert_to_numpy(self.covariances_, xp), int(sample) + mean, + move_to(self.covariances_, xp=np, device="cpu"), + int(sample), ) for (mean, sample) in zip( - _convert_to_numpy(self.means_, xp), n_samples_comp + move_to(self.means_, xp=np, device="cpu"), n_samples_comp ) ] ) @@ -491,8 +493,8 @@ def sample(self, n_samples=1): + rng.standard_normal(size=(sample, n_features)) * np.sqrt(covariance) for (mean, covariance, sample) in zip( - _convert_to_numpy(self.means_, xp), - _convert_to_numpy(self.covariances_, xp), + move_to(self.means_, xp=np, device="cpu"), + move_to(self.covariances_, xp=np, device="cpu"), n_samples_comp, ) ] diff --git a/sklearn/mixture/tests/test_gaussian_mixture.py b/sklearn/mixture/tests/test_gaussian_mixture.py index ef13457d1caae..f0da500478917 100644 --- a/sklearn/mixture/tests/test_gaussian_mixture.py +++ b/sklearn/mixture/tests/test_gaussian_mixture.py @@ -31,12 +31,12 @@ _estimate_gaussian_parameters, ) from sklearn.utils._array_api import ( - _convert_to_numpy, - get_namespace, - yield_namespace_device_dtype_combinations, + device as array_api_device, ) from sklearn.utils._array_api import ( - device as array_api_device, + get_namespace, + move_to, + yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import ( _array_api_for_tests, @@ -1568,40 +1568,41 @@ def test_gaussian_mixture_array_api_compliance( increased_rtol = 1e-3 if dtype_name == "float32" else 1e-7 # Check fitted attributes - assert_allclose(gmm.means_, _convert_to_numpy(gmm_xp.means_, xp=xp)) - assert_allclose(gmm.weights_, _convert_to_numpy(gmm_xp.weights_, xp=xp)) + assert_allclose(gmm.means_, move_to(gmm_xp.means_, xp=np, device="cpu")) + assert_allclose(gmm.weights_, move_to(gmm_xp.weights_, xp=np, device="cpu")) assert_allclose( gmm.covariances_, - _convert_to_numpy(gmm_xp.covariances_, xp=xp), + move_to(gmm_xp.covariances_, xp=np, device="cpu"), atol=increased_atol, rtol=increased_rtol, ) assert_allclose( gmm.precisions_cholesky_, - _convert_to_numpy(gmm_xp.precisions_cholesky_, xp=xp), + move_to(gmm_xp.precisions_cholesky_, xp=np, device="cpu"), atol=increased_atol, rtol=increased_rtol, ) assert_allclose( gmm.precisions_, - _convert_to_numpy(gmm_xp.precisions_, xp=xp), + move_to(gmm_xp.precisions_, xp=np, device="cpu"), atol=increased_atol, rtol=increased_rtol, ) # Check methods assert ( - adjusted_rand_score(gmm.predict(X), _convert_to_numpy(predict_xp, xp=xp)) > 0.95 + adjusted_rand_score(gmm.predict(X), move_to(predict_xp, xp=np, device="cpu")) + > 0.95 ) assert_allclose( gmm.predict_proba(X), - _convert_to_numpy(predict_proba_xp, xp=xp), + move_to(predict_proba_xp, xp=np, device="cpu"), rtol=increased_rtol, atol=increased_atol, ) assert_allclose( gmm.score_samples(X), - _convert_to_numpy(score_samples_xp, xp=xp), + move_to(score_samples_xp, xp=np, device="cpu"), rtol=increased_rtol, ) # comparing Python float so need explicit rtol when X has dtype float32 @@ -1610,8 +1611,10 @@ def test_gaussian_mixture_array_api_compliance( assert_allclose(gmm.bic(X), bic_xp, rtol=default_rtol) sample_X, sample_y = gmm.sample(10) # generated samples are float64 so need explicit rtol when X has dtype float32 - assert_allclose(sample_X, _convert_to_numpy(sample_X_xp, xp=xp), rtol=default_rtol) - assert_allclose(sample_y, _convert_to_numpy(sample_y_xp, xp=xp)) + assert_allclose( + sample_X, move_to(sample_X_xp, xp=np, device="cpu"), rtol=default_rtol + ) + assert_allclose(sample_y, move_to(sample_y_xp, xp=np, device="cpu")) @skip_if_array_api_compat_not_configured diff --git a/sklearn/model_selection/_split.py b/sklearn/model_selection/_split.py index 4a63e262b1af8..3b1dfefc36038 100644 --- a/sklearn/model_selection/_split.py +++ b/sklearn/model_selection/_split.py @@ -25,7 +25,6 @@ metadata_routing, ) from sklearn.utils._array_api import ( - _convert_to_numpy, get_namespace, get_namespace_and_device, move_to, @@ -780,7 +779,7 @@ def _make_test_folds(self, X, y=None): # we need the following explicit conversion: xp, is_array_api = get_namespace(y) if is_array_api: - y = _convert_to_numpy(y, xp) + y = move_to(y, xp=np, device="cpu") else: y = np.asarray(y) type_of_target_y = type_of_target(y) @@ -2329,7 +2328,7 @@ def _iter_indices(self, X, y, groups=None): # `y` is probably never a very large array, which means that converting it # should be cheap xp, _ = get_namespace(y) - y = _convert_to_numpy(y, xp=xp) + y = move_to(y, xp=np, device="cpu") if y.ndim == 2: # for multi-label y, map each distinct row to a string repr diff --git a/sklearn/model_selection/_validation.py b/sklearn/model_selection/_validation.py index d1e5693a45f29..827aa7b9e5d49 100644 --- a/sklearn/model_selection/_validation.py +++ b/sklearn/model_selection/_validation.py @@ -27,7 +27,6 @@ from sklearn.preprocessing import LabelEncoder from sklearn.utils import Bunch, _safe_indexing, check_random_state, indexable from sklearn.utils._array_api import ( - _convert_to_numpy, device, get_namespace, get_namespace_and_device, @@ -1320,7 +1319,7 @@ def _fit_and_predict(estimator, X, y, train, test, fit_params, method): # A 2D y array should be a binary label indicator matrix xp, _ = get_namespace(X, y) n_classes = ( - len(set(_convert_to_numpy(y, xp=xp))) if y.ndim == 1 else y.shape[1] + len(set(move_to(y, xp=np, device="cpu"))) if y.ndim == 1 else y.shape[1] ) predictions = _enforce_prediction_order( estimator.classes_, predictions, n_classes, method diff --git a/sklearn/model_selection/tests/test_split.py b/sklearn/model_selection/tests/test_split.py index d9f4eadf37a4b..43f6da90a873a 100644 --- a/sklearn/model_selection/tests/test_split.py +++ b/sklearn/model_selection/tests/test_split.py @@ -42,12 +42,12 @@ from sklearn.svm import SVC from sklearn.tests.metadata_routing_common import assert_request_is_empty from sklearn.utils._array_api import ( - _convert_to_numpy, - get_namespace, - yield_namespace_device_dtype_combinations, + device as array_api_device, ) from sklearn.utils._array_api import ( - device as array_api_device, + get_namespace, + move_to, + yield_namespace_device_dtype_combinations, ) from sklearn.utils._mocking import MockDataFrame from sklearn.utils._testing import ( @@ -1398,11 +1398,11 @@ def test_array_api_train_test_split( assert y_test_xp.dtype == y_xp.dtype assert_allclose( - _convert_to_numpy(X_train_xp, xp=xp), + move_to(X_train_xp, xp=np, device="cpu"), X_train_np, ) assert_allclose( - _convert_to_numpy(X_test_xp, xp=xp), + move_to(X_test_xp, xp=np, device="cpu"), X_test_np, ) diff --git a/sklearn/model_selection/tests/test_validation.py b/sklearn/model_selection/tests/test_validation.py index 76529c51d13de..26a82d510365b 100644 --- a/sklearn/model_selection/tests/test_validation.py +++ b/sklearn/model_selection/tests/test_validation.py @@ -84,7 +84,7 @@ from sklearn.utils import shuffle from sklearn.utils._array_api import ( _atol_for_type, - _convert_to_numpy, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._mocking import CheckingClassifier, MockDataFrame @@ -2741,5 +2741,5 @@ def test_cross_val_predict_array_api_compliance( pred_np = cross_val_predict(estimator, X_np, y_np, cv=cv) assert_allclose( - _convert_to_numpy(pred_xp, xp), pred_np, atol=_atol_for_type(dtype_name) + move_to(pred_xp, xp=np, device="cpu"), pred_np, atol=_atol_for_type(dtype_name) ) diff --git a/sklearn/naive_bayes.py b/sklearn/naive_bayes.py index 54d8b710623d2..93806ce7ccb7d 100644 --- a/sklearn/naive_bayes.py +++ b/sklearn/naive_bayes.py @@ -18,12 +18,12 @@ from sklearn.preprocessing import LabelBinarizer, binarize, label_binarize from sklearn.utils._array_api import ( _average, - _convert_to_numpy, _find_matching_floating_dtype, _isin, _logsumexp, get_namespace, get_namespace_and_device, + move_to, size, ) from sklearn.utils._param_validation import Interval @@ -113,7 +113,7 @@ def predict(self, X): jll = self._joint_log_likelihood(X) pred_indices = xp.argmax(jll, axis=1) if isinstance(self.classes_[0], str): - pred_indices = _convert_to_numpy(pred_indices, xp=xp) + pred_indices = move_to(pred_indices, xp=np, device="cpu") return self.classes_[pred_indices] def predict_log_proba(self, X): diff --git a/sklearn/preprocessing/_label.py b/sklearn/preprocessing/_label.py index 2851ecf44a909..dd7f65c752059 100644 --- a/sklearn/preprocessing/_label.py +++ b/sklearn/preprocessing/_label.py @@ -13,7 +13,6 @@ from sklearn.base import BaseEstimator, TransformerMixin, _fit_context from sklearn.utils import _align_api_if_sparse, column_or_1d from sklearn.utils._array_api import ( - _convert_to_numpy, _find_matching_floating_dtype, _is_numpy_namespace, _isin, @@ -21,6 +20,7 @@ get_namespace, get_namespace_and_device, indexing_dtype, + move_to, xpx, ) from sklearn.utils._encode import _encode, _unique @@ -636,9 +636,9 @@ def label_binarize(y, *, classes, neg_label=0, pos_label=1, sparse_output=False) # Use NumPy to construct the sparse matrix of one-hot labels Y = sp.csr_array( ( - _convert_to_numpy(data, xp=xp), - _convert_to_numpy(indices, xp=xp), - _convert_to_numpy(indptr, xp=xp), + move_to(data, xp=np, device="cpu"), + move_to(indices, xp=np, device="cpu"), + move_to(indptr, xp=np, device="cpu"), ), shape=(n_samples, n_classes), ) diff --git a/sklearn/preprocessing/tests/test_data.py b/sklearn/preprocessing/tests/test_data.py index 704ac326c8b52..e4a7f1652510c 100644 --- a/sklearn/preprocessing/tests/test_data.py +++ b/sklearn/preprocessing/tests/test_data.py @@ -39,7 +39,7 @@ from sklearn.svm import SVR from sklearn.utils import gen_batches, shuffle from sklearn.utils._array_api import ( - _convert_to_numpy, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import ( @@ -202,8 +202,8 @@ def test_standard_scaler_sample_weight_array_api( scaler_w_xp = StandardScaler() with config_context(array_api_dispatch=True): scaler_w_xp.fit(Xw_xp, yw_xp, sample_weight=sample_weight_xp) - w_mean = _convert_to_numpy(scaler_w_xp.mean_, xp=xp) - w_var = _convert_to_numpy(scaler_w_xp.var_, xp=xp) + w_mean = move_to(scaler_w_xp.mean_, xp=np, device="cpu") + w_var = move_to(scaler_w_xp.var_, xp=np, device="cpu") assert_allclose(scaler_w.mean_, w_mean) assert_allclose(scaler_w.var_, w_var) @@ -212,8 +212,8 @@ def test_standard_scaler_sample_weight_array_api( scaler_xp = StandardScaler() with config_context(array_api_dispatch=True): scaler_xp.fit(X_xp, y_xp) - uw_mean = _convert_to_numpy(scaler_xp.mean_, xp=xp) - uw_var = _convert_to_numpy(scaler_xp.var_, xp=xp) + uw_mean = move_to(scaler_xp.mean_, xp=np, device="cpu") + uw_var = move_to(scaler_xp.var_, xp=np, device="cpu") assert_allclose(scaler.mean_, uw_mean) assert_allclose(scaler.var_, uw_var) @@ -223,8 +223,8 @@ def test_standard_scaler_sample_weight_array_api( assert_allclose(uw_var, w_var) with config_context(array_api_dispatch=True): assert_allclose( - _convert_to_numpy(scaler_xp.transform(X_test_xp), xp=xp), - _convert_to_numpy(scaler_w_xp.transform(X_test_xp), xp=xp), + move_to(scaler_xp.transform(X_test_xp), xp=np, device="cpu"), + move_to(scaler_w_xp.transform(X_test_xp), xp=np, device="cpu"), ) @@ -2121,7 +2121,7 @@ def test_binarizer_array_api_int(array_namespace, device_name, dtype_name): binarized_np = Binarizer(threshold=2.5).fit_transform(X_np) with config_context(array_api_dispatch=True): binarized_xp = Binarizer(threshold=2.5).fit_transform(X_xp) - assert_array_equal(_convert_to_numpy(binarized_xp, xp), binarized_np) + assert_array_equal(move_to(binarized_xp, xp=np, device="cpu"), binarized_np) def test_center_kernel(): diff --git a/sklearn/preprocessing/tests/test_label.py b/sklearn/preprocessing/tests/test_label.py index cbe08fa92f7d3..6bb6e3e42d7c1 100644 --- a/sklearn/preprocessing/tests/test_label.py +++ b/sklearn/preprocessing/tests/test_label.py @@ -12,9 +12,9 @@ label_binarize, ) from sklearn.utils._array_api import ( - _convert_to_numpy, _is_numpy_namespace, get_namespace, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import ( @@ -283,14 +283,16 @@ def test_label_binarizer_array_api_compliance( assert get_namespace(binarized)[0].__name__ == xp.__name__ assert "int" in str(binarized.dtype) assert array_api_device(binarized) == array_api_device(y) - assert_array_equal(_convert_to_numpy(binarized, xp=xp), np.asarray(expected)) + assert_array_equal( + move_to(binarized, xp=np, device="cpu"), np.asarray(expected) + ) fitted_classes = lb_xp.classes_ assert get_namespace(fitted_classes)[0].__name__ == xp.__name__ assert array_api_device(fitted_classes) == array_api_device(y) assert "int" in str(fitted_classes.dtype) assert_array_equal( - _convert_to_numpy(fitted_classes, xp=xp), np.asarray(classes) + move_to(fitted_classes, xp=np, device="cpu"), np.asarray(classes) ) expected_xp = xp.asarray(expected, device=device) @@ -299,7 +301,8 @@ def test_label_binarizer_array_api_compliance( assert "int" in str(binarized_inverse.dtype) assert array_api_device(binarized_inverse) == array_api_device(y) assert_array_equal( - _convert_to_numpy(binarized_inverse, xp=xp), _convert_to_numpy(y, xp=xp) + move_to(binarized_inverse, xp=np, device="cpu"), + move_to(y, xp=np, device="cpu"), ) @@ -798,7 +801,7 @@ def test_label_binarize_array_api_compliance( assert get_namespace(binarized)[0].__name__ == xp.__name__ assert array_api_device(binarized) == array_api_device(y) assert "int" in str(binarized.dtype) - assert_array_equal(_convert_to_numpy(binarized, xp=xp), expected) + assert_array_equal(move_to(binarized, xp=np, device="cpu"), expected) if not xp_is_numpy and not numeric_dtype: msg = "`classes` contains unsupported dtype for array API " @@ -868,9 +871,11 @@ def test_label_encoder_array_api_compliance( assert get_namespace(xp_transformed)[0].__name__ == xp.__name__ assert get_namespace(xp_inv_transformed)[0].__name__ == xp.__name__ assert get_namespace(xp_label.classes_)[0].__name__ == xp.__name__ - assert_array_equal(_convert_to_numpy(xp_transformed, xp), np_transformed) - assert_array_equal(_convert_to_numpy(xp_inv_transformed, xp), y) - assert_array_equal(_convert_to_numpy(xp_label.classes_, xp), np_label.classes_) + assert_array_equal(move_to(xp_transformed, xp=np, device="cpu"), np_transformed) + assert_array_equal(move_to(xp_inv_transformed, xp=np, device="cpu"), y) + assert_array_equal( + move_to(xp_label.classes_, xp=np, device="cpu"), np_label.classes_ + ) xp_label = LabelEncoder() np_label = LabelEncoder() @@ -878,5 +883,7 @@ def test_label_encoder_array_api_compliance( np_transformed = np_label.fit_transform(y) assert get_namespace(xp_transformed)[0].__name__ == xp.__name__ assert get_namespace(xp_label.classes_)[0].__name__ == xp.__name__ - assert_array_equal(_convert_to_numpy(xp_transformed, xp), np_transformed) - assert_array_equal(_convert_to_numpy(xp_label.classes_, xp), np_label.classes_) + assert_array_equal(move_to(xp_transformed, xp=np, device="cpu"), np_transformed) + assert_array_equal( + move_to(xp_label.classes_, xp=np, device="cpu"), np_label.classes_ + ) diff --git a/sklearn/preprocessing/tests/test_polynomial.py b/sklearn/preprocessing/tests/test_polynomial.py index 512fc9f342462..5b0de52d8a7ea 100644 --- a/sklearn/preprocessing/tests/test_polynomial.py +++ b/sklearn/preprocessing/tests/test_polynomial.py @@ -20,9 +20,9 @@ _get_sizeof_LARGEST_INT_t, ) from sklearn.utils._array_api import ( - _convert_to_numpy, _is_numpy_namespace, get_namespace, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import ( @@ -1363,7 +1363,7 @@ def test_polynomial_features_array_api_compliance( ).fit(X_xp) out_np = tf_np.transform(X_np) out_xp = tf_xp.transform(X_xp) - assert_allclose(_convert_to_numpy(out_xp, xp=xp), out_np) + assert_allclose(move_to(out_xp, xp=np, device="cpu"), out_np) assert get_namespace(out_xp)[0].__name__ == xp.__name__ assert array_api_device(out_xp) == array_api_device(X_xp) assert out_xp.dtype == X_xp.dtype diff --git a/sklearn/tests/test_calibration.py b/sklearn/tests/test_calibration.py index 9ec27e4f01a9c..f64d026b48ebb 100644 --- a/sklearn/tests/test_calibration.py +++ b/sklearn/tests/test_calibration.py @@ -48,12 +48,12 @@ from sklearn.svm import LinearSVC from sklearn.tree import DecisionTreeClassifier from sklearn.utils._array_api import ( - _convert_to_numpy, - get_namespace, - yield_namespace_device_dtype_combinations, + device as array_api_device, ) from sklearn.utils._array_api import ( - device as array_api_device, + get_namespace, + move_to, + yield_namespace_device_dtype_combinations, ) from sklearn.utils._mocking import CheckingClassifier from sklearn.utils._tags import get_tags @@ -1281,12 +1281,12 @@ def test_temperature_scaling_array_api_compliance( assert calibrator_xp.beta_.dtype == X_cal_xp.dtype assert array_api_device(calibrator_xp.beta_) == array_api_device(X_cal_xp) assert_allclose( - _convert_to_numpy(calibrator_xp.beta_, xp=xp), + move_to(calibrator_xp.beta_, xp=np, device="cpu"), calibrator_np.beta_, rtol=rtol, ) pred_xp = cal_clf_xp.predict(X_train_xp) - assert_allclose(_convert_to_numpy(pred_xp, xp=xp), pred_np) + assert_allclose(move_to(pred_xp, xp=np, device="cpu"), pred_np) @pytest.mark.parametrize("ensemble", [False, True]) @@ -1352,7 +1352,7 @@ def test_temperature_scaling_array_api_with_str_y_estimator_not_prefit( assert calibrator_xp.beta_.dtype == X_xp.dtype assert array_api_device(calibrator_xp.beta_) == array_api_device(X_xp) assert_allclose( - _convert_to_numpy(calibrator_xp.beta_, xp=xp), + move_to(calibrator_xp.beta_, xp=np, device="cpu"), calibrator_np.beta_, rtol=rtol, ) diff --git a/sklearn/tests/test_kernel_approximation.py b/sklearn/tests/test_kernel_approximation.py index 4de61d14678c2..d37314a31bee1 100644 --- a/sklearn/tests/test_kernel_approximation.py +++ b/sklearn/tests/test_kernel_approximation.py @@ -20,8 +20,8 @@ ) from sklearn.utils._array_api import ( _atol_for_type, - _convert_to_numpy, get_namespace_and_device, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import ( @@ -377,7 +377,7 @@ def test_nystroem_approximation_array_api( with config_context(array_api_dispatch=True): X_xp_transformed = nystroem.fit_transform(X_xp) - X_xp_transformed_np = _convert_to_numpy(X_xp_transformed, xp=xp) + X_xp_transformed_np = move_to(X_xp_transformed, xp=np, device="cpu") for attribute_name in ["components_", "normalization_"]: xp_attr, _, device_attr = get_namespace_and_device( diff --git a/sklearn/tests/test_naive_bayes.py b/sklearn/tests/test_naive_bayes.py index 99dd78ce82884..83c7913d907d9 100644 --- a/sklearn/tests/test_naive_bayes.py +++ b/sklearn/tests/test_naive_bayes.py @@ -16,11 +16,11 @@ MultinomialNB, ) from sklearn.utils._array_api import ( - _convert_to_numpy, - yield_namespace_device_dtype_combinations, + device as array_api_device, ) from sklearn.utils._array_api import ( - device as array_api_device, + move_to, + yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import ( _array_api_for_tests, @@ -1029,23 +1029,23 @@ def test_gnb_array_api_compliance( np_attr = getattr(clf_np, fitted_attr) assert xp_attr.dtype == X_xp.dtype assert array_api_device(xp_attr) == array_api_device(X_xp) - assert_allclose(_convert_to_numpy(xp_attr, xp=xp), np_attr) + assert_allclose(move_to(xp_attr, xp=np, device="cpu"), np_attr) y_pred_xp = clf_xp.predict(X_xp) if not use_str_y: assert array_api_device(y_pred_xp) == array_api_device(X_xp) - y_pred_xp = _convert_to_numpy(y_pred_xp, xp=xp) + y_pred_xp = move_to(y_pred_xp, xp=np, device="cpu") assert_array_equal(y_pred_xp, y_pred_np) assert y_pred_xp.dtype == y_pred_np.dtype y_pred_proba_xp = clf_xp.predict_proba(X_xp) assert y_pred_proba_xp.dtype == X_xp.dtype assert array_api_device(y_pred_proba_xp) == array_api_device(X_xp) - assert_allclose(_convert_to_numpy(y_pred_proba_xp, xp=xp), y_pred_proba_np) + assert_allclose(move_to(y_pred_proba_xp, xp=np, device="cpu"), y_pred_proba_np) y_pred_log_proba_xp = clf_xp.predict_log_proba(X_xp) assert y_pred_log_proba_xp.dtype == X_xp.dtype assert array_api_device(y_pred_log_proba_xp) == array_api_device(X_xp) assert_allclose( - _convert_to_numpy(y_pred_log_proba_xp, xp=xp), y_pred_log_proba_np + move_to(y_pred_log_proba_xp, xp=np, device="cpu"), y_pred_log_proba_np ) diff --git a/sklearn/tests/test_pipeline.py b/sklearn/tests/test_pipeline.py index 9eba2f04ec49a..6d7c3b4c23fa1 100644 --- a/sklearn/tests/test_pipeline.py +++ b/sklearn/tests/test_pipeline.py @@ -51,8 +51,8 @@ from sklearn.utils import get_tags from sklearn.utils._array_api import ( _atol_for_type, - _convert_to_numpy, get_namespace_and_device, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._metadata_requests import COMPOSITE_METHODS, METHODS @@ -1984,7 +1984,7 @@ def test_feature_union_array_api_compliance(array_namespace, device_name, dtype_ with config_context(array_api_dispatch=True): X_xp_transformed = union.fit_transform(X_xp) - X_xp_transformed_np = _convert_to_numpy(X_xp_transformed, xp=xp) + X_xp_transformed_np = move_to(X_xp_transformed, xp=np, device="cpu") for name, trans in union.transformer_list: for attr in ["components_", "normalization_"]: diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index b6cd21f6cf7cb..e1f2ee9d5516d 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -857,9 +857,8 @@ def _median(x, axis=None, keepdims=False, xp=None): if hasattr(xp, "median"): return xp.median(x, axis=axis, keepdims=keepdims) - # Intended mostly for array-api-strict (which as no "median", as per the spec) - # as `_convert_to_numpy` does not necessarily work for all array types. - x_np = _convert_to_numpy(x, xp=xp) + # Intended mostly for array-api-strict (which has no "median", as per the spec). + x_np = move_to(x, xp=numpy, device="cpu") return xp.asarray(numpy.median(x_np, axis=axis, keepdims=keepdims), device=device) @@ -985,7 +984,15 @@ def _ravel(array, xp=None): def _convert_to_numpy(array, xp): - """Convert X into a NumPy ndarray on the CPU.""" + """Convert X into a NumPy ndarray on the CPU. + + This function uses library-specific methods to convert the array to a NumPy + ndarray on the CPU. It is only meant as a fallback when move_to fails to use the + DLPACK protocol. + + This function is not meant to be called directly and + `move_to(array, xp=np, device="cpu")` should be used instead. + """ if _is_xp_namespace(xp, "torch"): return array.cpu().numpy() elif _is_xp_namespace(xp, "cupy"): # pragma: nocover @@ -1181,9 +1188,9 @@ def _bincount(array, weights=None, minlength=0, xp=None): if hasattr(xp, "bincount"): return xp.bincount(array, weights=weights, minlength=minlength) - array_np = _convert_to_numpy(array, xp=xp) + array_np = move_to(array, xp=numpy, device="cpu") if weights is not None: - weights_np = _convert_to_numpy(weights, xp=xp) + weights_np = move_to(weights, xp=numpy, device="cpu") else: weights_np = None bin_out = numpy.bincount(array_np, weights=weights_np, minlength=minlength) diff --git a/sklearn/utils/class_weight.py b/sklearn/utils/class_weight.py index 2c7a23cea23cc..76e06e92e9820 100644 --- a/sklearn/utils/class_weight.py +++ b/sklearn/utils/class_weight.py @@ -8,11 +8,10 @@ from sklearn.utils._array_api import ( _bincount, - _convert_to_numpy, _is_numpy_namespace, _isin, - get_namespace, get_namespace_and_device, + move_to, size, ) from sklearn.utils._param_validation import StrOptions, validate_params @@ -75,7 +74,9 @@ def compute_class_weight(class_weight, *, classes, y, sample_weight=None): xp, _, device_ = get_namespace_and_device(y, classes) unique_y = xp.unique_values(y) - if set(_convert_to_numpy(unique_y, xp)) - set(_convert_to_numpy(classes, xp)): + if set(move_to(unique_y, xp=np, device="cpu")) - set( + move_to(classes, xp=np, device="cpu") + ): raise ValueError("classes should include all valid labels that can be in y") if class_weight is None or len(class_weight) == 0: # uniform class weights @@ -88,8 +89,7 @@ def compute_class_weight(class_weight, *, classes, y, sample_weight=None): raise ValueError("classes should have valid labels that are in y") if _is_numpy_namespace(xp) and sample_weight is not None: - xp_sw, _ = get_namespace(sample_weight) - sample_weight = _convert_to_numpy(sample_weight, xp_sw) + sample_weight = move_to(sample_weight, xp=np, device="cpu") sample_weight = _check_sample_weight(sample_weight, y) weighted_class_counts = _bincount(y_ind, weights=sample_weight, xp=xp) diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index 2c7c3656c3157..4ac4b6a553d70 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -62,8 +62,8 @@ from sklearn.utils import _safe_indexing, shuffle from sklearn.utils._array_api import ( _atol_for_type, - _convert_to_numpy, get_namespace, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import device as array_device @@ -1129,7 +1129,7 @@ def check_array_api_input( with config_context(array_api_dispatch=True): assert array_device(est_xp_param) == array_device(X_xp) - est_xp_param_np = _convert_to_numpy(est_xp_param, xp=xp) + est_xp_param_np = move_to(est_xp_param, xp=np, device="cpu") if check_values: assert_allclose( attribute, @@ -1222,7 +1222,7 @@ def check_array_api_input( with config_context(array_api_dispatch=True): assert array_device(result_xp) == array_device(X_xp) - result_xp_np = _convert_to_numpy(result_xp, xp=xp) + result_xp_np = move_to(result_xp, xp=np, device="cpu") if check_values: assert_allclose( result, @@ -1249,7 +1249,7 @@ def check_array_api_input( with config_context(array_api_dispatch=True): assert array_device(result_xp) == array_device(X_xp) - inverse_result_xp_np = _convert_to_numpy(inverse_result_xp, xp=xp) + inverse_result_xp_np = move_to(inverse_result_xp, xp=np, device="cpu") if check_values: assert_allclose( inverse_result, diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index 9ed3b2014c335..0203fd45e2a5c 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -255,7 +255,7 @@ def test_average( # https://github.com/numpy/numpy/issues/26850 assert array_api_device(array_in) == array_api_device(result) - result = _convert_to_numpy(result, xp) + result = move_to(result, xp=numpy, device="cpu") assert_allclose(result, expected, atol=_atol_for_type(dtype_name)) @@ -438,7 +438,7 @@ def test_nan_reductions(library, X, reduction, expected): with config_context(array_api_dispatch=True): result = reduction(xp.asarray(X)) - result = _convert_to_numpy(result, xp) + result = move_to(result, xp=numpy, device="cpu") assert_allclose(result, expected) @@ -454,7 +454,7 @@ def test_ravel(namespace, device_name, dtype_name): with config_context(array_api_dispatch=True): result = _ravel(array_xp) - result = _convert_to_numpy(result, xp) + result = move_to(result, xp=numpy, device="cpu") expected = numpy.ravel(array, order="C") assert_allclose(expected, result) @@ -591,7 +591,7 @@ def test_isin( invert=invert, ) - assert_array_equal(_convert_to_numpy(result, xp=xp), expected) + assert_array_equal(move_to(result, xp=numpy, device="cpu"), expected) @pytest.mark.skipif( @@ -659,7 +659,7 @@ def test_count_nonzero( array_xp, axis=axis, sample_weight=sample_weight, xp=xp, device=device ) - assert_allclose(_convert_to_numpy(result, xp=xp), expected) + assert_allclose(move_to(result, xp=numpy, device="cpu"), expected) if np_version < parse_version("2.0.0") or np_version >= parse_version("2.1.0"): # NumPy 2.0 has a problem with the device attribute of scalar arrays: @@ -745,7 +745,7 @@ def test_fill_diagonal(array, array_namespace, device_name, dtype_name): with config_context(array_api_dispatch=True): _fill_diagonal(array_xp, value=1, xp=xp) - assert_array_equal(_convert_to_numpy(array_xp, xp=xp), array_np) + assert_array_equal(move_to(array_xp, xp=numpy, device="cpu"), array_np) @pytest.mark.parametrize( @@ -765,7 +765,7 @@ def test_add_to_diagonal(array_namespace, device_name, dtype_name): with config_context(array_api_dispatch=True): _fill_diagonal(array_xp, value=add_val, xp=xp) - assert_array_equal(_convert_to_numpy(array_xp, xp=xp), array_np) + assert_array_equal(move_to(array_xp, xp=numpy, device="cpu"), array_np) @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) @@ -810,7 +810,7 @@ def test_median(namespace, device_name, dtype_name, axis): # part of the Array API spec assert get_namespace(result_xp)[0] == xp assert result_xp.device == X_xp.device - assert_allclose(result_np, _convert_to_numpy(result_xp, xp=xp)) + assert_allclose(result_np, move_to(result_xp, xp=numpy, device="cpu")) @pytest.mark.parametrize( @@ -825,7 +825,7 @@ def test_expit_logit(namespace, device_name, dtype_name): x_np = numpy.linspace(-20, 20, 1000).astype(dtype_name) x_xp = xp.asarray(x_np, device=device) assert_allclose( - _convert_to_numpy(_expit(x_xp), xp=xp), + move_to(_expit(x_xp), xp=numpy, device="cpu"), expit(x_np), rtol=rtol, ) @@ -833,7 +833,7 @@ def test_expit_logit(namespace, device_name, dtype_name): x_np = numpy.linspace(0, 1, 1000).astype(dtype_name) x_xp = xp.asarray(x_np, device=device) assert_allclose( - _convert_to_numpy(_logit(x_xp), xp=xp), + move_to(_logit(x_xp), xp=numpy, device="cpu"), logit(x_np), rtol=rtol, ) @@ -871,7 +871,7 @@ def test_logsumexp_like_scipy_logsumexp(array_namespace, device_name, dtype_name with config_context(array_api_dispatch=True): res_xp = _logsumexp(array_xp, axis=axis) - res_xp = _convert_to_numpy(res_xp, xp) + res_xp = move_to(res_xp, xp=numpy, device="cpu") assert_allclose(res_np, res_xp, rtol=rtol) # Test with NaNs and +np.inf @@ -891,7 +891,7 @@ def test_logsumexp_like_scipy_logsumexp(array_namespace, device_name, dtype_name with config_context(array_api_dispatch=True): res_xp_2 = _logsumexp(array_xp_2, axis=axis) - res_xp_2 = _convert_to_numpy(res_xp_2, xp) + res_xp_2 = move_to(res_xp_2, xp=numpy, device="cpu") assert_allclose(res_np_2, res_xp_2, rtol=rtol) diff --git a/sklearn/utils/tests/test_extmath.py b/sklearn/utils/tests/test_extmath.py index db7987b4498cb..3e9e27e50c589 100644 --- a/sklearn/utils/tests/test_extmath.py +++ b/sklearn/utils/tests/test_extmath.py @@ -14,9 +14,9 @@ from sklearn.utils import gen_batches from sklearn.utils._arpack import _init_arpack_v0 from sklearn.utils._array_api import ( - _convert_to_numpy, _max_precision_float_dtype, get_namespace, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import ( @@ -730,8 +730,8 @@ def test_incremental_weighted_mean_and_variance_array_api( assert array_device(var_xp) == array_device(X_xp) assert var_xp.dtype == _max_precision_float_dtype(xp, device=device) - mean_xp = _convert_to_numpy(mean_xp, xp=xp) - var_xp = _convert_to_numpy(var_xp, xp=xp) + mean_xp = move_to(mean_xp, xp=np, device="cpu") + var_xp = move_to(var_xp, xp=np, device="cpu") assert_allclose(mean, mean_xp) assert_allclose(var, var_xp) @@ -1122,9 +1122,9 @@ def test_randomized_svd_array_api_compliance(array_namespace, device_name, dtype assert get_namespace(s_xp)[0].__name__ == xp.__name__ assert get_namespace(vt_xp)[0].__name__ == xp.__name__ - assert_allclose(_convert_to_numpy(u_xp, xp), u_np, atol=atol) - assert_allclose(_convert_to_numpy(s_xp, xp), s_np, atol=atol) - assert_allclose(_convert_to_numpy(vt_xp, xp), vt_np, atol=atol) + assert_allclose(move_to(u_xp, xp=np, device="cpu"), u_np, atol=atol) + assert_allclose(move_to(s_xp, xp=np, device="cpu"), s_np, atol=atol) + assert_allclose(move_to(vt_xp, xp=np, device="cpu"), vt_np, atol=atol) @pytest.mark.parametrize( @@ -1148,4 +1148,4 @@ def test_randomized_range_finder_array_api_compliance( Q_xp = randomized_range_finder(X_xp, size=size, n_iter=n_iter, random_state=0) assert get_namespace(Q_xp)[0].__name__ == xp.__name__ - assert_allclose(_convert_to_numpy(Q_xp, xp), Q_np, atol=atol) + assert_allclose(move_to(Q_xp, xp=np, device="cpu"), Q_np, atol=atol) diff --git a/sklearn/utils/tests/test_indexing.py b/sklearn/utils/tests/test_indexing.py index 958cca77d8323..27bca5968f21d 100644 --- a/sklearn/utils/tests/test_indexing.py +++ b/sklearn/utils/tests/test_indexing.py @@ -10,12 +10,11 @@ from sklearn.externals._packaging.version import parse as parse_version from sklearn.utils import _safe_indexing, resample, shuffle from sklearn.utils._array_api import ( - _convert_to_numpy, - move_to, - yield_namespace_device_dtype_combinations, + device as array_api_device, ) from sklearn.utils._array_api import ( - device as array_api_device, + move_to, + yield_namespace_device_dtype_combinations, ) from sklearn.utils._indexing import ( _determine_key_type, @@ -169,7 +168,7 @@ def test_safe_indexing_array_api_support( assert array_api_device(indexed_array_xp) == array_api_device(array_to_index_xp) assert indexed_array_xp.dtype == array_to_index_xp.dtype - assert_allclose(_convert_to_numpy(indexed_array_xp, xp=xp), expected_result) + assert_allclose(move_to(indexed_array_xp, xp=np, device="cpu"), expected_result) @pytest.mark.parametrize( diff --git a/sklearn/utils/tests/test_stats.py b/sklearn/utils/tests/test_stats.py index 6bfaa48045fc2..fff0d196a7107 100644 --- a/sklearn/utils/tests/test_stats.py +++ b/sklearn/utils/tests/test_stats.py @@ -4,12 +4,12 @@ from pytest import approx from sklearn._config import config_context +from sklearn.utils._array_api import device as array_device from sklearn.utils._array_api import ( - _convert_to_numpy, get_namespace, + move_to, yield_namespace_device_dtype_combinations, ) -from sklearn.utils._array_api import device as array_device from sklearn.utils.estimator_checks import _array_api_for_tests from sklearn.utils.fixes import np_version, parse_version from sklearn.utils.stats import _weighted_percentile @@ -324,7 +324,7 @@ def test_weighted_percentile_array_api_consistency( result_xp = _weighted_percentile(X_xp, weights_xp, percentile) assert array_device(result_xp) == array_device(X_xp) assert get_namespace(result_xp)[0] == get_namespace(X_xp)[0] - result_xp_np = _convert_to_numpy(result_xp, xp=xp) + result_xp_np = move_to(result_xp, xp=np, device="cpu") assert result_xp_np.dtype == result_np.dtype assert result_xp_np.shape == result_np.shape diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 20e3a41880b99..0eefcf9a3cc09 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -34,8 +34,8 @@ deprecated, ) from sklearn.utils._array_api import ( - _convert_to_numpy, _is_numpy_namespace, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._mocking import ( @@ -1608,11 +1608,11 @@ def _check_sample_weight_common(xp): # for check_sample_weight # check None input sample_weight = _check_sample_weight(None, X=xp.ones((5, 2))) - assert_allclose(_convert_to_numpy(sample_weight, xp), np.ones(5)) + assert_allclose(move_to(sample_weight, xp=np, device="cpu"), np.ones(5)) # check numbers input sample_weight = _check_sample_weight(2.0, X=xp.ones((5, 2))) - assert_allclose(_convert_to_numpy(sample_weight, xp), 2 * np.ones(5)) + assert_allclose(move_to(sample_weight, xp=np, device="cpu"), 2 * np.ones(5)) # check wrong number of dimensions with pytest.raises(ValueError, match=r"Sample weights must be 1D array or scalar"): diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index 7ba1c19733621..5cbbbd14b9678 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -23,11 +23,11 @@ ) from sklearn.utils._array_api import ( _asarray_with_order, - _convert_to_numpy, _is_numpy_namespace, _max_precision_float_dtype, get_namespace, get_namespace_and_device, + move_to, ) from sklearn.utils._dataframe import is_pandas_df, is_pandas_df_or_series from sklearn.utils._isfinite import FiniteStatus, cy_isfinite @@ -2598,7 +2598,7 @@ def _check_pos_label_consistency(pos_label, y_true): or xp.all(classes == xp.asarray([1], device=device)) ) ): - classes = _convert_to_numpy(classes, xp=xp) + classes = move_to(classes, xp=np, device="cpu") classes_repr = ", ".join([repr(c) for c in classes.tolist()]) raise ValueError( f"y_true takes value in {{{classes_repr}}} and pos_label is not " From c50ac77e53a2eba7a72325b0ce9ed40fa1a3b551 Mon Sep 17 00:00:00 2001 From: Tim Head <betatim@gmail.com> Date: Wed, 25 Mar 2026 15:22:30 +0100 Subject: [PATCH 306/462] Raise if fit and predict use different array API namespaces or devices (continued) (#33076) Co-authored-by: Jerome Dockes <jerome@dockes.org> Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> Co-authored-by: Omar Salman <omar.salman@arbisoft.com> --- .github/workflows/cuda-ci.yml | 7 + ...a_forge_cuda_array-api_linux-64_conda.lock | 65 +++++---- ...ge_cuda_array-api_linux-64_environment.yml | 1 + .../update_environments_and_lock_files.py | 1 + doc/modules/array_api.rst | 30 +++-- .../array-api/33076.feature.rst | 8 ++ sklearn/discriminant_analysis.py | 11 +- sklearn/linear_model/_base.py | 4 + sklearn/linear_model/_logistic.py | 3 + sklearn/linear_model/tests/test_base.py | 22 ++++ sklearn/model_selection/_search.py | 44 ++++++- sklearn/utils/_array_api.py | 123 +++++++++++++++++- .../utils/_test_common/instance_generator.py | 44 ++++++- sklearn/utils/estimator_checks.py | 64 +++++++++ sklearn/utils/tests/test_array_api.py | 89 ++++++++++++- sklearn/utils/tests/test_estimator_checks.py | 6 +- 16 files changed, 458 insertions(+), 64 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/33076.feature.rst diff --git a/.github/workflows/cuda-ci.yml b/.github/workflows/cuda-ci.yml index 8e2da554f9362..4602a67fdf45f 100644 --- a/.github/workflows/cuda-ci.yml +++ b/.github/workflows/cuda-ci.yml @@ -72,3 +72,10 @@ jobs: SCIPY_ARRAY_API=1 pytest --pyargs sklearn -k 'cuda or cupy' -vl # Run in /home/runner to not load sklearn from the checkout repo working-directory: /home/runner + + - name: Run doctests in doc/modules/array_api.rst + run: | + source "${HOME}/conda/etc/profile.d/conda.sh" + conda activate sklearn + cd doc + SCIPY_ARRAY_API=1 pytest --doctest-modules modules/array_api.rst diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index ccd322f4e6200..d8b6052e3fe2d 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: fe79c472e9c028c3b054f565da29f7c4ae75aa209b99c5d4c71e227962497228 +# input_hash: ae929270db8c178cbc2f0b81101682a5018610a1b61b163166d21e8184d423b6 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/cuda-version-12.9-h4f385c5_3.conda#b6d5d7f1c171cbd228ea06b556cfa859 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 @@ -24,7 +24,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/noarch/libnvptxcompiler-dev_linux-64-12.9.86-ha770c72_2.conda#a66a909acf08924aced622903832a937 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.1-h4922eb0_0.conda#0e6b63a4861d9b63cde30993bfc0846d https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_linux-64-12.9.79-h3f2d84a_0.conda#86e40eb67d83f1a58bdafdd44e5a77c6 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -43,8 +43,8 @@ https://conda.anaconda.org/conda-forge/noarch/cuda-nvcc-dev_linux-64-12.9.86-he9 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-impl-12.9.86-h4bc722e_2.conda#82125dd3c0c4aa009faa00e2829b93d8 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvvm-tools-12.9.86-h4bc722e_2.conda#f9af26e4079adcd72688a8e8dbecb229 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 -https://conda.anaconda.org/conda-forge/linux-64/libattr-2.5.2-hb03c661_1.conda#7e7f0a692eb62b95d3010563e7f963b6 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed +https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499cd8e2d4358986dbe3b30e8fe1bf6a https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb @@ -71,7 +71,6 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-hb03c661_1.conda#9bb149f49de3f322fca007283eaa2725 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.13-h2c9d079_1.conda#3c3d02681058c3d206b562b2e3bc337f https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.2-h8b1a151_0.conda#f16f498641c9e05b645fe65902df661a https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.2.4-h8b1a151_4.conda#c7e3e08b7b1b285524ab9d74162ce40b @@ -98,12 +97,14 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libnvjitlink-12.9.86-hecca717_2.conda#3461b0f2d5cbb7973d361f9e85241d98 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-260.1-h6569c3e_0.conda#5020e400d8f01d9e6a39d559e65060f1 +https://conda.anaconda.org/conda-forge/linux-64/libudev1-260.1-h6569c3e_0.conda#0bcc534980c246af677ed6f118d8c2ef https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -119,7 +120,7 @@ https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98 https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda#996583ea9c796e5b915f7d7580b51ea6 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-hc87160b_2.conda#3a7d90d34895728f0b69107602b6e189 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-hc87160b_0.conda#dde6a3e4fe6bb2ecd2a7050dd1e701fb https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 @@ -127,12 +128,11 @@ https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_ https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 -https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.conda#af0df9bc982b5ed2c67e8f5062d1f8c1 https://conda.anaconda.org/conda-forge/linux-64/libcurand-dev-10.3.10.19-h676940d_1.conda#fc716aaff5af15b80ccbd28b3e67672c https://conda.anaconda.org/conda-forge/linux-64/libcusparse-12.5.10.65-hecca717_2.conda#890ebfaad48c887d3d82847ec9d6bc79 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-openmp_hd680484_4.conda#c0512e4f60d62ccccb4c3c8333b33608 @@ -144,33 +144,33 @@ https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.cond https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 +https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.6.0-h841be55_0.conda#d45136de07e991786e04716c3f70b036 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.11-hf621c6d_0.conda#caf217f88155d551b4a586f2da37941a +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.6.0-h9b893ba_1.conda#cd4946050ecfcb3c6fd09106ae6a261e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.12-h4bacb7b_1.conda#7bc920933e5fb225aba86a788164a8f1 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvcc-impl-12.9.86-h85509e4_2.conda#67458d2685e7503933efa550f3ee40f3 https://conda.anaconda.org/conda-forge/linux-64/cuda-profiler-api-12.9.79-h7938cbb_1.conda#90d09865fb37d11d510444e34ebe6a09 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcublas-dev-12.9.1.4-h676940d_1.conda#f90f4ff087ac29005c6989ea0fb2735a https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.conda#a178a1f3642521f104ecceeefa138d01 https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_1.conda#c5b8ea827c65e5811d61aa49cd0bae9a +https://conda.anaconda.org/conda-forge/linux-64/libcufile-1.14.1.1-hbc026e6_1.conda#cab1818eada3952ed09c8dcbb7c26af7 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2.conda#bb6e31a0daa64ede76fe8d3fff01c06f https://conda.anaconda.org/conda-forge/linux-64/libcusparse-dev-12.5.10.65-hecca717_2.conda#db94469fbd554c107acc3afd0af5d8ec https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-26.02.00-cuda12_260204_c212ab9b.conda#702a98df50c3b8be134516647a217fde -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-260-h6569c3e_0.conda#1db3f7f63f3ce0d0f3c8ea4fe130d5d0 -https://conda.anaconda.org/conda-forge/linux-64/libudev1-260-h6569c3e_0.conda#56bcdcefe1c46ba9d0269338c33bd575 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-openmp_hd77311e_4.conda#525e2455ed342f2aef93c59ac5db2e28 @@ -178,18 +178,19 @@ https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda# https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c +https://conda.anaconda.org/conda-forge/linux-64/ucx-1.20.0-hbe80e26_1.conda#ffdaec09a7c09710040eb9e613f8c531 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h536185d_1.conda#bc645a385e91cd3d9235174fcbd17e25 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.0-hac84f0a_1.conda#9cf66b4abc53e47857afbee27364102b +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h2d2dd48_2.conda#675ea6d90900350b1dcfa8231a5ea2dd +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-he9ea9c5_1.conda#8e77514673f5773b40ff8953583938b6 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.4.3-pyhc364b38_0.conda#3cfe70d38d34a49cfa358435d439375f +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.4.4-pyhc364b38_0.conda#e596a2fd285b8c9561aaf37b65b00e94 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 @@ -203,6 +204,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d +https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/llvmlite-0.44.0-py313hfdae721_2.conda#dd0d7947635c0c524608eab7db55dcc9 @@ -222,7 +224,6 @@ https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0. https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f @@ -237,19 +238,19 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h37c9286_4.conda#e9c44a6e46de739827d2eae25ed2ee32 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h6d69fc9_5.conda#4c5c16bf1133dcfe100f33dd4470998e https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py313h3dea7bd_0.conda#acbda45380f5097ade59014704eb0ba0 +https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.6-py313h929d4db_0.conda#602176b8957b10172dfea675a332d0ac https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py313h3dea7bd_0.conda#e479cfdec38fb69dc81ce8806b5c75f6 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py313h86d8783_1.conda#047e3ea395eab013f918b338fecc19a0 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.0-h6083320_0.conda#71c2c966e17a65b08b995f571310fb9f +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d -https://conda.anaconda.org/conda-forge/linux-64/libcufile-1.14.1.1-hbc026e6_1.conda#cab1818eada3952ed09c8dcbb7c26af7 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f @@ -262,19 +263,18 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.12-h4df99d1_100.conda#3d92938d5b83c49162ade038aab58a59 https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py313h246eb7c_1.conda#8526afdb4ae2d95db733c4188f092f01 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/linux-64/ucx-1.20.0-hbe80e26_1.conda#ffdaec09a7c09710040eb9e613f8c531 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-haf8ea0b_2.conda#6f531ae41a8ac7c69c85130d16585d61 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h4c8aef7_3.conda#798a499cf76e530a992365d557ba5827 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 -https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.6-py313h929d4db_0.conda#602176b8957b10172dfea675a332d0ac +https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.6.0-cuda12_py313hacc9b55_0.conda#1986c17fb0b8184289ea7d6fc8ba4b34 +https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.conda#8d3dbe5292af711edd6df92c68e55a89 https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py313h28b6081_0.conda#fe933a91c19fa88788b4204b6ba67ba2 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_hb019b6b_203.conda#5e373fc37a76270b4454c02cb126ab34 -https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.conda#84cef0ce56c6db53edb3f8b83bdbb364 https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py313h7037e92_0.conda#21f1c403983c8a4e067ba6eec6b878ec @@ -286,34 +286,33 @@ https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda# https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 -https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.6.0-cuda12_py313hacc9b55_0.conda#1986c17fb0b8184289ea7d6fc8ba4b34 -https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.conda#8d3dbe5292af711edd6df92c68e55a89 https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py313h7fc6698_0.conda#41368ea5c4c7c607ac98ecab56833535 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 +https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313hcd51b16_1.conda#745f9c0ffaf06cea2e68e12259ace5b5 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_hb8e8477_203.conda#6cfb64f7fc401f2c7c789214237aea24 +https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f +https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b -https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda#d5a4e013a30dd8dfde9ab39f45aaf9c1 https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_203.conda#969fd0ea1b469425630712ba3513deff -https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f +https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_9_cpu.conda#b3ba3597c481a636fc161185819cf6b1 https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_9_cpu.conda#2dccf1b6cf9dba8857050740dbc0497e -https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py313h98bfbea_0_cpu.conda#d2b771a9050c52941a61a72f2d161c64 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_9_cpu.conda#9c5282b7aaf2261d3dbe5a61d24d5337 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_9_cpu.conda#d5338f154126253750e8ccc539386b92 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py313h98bfbea_0_cpu.conda#d2b771a9050c52941a61a72f2d161c64 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_9_cpu.conda#9c5282b7aaf2261d3dbe5a61d24d5337 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.02.00-cuda12_260204_a2f5a8b7.conda#361cae27e77618c6ba9f943807471f9f https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.02.00-cuda12_py313_260204_c212ab9b.conda#14933b753ec82f9d5a61d7cb4b5e2e71 https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.02.00-cuda12_py313_260204_a2f5a8b7.conda#c46807878ad576379e7be3acc187d13a +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_9_cpu.conda#d5338f154126253750e8ccc539386b92 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py313h78bf25f_0.conda#bd299f66ab2d10d1e03d4148397fe263 diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml index 26e06923e0f90..0a984b9ca6148 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml @@ -30,3 +30,4 @@ dependencies: - cupy - cuvs - array-api-strict + - scipy-doctest diff --git a/build_tools/update_environments_and_lock_files.py b/build_tools/update_environments_and_lock_files.py index 1bd11432d4e8b..94619e7d35bdb 100644 --- a/build_tools/update_environments_and_lock_files.py +++ b/build_tools/update_environments_and_lock_files.py @@ -112,6 +112,7 @@ def remove_from(alist, to_remove): # cuvs is needed for cupyx.scipy.spatial.distance.cdist and friends "cuvs", "array-api-strict", + "scipy-doctest", ], "virtual_package_spec": True, }, diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index a2475e199954f..5f003d0700195 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -89,16 +89,26 @@ The example code snippet below demonstrates how to use `CuPy >>> X_trans.device <CUDA Device 0> -After the model is trained, fitted attributes that are arrays will also be -from the same Array API namespace as the training data. For example, if CuPy's -Array API namespace was used for training, then fitted attributes will be on the -GPU. We provide an experimental `_estimator_with_converted_arrays` utility that -transfers an estimator attributes from Array API to an ndarray:: - - >>> from sklearn.utils._array_api import _estimator_with_converted_arrays - >>> cupy_to_ndarray = lambda array : array.get() - >>> lda_np = _estimator_with_converted_arrays(lda, cupy_to_ndarray) - >>> X_trans = lda_np.transform(X_np) +After the model is trained, fitted attributes that are arrays will also be from +the same Array API namespace as the training data. For example, if CuPy's Array +API namespace was used for training, then fitted attributes will be on the GPU. +Passing data in a different namespace to ``transform`` or ``predict`` is an +error:: + + >>> with config_context(array_api_dispatch=True): + ... lda.transform(X_np) + Traceback (most recent call last): + ... + ValueError: Inputs passed to LinearDiscriminantAnalysis.transform() must use the same namespace and the same device as those passed to fit()... + +We provide ``move_estimator_to`` to transfer an estimator's array attributes +to a different namespace and device:: + + >>> from sklearn.utils._array_api import move_estimator_to, get_namespace_and_device + >>> import numpy as np + >>> lda_np = move_estimator_to(lda, np, device="cpu") + >>> with config_context(array_api_dispatch=True): + ... X_trans = lda_np.transform(X_np) >>> type(X_trans) <class 'numpy.ndarray'> diff --git a/doc/whats_new/upcoming_changes/array-api/33076.feature.rst b/doc/whats_new/upcoming_changes/array-api/33076.feature.rst new file mode 100644 index 0000000000000..8053318f56075 --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/33076.feature.rst @@ -0,0 +1,8 @@ +- :class:`linear_model.LinearRegression`, :class:`linear_model.Ridge`, + :class:`linear_model.RidgeClassifier`, :class:`linear_model.LogisticRegression`, + and :class:`discriminant_analysis.LinearDiscriminantAnalysis` now raise a more + informative error message when arrays passed at fit and prediction time use + different array API namespaces or devices. A new + ``sklearn.utils._array_api.move_estimator_to`` utility is provided to move an + estimator's fitted array attributes to a different namespace and device. + By :user:`Jérôme Dockès <jeromedockes>` and :user:`Tim Head <betatim>`. diff --git a/sklearn/discriminant_analysis.py b/sklearn/discriminant_analysis.py index 02e38d996efba..0fe50e33a5689 100644 --- a/sklearn/discriminant_analysis.py +++ b/sklearn/discriminant_analysis.py @@ -20,7 +20,13 @@ from sklearn.covariance import empirical_covariance, ledoit_wolf, shrunk_covariance from sklearn.linear_model._base import LinearClassifierMixin from sklearn.preprocessing import StandardScaler -from sklearn.utils._array_api import _expit, device, get_namespace, size +from sklearn.utils._array_api import ( + _expit, + check_same_namespace, + device, + get_namespace, + size, +) from sklearn.utils._param_validation import HasMethods, Interval, StrOptions from sklearn.utils.extmath import softmax from sklearn.utils.multiclass import check_classification_targets, unique_labels @@ -749,6 +755,7 @@ def transform(self, X): "transform not implemented for 'lsqr' solver (use 'svd' or 'eigen')." ) check_is_fitted(self) + check_same_namespace(X, self, attribute="coef_", method="transform") X = validate_data(self, X, reset=False) if self.solver == "svd": @@ -772,6 +779,7 @@ def predict_proba(self, X): Estimated probabilities. """ check_is_fitted(self) + check_same_namespace(X, self, attribute="coef_", method="predict_proba") xp, _ = get_namespace(X) decision = self.decision_function(X) if size(self.classes_) == 2: @@ -793,6 +801,7 @@ def predict_log_proba(self, X): C : ndarray of shape (n_samples, n_classes) Estimated log probabilities. """ + check_same_namespace(X, self, attribute="coef_", method="predict_log_proba") xp, _ = get_namespace(X) prediction = self.predict_proba(X) diff --git a/sklearn/linear_model/_base.py b/sklearn/linear_model/_base.py index 1a9b19d803a62..4788b67fde4dc 100644 --- a/sklearn/linear_model/_base.py +++ b/sklearn/linear_model/_base.py @@ -27,6 +27,7 @@ _average, _expit, _is_numpy_namespace, + check_same_namespace, get_namespace, get_namespace_and_device, indexing_dtype, @@ -309,6 +310,7 @@ def predict(self, X): C : array, shape (n_samples,) Returns predicted values. """ + check_same_namespace(X, self, attribute="coef_", method="predict") return self._decision_function(X) def _set_intercept(self, X_offset, y_offset, X_scale=None): @@ -360,6 +362,7 @@ def decision_function(self, X): """ check_is_fitted(self) xp, _ = get_namespace(X) + check_same_namespace(X, self, attribute="coef_", method="decision_function") X = validate_data(self, X, accept_sparse="csr", reset=False) coef_T = self.coef_.T if self.coef_.ndim == 2 else self.coef_ @@ -384,6 +387,7 @@ def predict(self, X): y_pred : ndarray of shape (n_samples,) Vector containing the class labels for each sample. """ + check_same_namespace(X, self, attribute="coef_", method="predict") xp, _ = get_namespace(X) scores = self.decision_function(X) if len(scores.shape) == 1: diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index 1b496e02ada37..a11861448f3c7 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -42,6 +42,7 @@ from sklearn.utils._array_api import ( _is_numpy_namespace, _matching_numpy_dtype, + check_same_namespace, get_namespace, get_namespace_and_device, move_to, @@ -1402,6 +1403,7 @@ def predict_proba(self, X): where classes are ordered as they are in ``self.classes_``. """ check_is_fitted(self) + check_same_namespace(X, self, attribute="coef_", method="predict_proba") is_binary = size(self.classes_) <= 2 if is_binary: @@ -1429,6 +1431,7 @@ def predict_log_proba(self, X): Returns the log-probability of the sample for each class in the model, where classes are ordered as they are in ``self.classes_``. """ + check_same_namespace(X, self, attribute="coef_", method="predict_log_proba") xp, _ = get_namespace(X) return xp.log(self.predict_proba(X)) diff --git a/sklearn/linear_model/tests/test_base.py b/sklearn/linear_model/tests/test_base.py index 2e1d7270abd13..a82171228ac1e 100644 --- a/sklearn/linear_model/tests/test_base.py +++ b/sklearn/linear_model/tests/test_base.py @@ -7,6 +7,7 @@ import pytest from scipy import linalg, sparse +from sklearn import config_context from sklearn.base import BaseEstimator from sklearn.datasets import load_iris, make_regression, make_sparse_uncorrelated from sklearn.linear_model import LinearRegression @@ -17,10 +18,12 @@ make_dataset, ) from sklearn.preprocessing import add_dummy_feature +from sklearn.utils._array_api import get_namespace_and_device, move_estimator_to from sklearn.utils._testing import ( assert_allclose, assert_array_almost_equal, assert_array_equal, + skip_if_array_api_compat_not_configured, ) from sklearn.utils.fixes import ( COO_CONTAINERS, @@ -857,6 +860,25 @@ def test_linear_regression_sample_weight_consistency( assert_allclose(reg1.intercept_, reg2.intercept_) +@skip_if_array_api_compat_not_configured +def test_array_api_move_estimator_to(): + xp = pytest.importorskip("array_api_strict") + rng = np.random.default_rng(0) + X = rng.normal(size=(10, 5)) + y = rng.normal(size=10) + + reg = LinearRegression().fit(X, y) + X_xp = xp.asarray(X) + reg.predict(X_xp) + + with config_context(array_api_dispatch=True): + with pytest.raises(ValueError, match=".*must use the same namespace"): + reg.predict(X_xp) + xp_target, _, device = get_namespace_and_device(X_xp) + reg = move_estimator_to(reg, xp_target, device) + reg.predict(X_xp) + + def test_predict_proba_lr_large_values(): """Test that _predict_proba_lr of LinearClassifierMixin deals with large negative values. diff --git a/sklearn/model_selection/_search.py b/sklearn/model_selection/_search.py index 3f568ce60c842..39f2034451d2b 100644 --- a/sklearn/model_selection/_search.py +++ b/sklearn/model_selection/_search.py @@ -8,6 +8,7 @@ import numbers import operator +import re import time import warnings from abc import ABCMeta, abstractmethod @@ -554,6 +555,27 @@ def score(self, X, y=None, **params): score = score[self.refit] return score + def _wrap_namespace_error(self, method_name, call, *args, **kwargs): + """Call ``call`` and rewrite namespace mismatch errors from inner estimator.""" + try: + return call(*args, **kwargs) + except ValueError as e: + if "must use the same namespace" not in str(e): + raise + inner_class = self.best_estimator_.__class__.__name__ + outer_class = self.__class__.__name__ + msg = str(e) + # The inner estimator may raise from a different method than the + # one the user called on the meta-estimator (e.g. predict -> + # decision_function). Replace the inner "Class.method()" with the + # outer one so the message is actionable. + msg = re.sub( + rf"{re.escape(inner_class)}\.\w+\(\)", + f"{outer_class}.{method_name}()", + msg, + ) + raise ValueError(msg) from None + @available_if(_search_estimator_has("score_samples")) def score_samples(self, X): """Call score_samples on the estimator with the best found parameters. @@ -575,7 +597,9 @@ def score_samples(self, X): The ``best_estimator_.score_samples`` method. """ check_is_fitted(self) - return self.best_estimator_.score_samples(X) + return self._wrap_namespace_error( + "score_samples", self.best_estimator_.score_samples, X + ) @available_if(_search_estimator_has("predict")) def predict(self, X): @@ -597,7 +621,7 @@ def predict(self, X): the best found parameters. """ check_is_fitted(self) - return self.best_estimator_.predict(X) + return self._wrap_namespace_error("predict", self.best_estimator_.predict, X) @available_if(_search_estimator_has("predict_proba")) def predict_proba(self, X): @@ -620,7 +644,9 @@ def predict_proba(self, X): to that in the fitted attribute :term:`classes_`. """ check_is_fitted(self) - return self.best_estimator_.predict_proba(X) + return self._wrap_namespace_error( + "predict_proba", self.best_estimator_.predict_proba, X + ) @available_if(_search_estimator_has("predict_log_proba")) def predict_log_proba(self, X): @@ -643,7 +669,9 @@ def predict_log_proba(self, X): corresponds to that in the fitted attribute :term:`classes_`. """ check_is_fitted(self) - return self.best_estimator_.predict_log_proba(X) + return self._wrap_namespace_error( + "predict_log_proba", self.best_estimator_.predict_log_proba, X + ) @available_if(_search_estimator_has("decision_function")) def decision_function(self, X): @@ -666,7 +694,9 @@ def decision_function(self, X): the best found parameters. """ check_is_fitted(self) - return self.best_estimator_.decision_function(X) + return self._wrap_namespace_error( + "decision_function", self.best_estimator_.decision_function, X + ) @available_if(_search_estimator_has("transform")) def transform(self, X): @@ -688,7 +718,9 @@ def transform(self, X): the best found parameters. """ check_is_fitted(self) - return self.best_estimator_.transform(X) + return self._wrap_namespace_error( + "transform", self.best_estimator_.transform, X + ) @available_if(_search_estimator_has("inverse_transform")) def inverse_transform(self, X): diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index e1f2ee9d5516d..634364553a1d1 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -3,10 +3,12 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause +import inspect import itertools import math import os from collections import namedtuple +from functools import partial import numpy import scipy @@ -524,7 +526,7 @@ def move_to(*arrays, xp, device): Each array will be moved to the reference namespace and device if it is not already using it. Otherwise the array is left unchanged. - `array` may contain `None` entries, these are left unchanged. + `arrays` may contain `None` entries, these are left unchanged. Sparse arrays are accepted (as pass through) if the reference namespace is NumPy, in which case they are returned unchanged. Otherwise a `TypeError` @@ -1004,10 +1006,9 @@ def _convert_to_numpy(array, xp): def _estimator_with_converted_arrays(estimator, converter): - """Create new estimator which converting all attributes that are arrays. + """Create a new estimator with converted array attributes. - The converter is called on all NumPy arrays and arrays that support the - `DLPack interface <https://dmlc.github.io/dlpack/latest/>`__. + All attributes that are arrays will be converted using the provided converter. Parameters ---------- @@ -1020,18 +1021,126 @@ def _estimator_with_converted_arrays(estimator, converter): Returns ------- new_estimator : Estimator - Convert estimator + A clone of the estimator with converted array attributes. """ + # Inline import to avoid circular import from sklearn.base import clone + # Because we call this function recursively `estimator` might actually be an + # attribute of an estimator and not an actual estimator object. + estimator_type = type(estimator) + + if hasattr(estimator, "__sklearn_array_api_convert__") and not inspect.isclass( + estimator + ): + return estimator.__sklearn_array_api_convert__(converter) + + if estimator_type is dict: + return { + k: _estimator_with_converted_arrays(v, converter) + for k, v in estimator.items() + } + + if estimator_type in (list, tuple, set, frozenset): + return estimator_type( + _estimator_with_converted_arrays(v, converter) for v in estimator + ) + + if hasattr(estimator, "__dlpack__") or isinstance( + estimator, (numpy.ndarray, numpy.generic) + ): + return converter(estimator) + + if not hasattr(estimator, "get_params") or isinstance(estimator, type): + return estimator + new_estimator = clone(estimator) for key, attribute in vars(estimator).items(): - if hasattr(attribute, "__dlpack__") or isinstance(attribute, numpy.ndarray): - attribute = converter(attribute) + attribute = _estimator_with_converted_arrays(attribute, converter) setattr(new_estimator, key, attribute) return new_estimator +def move_estimator_to(estimator, xp, device): + """Move estimator array attributes to the given namespace and device. + + Attributes which are not arrays are left unchanged. + + Parameters + ---------- + estimator : estimator object + The estimator whose attributes should be converted. + + xp : array namespace + The target array API namespace. + + device : device or None + The target device. + + Returns + ------- + new_estimator : estimator object + A clone of the estimator with array attributes moved. + """ + return _estimator_with_converted_arrays( + estimator, partial(move_to, xp=xp, device=device) + ) + + +def check_same_namespace(X, estimator, *, attribute, method): + """Check that estimator's fitted attribute is compatible with X. + + Use this to check that an estimator was fitted using the same array + namespace and device as ``X``. This is done by comparing the namespace and + device of ``X`` and the provided ``attribute``. + + Parameters + ---------- + X : array-like + The data passed to the fitted estimator's method, e.g. to ``predict``. + + estimator : estimator object + The fitted estimator. + + attribute : str + The name of the fitted attribute to check; for example it could be + ``"coef_"`` for a linear model. This function will check that ``X`` is + in a namespace and device that are consistent with the attribute. + + method : str + The name of the calling method (e.g. ``"predict"``). It is used to + write the error message if the check fails. + """ + if not get_config()["array_api_dispatch"]: + return + + attr = getattr(estimator, attribute) + a_xp, _, a_device = get_namespace_and_device(attr) + + X_xp, _, X_device = get_namespace_and_device(X) + + if X_xp == a_xp and X_device == a_device: + return + + if X_xp != a_xp: + msg = ( + f"Array namespaces used during fit ({a_xp.__name__}) " + f"and {method} ({X_xp.__name__}) differ." + ) + else: # pragma: no cover + msg = f"Devices used during fit ({a_device}) and {method} ({X_device}) differ." + + raise ValueError( + f"Inputs passed to {estimator.__class__.__name__}.{method}() " + "must use the same namespace and the same device as those passed to fit(). " + f"{msg} " + "You can move the estimator to the same namespace and device as X with: " + "'from sklearn.utils._array_api import move_estimator_to; " + "xp, _, device = get_namespace_and_device(X); " + "estimator = move_estimator_to(estimator, xp, device)'" + ) + + def _atol_for_type(dtype_or_dtype_name): """Return the absolute tolerance for a given numpy dtype.""" if dtype_or_dtype_name is None: diff --git a/sklearn/utils/_test_common/instance_generator.py b/sklearn/utils/_test_common/instance_generator.py index 4f2c43a0b106e..64e067bd36e52 100644 --- a/sklearn/utils/_test_common/instance_generator.py +++ b/sklearn/utils/_test_common/instance_generator.py @@ -151,6 +151,7 @@ MultiOutputRegressor, RegressorChain, ) +from sklearn.naive_bayes import GaussianNB from sklearn.neighbors import ( KernelDensity, KNeighborsClassifier, @@ -162,8 +163,14 @@ from sklearn.neural_network import BernoulliRBM, MLPClassifier, MLPRegressor from sklearn.pipeline import FeatureUnion, Pipeline from sklearn.preprocessing import ( + Binarizer, KBinsDiscretizer, + KernelCenterer, + LabelEncoder, + MinMaxScaler, + Normalizer, OneHotEncoder, + PolynomialFeatures, SplineTransformer, StandardScaler, TargetEncoder, @@ -940,6 +947,9 @@ def _yield_instances_for_check(check, estimator_orig): "sample_weight is not equivalent to removing/repeating samples." ), }, + Binarizer: { + "check_array_api_same_namespace": "check_same_namespace not yet added", + }, BernoulliRBM: { "check_methods_subset_invariance": ("fails for the decision_function method"), "check_methods_sample_order_invariance": ("fails for the score_samples method"), @@ -968,6 +978,9 @@ def _yield_instances_for_check(check, estimator_orig): "check_methods_sample_order_invariance": "fails for the predict method", }, FeatureUnion: { + # Fails because StandardScaler, which gets wrapped by FeatureUnion, supports + # array API but FeatureUnion itself does not + "check_array_api_same_namespace": "check_same_namespace not yet added", "check_estimators_overwrite_params": "FIXME", "check_estimators_nan_inf": "FIXME", "check_dont_overwrite_parameters": "FIXME", @@ -983,6 +996,9 @@ def _yield_instances_for_check(check, estimator_orig): "sample_weight is not equivalent to removing/repeating samples." ), }, + GaussianNB: { + "check_array_api_same_namespace": "check_same_namespace not yet added", + }, GradientBoostingClassifier: { # TODO: investigate failure see meta-issue #16298 "check_sample_weight_equivalence_on_dense_data": ( @@ -1052,6 +1068,9 @@ def _yield_instances_for_check(check, estimator_orig): "sample_weight is not equivalent to removing/repeating samples." ), }, + KernelCenterer: { + "check_array_api_same_namespace": "check_same_namespace not yet added", + }, KernelDensity: { "check_sample_weight_equivalence_on_dense_data": ( "sample_weight must have positive values" @@ -1069,6 +1088,9 @@ def _yield_instances_for_check(check, estimator_orig): KNeighborsTransformer: { "check_methods_sample_order_invariance": "check is not applicable." }, + LabelEncoder: { + "check_array_api_same_namespace": "check_same_namespace not yet added", + }, LinearSVC: { # TODO: replace by a statistical test when _dual=True, see meta-issue #16298 "check_sample_weight_equivalence_on_dense_data": ( @@ -1099,6 +1121,9 @@ def _yield_instances_for_check(check, estimator_orig): "sample_weight is not equivalent to removing/repeating samples." ), }, + MinMaxScaler: { + "check_array_api_same_namespace": "check_same_namespace not yet added", + }, MiniBatchKMeans: { # TODO: replace by a statistical test, see meta-issue #16298 "check_sample_weight_equivalence_on_dense_data": ( @@ -1132,10 +1157,14 @@ def _yield_instances_for_check(check, estimator_orig): "sample_weight is not equivalent to removing/repeating samples." ), }, + Normalizer: { + "check_array_api_same_namespace": "check_same_namespace not yet added", + }, Nystroem: { + "check_array_api_same_namespace": "check_same_namespace not yet added", "check_transformer_preserves_dtypes": ( "dtypes are preserved but not at a close enough precision" - ) + ), }, OneClassSVM: { # TODO: fix sample_weight handling of this estimator, see meta-issue #16298 @@ -1149,6 +1178,7 @@ def _yield_instances_for_check(check, estimator_orig): PCA: { # TODO: see gh-33205 for details "check_array_api_input": "`linalg.inv` fails because input is singular", + "check_array_api_same_namespace": "check_same_namespace not yet added", }, Perceptron: { # TODO: replace by a statistical test, see meta-issue #16298 @@ -1169,6 +1199,12 @@ def _yield_instances_for_check(check, estimator_orig): "Therefore this test is x-fail until we fix this." ), }, + PoissonRegressor: { + "check_array_api_same_namespace": "check_same_namespace not yet added", + }, + PolynomialFeatures: { + "check_array_api_same_namespace": "check_same_namespace not yet added", + }, RadiusNeighborsTransformer: { "check_methods_sample_order_invariance": "check is not applicable." }, @@ -1216,6 +1252,9 @@ def _yield_instances_for_check(check, estimator_orig): "sample_weight is not equivalent to removing/repeating samples." ), }, + RBFSampler: { + "check_array_api_same_namespace": "check_same_namespace not yet added", + }, Ridge: { "check_non_transformer_estimators_n_iter": ( "n_iter_ cannot be easily accessed." @@ -1279,6 +1318,9 @@ def _yield_instances_for_check(check, estimator_orig): "check_dont_overwrite_parameters": "empty array passed inside", "check_fit2d_predict1d": "empty array passed inside", }, + StandardScaler: { + "check_array_api_same_namespace": "check_same_namespace not yet added", + }, SVC: { # TODO: fix sample_weight handling of this estimator when probability=False # TODO: replace by a statistical test when probability=True diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index 4ac4b6a553d70..a9dcbf16abe77 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -364,6 +364,13 @@ def _yield_array_api_checks(estimator, only_numpy=False): device_name=device_name, dtype_name=dtype_name, ) + # Only test with one namespace to keep costs down + # There should be no dependency on the exact + # namespace used. + yield partial( + check_array_api_same_namespace, + array_namespace="array_api_strict", + ) def _yield_all_checks(estimator, legacy: bool): @@ -1281,6 +1288,63 @@ def check_array_api_input_and_values( ) +def check_array_api_same_namespace( + name, estimator_orig, array_namespace, device_name=None +): + """Check that estimator raises when predict/transform namespace differs from fit. + + Array API compatible estimators should call ``check_same_namespace`` in + their ``predict``, ``transform``, and similar methods to verify that the + input arrays are from the same namespace and device as the fitted + attributes. + """ + xp, device = _array_api_for_tests(array_namespace, device_name) + + X, y = make_classification(n_samples=30, n_features=10, random_state=42) + X = X.astype("float64", copy=False) + + X = _enforce_estimator_tags_X(estimator_orig, X) + y = _enforce_estimator_tags_y(estimator_orig, y) + + est = clone(estimator_orig) + set_random_state(est) + + X_xp = xp.asarray(X, device=device) + y_xp = xp.asarray(y, device=device) + + with config_context(array_api_dispatch=True): + est.fit(X_xp, y_xp) + + methods = ( + "decision_function", + "predict", + "predict_log_proba", + "predict_proba", + "transform", + ) + + for method_name in methods: + method = getattr(est, method_name, None) + if method is None: + continue + + with config_context(array_api_dispatch=True): + try: + method(X) + except ValueError as e: + if "must use the same namespace" in str( + e + ) and f"{name}.{method_name}()" in str(e): + continue + raise + raise AssertionError( + f"{name}.{method_name}() did not raise when called with a " + f"different array namespace than the one used during fit. " + f"Add a call to check_same_namespace() at the start of " + f"{method_name} to fix this." + ) + + def check_estimator_sparse_tag(name, estimator_orig): """Check that estimator tag related with accepting sparse data is properly set.""" estimator = clone(estimator_orig) diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index 0203fd45e2a5c..2cafe7cea175d 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -34,9 +34,11 @@ _nanmin, _ravel, _validate_diagonal_args, + check_same_namespace, get_namespace, get_namespace_and_device, indexing_dtype, + move_estimator_to, move_to, np_compat, supported_float_dtypes, @@ -494,9 +496,35 @@ def test_convert_to_numpy_cpu(): class SimpleEstimator(BaseEstimator): def fit(self, X, y=None): self.X_ = X + self.X_dict_ = {"X": X} + self.X_list_ = [X] self.n_features_ = X.shape[0] return self + def predict(self, X): + check_same_namespace(X, self, attribute="X_", method="predict") + return X + + +class SimpleEstimatorCustomLogic(BaseEstimator): + def fit(self, X, y=None): + self.X_ = X + self.X_dict_ = {"X": X} + self.n_features_ = X.shape[0] + return self + + def predict(self, X): + check_same_namespace(X, self, attribute="X_", method="predict") + return X + + def __sklearn_array_api_convert__(self, converter): + self.X_ = converter(self.X_) + self.X_dict_ = {k: converter(v) for k, v in self.X_dict_.items()} + # XXX Do we need this? What else could the custom logic do that wouldn't work + # with the default logic? + self.converted_ = True + return self + @skip_if_array_api_compat_not_configured @pytest.mark.parametrize( @@ -512,15 +540,18 @@ def test_convert_estimator_to_ndarray(array_namespace, converter): xp = pytest.importorskip(array_namespace) X = xp.asarray([[1.3, 4.5]]) - est = SimpleEstimator().fit(X) + with config_context(array_api_dispatch=True): + est = SimpleEstimator().fit(X) + est.predict(X) - new_est = _estimator_with_converted_arrays(est, converter) - assert isinstance(new_est.X_, numpy.ndarray) + new_est = _estimator_with_converted_arrays(est, converter) + assert isinstance(new_est.X_, numpy.ndarray) + new_est = move_estimator_to(est, numpy, device="cpu") + assert isinstance(new_est.X_, numpy.ndarray) @skip_if_array_api_compat_not_configured -def test_convert_estimator_to_array_api(): - """Convert estimator attributes to ArrayAPI arrays.""" +def test_convert_estimator_with_custom_logic(): xp = pytest.importorskip("array_api_strict") X_np = numpy.asarray([[1.3, 4.5]]) @@ -528,6 +559,54 @@ def test_convert_estimator_to_array_api(): new_est = _estimator_with_converted_arrays(est, lambda array: xp.asarray(array)) assert hasattr(new_est.X_, "__array_namespace__") + with config_context(array_api_dispatch=True): + new_est = move_estimator_to(est, xp, device=None) + + assert get_namespace(new_est.X_)[0] == xp + assert get_namespace(new_est.X_dict_["X"])[0] == xp + assert get_namespace(new_est.X_list_[0])[0] == xp + + +@skip_if_array_api_compat_not_configured +def test_custom_conversion_estimator_to_array_api_strict(): + xp = pytest.importorskip("array_api_strict") + + X_np = numpy.asarray([[1.3, 4.5]]) + est = SimpleEstimatorCustomLogic().fit(X_np) + + with config_context(array_api_dispatch=True): + new_est = move_estimator_to(est, xp, device=None) + + new_est.predict(xp.asarray([[1.3, 4.5]])) + + assert get_namespace(new_est.X_)[0] == xp + assert get_namespace(new_est.X_dict_["X"])[0] == xp + assert new_est.converted_ + + +@skip_if_array_api_compat_not_configured +def test_convert_estimator_to_array_api_strict(): + xp = pytest.importorskip("array_api_strict") + + X_np = numpy.asarray([[1.3, 4.5]]) + est = SimpleEstimator().fit(X_np) + + with config_context(array_api_dispatch=True): + new_est = move_estimator_to(est, xp, device=None) + + assert get_namespace(new_est.X_)[0] == xp + assert get_namespace(new_est.X_dict_["X"])[0] == xp + + +@skip_if_array_api_compat_not_configured +def test_check_fitted_attribute(): + xp = pytest.importorskip("array_api_strict") + + with config_context(array_api_dispatch=True): + est = SimpleEstimator().fit(xp.asarray([[1.3, 4.5]])) + + with pytest.raises(ValueError, match=".*must use the same namespace"): + est.predict(numpy.asarray([0])) @pytest.mark.parametrize( diff --git a/sklearn/utils/tests/test_estimator_checks.py b/sklearn/utils/tests/test_estimator_checks.py index 3e261f1648e01..f94432c79a2db 100644 --- a/sklearn/utils/tests/test_estimator_checks.py +++ b/sklearn/utils/tests/test_estimator_checks.py @@ -1737,7 +1737,11 @@ def test_estimator_with_set_output(): "check_array_api_input": ( "this check is expected to fail because pandas and polars" " are not compatible with the array api." - ) + ), + "check_array_api_same_namespace": ( + "this check is expected to fail because pandas and polars" + " are not compatible with the array api." + ), }, ) From 8aba6fd150b02f3a0a16af828d3173c9cd4bbd00 Mon Sep 17 00:00:00 2001 From: Daniel Agyapong <agyapongdaniel7777@gmail.com> Date: Fri, 27 Mar 2026 02:13:30 -0700 Subject: [PATCH 307/462] FIX ConvergenceWarning in plot_gpr_on_structured_data (#31164) (#31289) Co-authored-by: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> --- .../gaussian_process/plot_gpr_on_structured_data.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/gaussian_process/plot_gpr_on_structured_data.py b/examples/gaussian_process/plot_gpr_on_structured_data.py index f3a8de5d018ef..dfe39964100f1 100644 --- a/examples/gaussian_process/plot_gpr_on_structured_data.py +++ b/examples/gaussian_process/plot_gpr_on_structured_data.py @@ -5,7 +5,7 @@ This example illustrates the use of Gaussian processes for regression and classification tasks on data that are not in fixed-length feature vector form. -This is achieved through the use of kernel functions that operates directly +This is achieved through the use of kernel functions that operate directly on discrete structures such as variable-length sequences, trees, and graphs. Specifically, here the input variables are some gene sequences stored as @@ -54,7 +54,7 @@ class SequenceKernel(GenericKernelMixin, Kernel): A minimal (but valid) convolutional kernel for sequences of variable lengths.""" - def __init__(self, baseline_similarity=0.5, baseline_similarity_bounds=(1e-5, 1)): + def __init__(self, baseline_similarity=0.5, baseline_similarity_bounds="fixed"): self.baseline_similarity = baseline_similarity self.baseline_similarity_bounds = baseline_similarity_bounds @@ -102,6 +102,12 @@ def clone_with_theta(self, theta): return cloned +# %% +# .. note:: +# Here, we freeze the value of ``baseline_similarity`` by setting +# `baseline_similarity_bounds="fixed"` as LBFGS would otherwise fail to +# optimize the value of this kernel parameter for some unknown reason. + kernel = SequenceKernel() # %% From d2cba0903ceb1a9a30469fb30ab26756cdafcdb5 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Fri, 27 Mar 2026 14:30:11 +0100 Subject: [PATCH 308/462] DOC fix colors and typos in example on Multinomial and One-vs-Rest Decision Boundaries (#33622) --- .../linear_model/plot_logistic_multinomial.py | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/examples/linear_model/plot_logistic_multinomial.py b/examples/linear_model/plot_logistic_multinomial.py index c12229c81c7f1..1ea433fb6c107 100644 --- a/examples/linear_model/plot_logistic_multinomial.py +++ b/examples/linear_model/plot_logistic_multinomial.py @@ -18,10 +18,10 @@ # Dataset Generation # ------------------ # -# We generate a synthetic dataset using :func:`~sklearn.datasets.make_blobs` function. -# The dataset consists of 1,000 samples from three different classes, +# We generate a synthetic dataset using the :func:`~sklearn.datasets.make_blobs` +# function. The dataset consists of 1,000 samples from three different classes, # centered around [-5, 0], [0, 1.5], and [5, -1]. After generation, we apply a linear -# transformation to introduce some correlation between features and make the problem +# transformation to introduce some correlation between the features to make the problem # more challenging. This results in a 2D dataset with three overlapping classes, # suitable for demonstrating the differences between multinomial and one-vs-rest # logistic regression. @@ -30,6 +30,8 @@ from sklearn.datasets import make_blobs +cmap = "coolwarm" + centers = [[-5, 0], [0, 1.5], [5, -1]] X, y = make_blobs(n_samples=1_000, centers=centers, random_state=40) transformation = [[0.4, 0.2], [-0.4, 1.2]] @@ -37,7 +39,7 @@ fig, ax = plt.subplots(figsize=(6, 4)) -scatter = ax.scatter(X[:, 0], X[:, 1], c=y, edgecolor="black") +scatter = ax.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap, edgecolor="black") ax.set(title="Synthetic Dataset", xlabel="Feature 1", ylabel="Feature 2") _ = ax.legend(*scatter.legend_elements(), title="Classes") @@ -86,8 +88,9 @@ ax=ax, response_method="predict", alpha=0.8, + multiclass_colors=cmap, ) - scatter = ax.scatter(X[:, 0], X[:, 1], c=y, edgecolor="k") + scatter = ax.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap, edgecolor="k") legend = ax.legend(*scatter.legend_elements(), title="Classes") ax.add_artist(legend) ax.set_title(title) @@ -108,8 +111,8 @@ # -------------------------- # # We also visualize the hyperplanes that correspond to the line when the probability -# estimate for a class is of 0.5. -def plot_hyperplanes(classifier, X, ax): +# estimate for a class is 0.5. +def plot_hyperplanes(classifier, X, ax, colors): xmin, xmax = X[:, 0].min(), X[:, 0].max() ymin, ymax = X[:, 1].min(), X[:, 1].max() ax.set(xlim=(xmin, xmax), ylim=(ymin, ymax)) @@ -121,12 +124,12 @@ def plot_hyperplanes(classifier, X, ax): coef = classifier.coef_ intercept = classifier.intercept_ - for i in range(coef.shape[0]): + for i, color in zip(range(coef.shape[0]), colors): w = coef[i] a = -w[0] / w[1] xx = np.linspace(xmin, xmax) yy = a * xx - (intercept[i]) / w[1] - ax.plot(xx, yy, "--", linewidth=3, label=f"Class {i}") + ax.plot(xx, yy, "--", color=color, linewidth=4, label=f"Class {i}") return ax.get_legend_handles_labels() @@ -142,8 +145,10 @@ def plot_hyperplanes(classifier, X, ax): ), (logistic_regression_ovr, "One-vs-Rest Logistic Regression Hyperplanes", ax2), ]: - hyperplane_handles, hyperplane_labels = plot_hyperplanes(model, X, ax) - scatter = ax.scatter(X[:, 0], X[:, 1], c=y, edgecolor="k") + hyperplane_handles, hyperplane_labels = plot_hyperplanes( + model, X, ax, colors=["blue", "dimgray", "red"] + ) + scatter = ax.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap, edgecolor="k") scatter_handles, scatter_labels = scatter.legend_elements() all_handles = hyperplane_handles + scatter_handles From 273a01dde292a196909303e2a8ac87d9a7d0fd2f Mon Sep 17 00:00:00 2001 From: Yann Lechelle <yann@probabl.ai> Date: Fri, 27 Mar 2026 14:31:25 +0100 Subject: [PATCH 309/462] DOC Adding link to ecosystem page "scikit-learn central" (#33527) --- doc/templates/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/templates/index.html b/doc/templates/index.html index dae1e60b6288e..b208e2f9981d2 100644 --- a/doc/templates/index.html +++ b/doc/templates/index.html @@ -227,6 +227,7 @@ <h4 class="sk-landing-call-header">Community</h4> <li><strong>Blog:</strong> <a href="https://blog.scikit-learn.org">blog.scikit-learn.org</a></li> <li><strong>Logos & Branding:</strong> <a href="https://github.com/scikit-learn/scikit-learn/tree/main/doc/logos">logos and branding</a></li> <li><strong>Calendar:</strong> <a href="https://blog.scikit-learn.org/calendar/">calendar</a></li> + <li><strong>Ecosystem:</strong> <a href="https://scikit-learn-central.probabl.ai">scikit-learn central</a></li> <li><strong>LinkedIn:</strong> <a href="https://www.linkedin.com/company/scikit-learn">linkedin/scikit-learn</a></li> <li><strong>Bluesky:</strong> <a href="https://bsky.app/profile/scikit-learn.org">bluesky/scikit-learn.org</a></li> <li><strong>Mastodon:</strong> <a href="https://mastodon.social/@sklearn@fosstodon.org">@sklearn</a></li> From dd53c1d466c7c23f7bb757d26ddb0f1c9a58fbde Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Fri, 27 Mar 2026 18:18:04 +0100 Subject: [PATCH 310/462] MNT align type of `multiclass_colors_` for list and colormap in `DecisionBoundaryDisplay` (#33651) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> --- .../upcoming_changes/sklearn.inspection/33651.fix.rst | 3 +++ sklearn/inspection/_plot/decision_boundary.py | 2 +- .../inspection/_plot/tests/test_boundary_decision_display.py | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.inspection/33651.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/33651.fix.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/33651.fix.rst new file mode 100644 index 0000000000000..45da8a577aa8b --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.inspection/33651.fix.rst @@ -0,0 +1,3 @@ +- In :class:`inspection.DecisionBoundaryDisplay`, `multiclass_colors_` now always stores + the colors for multiclass problems as a numpy array. + By :user:`Anne Beyer <AnneBeyer>`. diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index a1e28882565d5..bcbf72a16dd35 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -117,7 +117,7 @@ def _select_colors(mpl, multiclass_colors, n_classes): "When 'multiclass_colors' is a list, it can only contain valid" f" Matplotlib color names. Got: {multiclass_colors}" ) - return [mpl.colors.to_rgba(color) for color in multiclass_colors] + return mpl.colors.to_rgba_array(multiclass_colors) else: raise TypeError("'multiclass_colors' must be a list or a str.") diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index 539caedb013f6..1039d5eca1cdd 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -666,6 +666,9 @@ def test_multiclass_colors_cmap( multiclass_colors=multiclass_colors, ) + # Non-regression test for PR #33651 + assert isinstance(disp.multiclass_colors_, np.ndarray) + if multiclass_colors is None: if len(clf.classes_) <= 10: multiclass_colors = "tab10" @@ -679,7 +682,7 @@ def test_multiclass_colors_cmap( cmap = mpl.pyplot.get_cmap(multiclass_colors) colors = cmap(np.linspace(0, 1, len(clf.classes_))) else: - colors = [mpl.colors.to_rgba(color) for color in multiclass_colors] + colors = mpl.colors.to_rgba_array(multiclass_colors) # Make sure the colormap has enough distinct colors. assert disp.n_classes == len(np.unique(colors, axis=0)) From cc52cbbd50ffc1704d92602d0a129868227889b3 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 30 Mar 2026 04:17:44 -0400 Subject: [PATCH 311/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33662) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/circle/doc_linux-64_conda.lock | 95 ++++++++++--------- .../doc_min_dependencies_linux-64_conda.lock | 56 ++++++----- build_tools/github/debian_32bit_lock.txt | 2 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 69 +++++++------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 20 ++-- .../pylatest_conda_forge_osx-arm64_conda.lock | 38 ++++---- ...st_pip_openblas_pandas_linux-64_conda.lock | 8 +- ...n_conda_forge_arm_linux-aarch64_conda.lock | 43 +++++---- ...nblas_min_dependencies_linux-64_conda.lock | 32 +++---- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 30 +++--- ...min_conda_forge_openblas_win-64_conda.lock | 38 ++++---- build_tools/github/ubuntu_atlas_lock.txt | 2 +- 12 files changed, 219 insertions(+), 214 deletions(-) diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 0604a6981221e..77af5a55514e0 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -7,6 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_10.conda#590b5a14299d67b9669fe5eb1fdd4d3b https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d @@ -16,8 +17,9 @@ https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda# https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.2-h4922eb0_0.conda#2a60ab96432bc74eedbcda8a528080a1 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 -https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de +https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 @@ -30,7 +32,7 @@ https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2f https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -40,7 +42,7 @@ https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda#7af961ef4aa2c1136e11dd43ded245ab https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 @@ -69,7 +71,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.2.0-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.conda#4ffbb341c8b616aa2494b6afb26a0c5f https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b @@ -94,10 +96,9 @@ https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#594 https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.1-hc31b594_0.conda#68ceffc6cadae61846a207cae60de094 https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 -https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 @@ -113,17 +114,15 @@ https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_22.conda#0b6cd616dab5e509c5c368d58a01982d https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d -https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.3-h8d634f6_0.conda#792d5b6e99677177f5527a758a02bc07 https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f @@ -152,28 +151,28 @@ https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/doit-0.37.0-pyhcf101f3_0.conda#37b3d4c558f2bb2b5378c43f4d6f1fb5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h31f076a_22.conda#5e6d687088defd7740e973f604e0a8e2 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h7ab9642_22.conda#ac8519fa5fe0e5d779b5f6d658c10ed5 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/noarch/json5-0.13.0-pyhd8ed1ab_0.conda#8d5f66ebf832c4ce28d5c37a0e76605c -https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.0.0-pyhcf101f3_3.conda#cd2214824e36b0180141d422aba01938 +https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda#1269891272187518a0a75c286f7d0bbf +https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda#89bf346df77603055d3c8fe5811691e6 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b965c999135d43a3d0f7bd7d024e26a -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.2-hf7376ad_0.conda#7147b0792a803cd5b9929ce5d48f7818 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.0-pyhcf101f3_0.conda#bc317f07dd82e410012684d2e3a9c06d +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.1-pyhcf101f3_1.conda#30bec5e8f4c3969e2b1bd407c5e52afb https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 @@ -186,7 +185,7 @@ https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.24.1-pyhd8ed1a https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda#7d9daffbb8d8e0af0f769dbbcd173a54 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda#23029aae904a2ba587daba708208012f @@ -204,8 +203,8 @@ https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0 https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda#18de09b20462742fe093ba39185d9bac https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda#73b44a114241e564deb5846e7394bf19 https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda#019a7385be9af33791c989871317e1ed https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda#f6d7aa696c67756a650e91e15e88223c @@ -232,7 +231,7 @@ https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0 https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.0-h6083320_0.conda#71c2c966e17a65b08b995f571310fb9f +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d @@ -240,15 +239,13 @@ https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#61 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b11e360fc4de2b0035fc8aaa74f17fd6 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py311h2e04523_0.conda#cfc8f864dea571677095ebae8e6f0c07 https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda#3e9427ee186846052e81fadde8ebe96a https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 @@ -257,24 +254,21 @@ https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.15-hd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 +https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda#17b43cee5cc84969529d5d0b0309b2cb https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda#f1acf5fdefa8300de697982bcb1761c9 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/noarch/anyio-4.12.1-pyhcf101f3_0.conda#11a2b8c732d215d977998ccd69a9d5e8 +https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda#af2df4b9108808da3dc76710fe50eae2 https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda#6e36e9d2b535c3fbe2e093108df26695 https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda#85c4f19f377424eafc4ed7911b291642 https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda#f11a319b9700b203aa14c295858782b6 -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311h724c32c_4.conda#d04e508f5a03162c8bab4586a65d00bf https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 -https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 @@ -282,42 +276,53 @@ https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyh https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.4-pyhcf101f3_0.conda#e81089ba496151ed0bfe3e9cb196ca11 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.conda#3ac73c673df24589b5b84d43a4afd235 -https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-pl5321h16c4a6b_6.conda#3a00bff44c15ee37bfd5eb435e1b2a51 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_2.conda#c6ba2de6b22dedf2f20eba3bde1dbe8e https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b -https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.1-pyhcf101f3_0.conda#4552b601cf622dea2bb5075baccc2c5b -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 -https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py311hf27b23e_1.conda#69d2caeedece7a008151c6917525403d +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py311hf27b23e_0.conda#78202f74ac55b455e0539b6d0253964d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 -https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.3.3-pyhd8ed1ab_0.conda#cecacab21bc8f4ed17fac11bc8b08cf0 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.0-pyhcf101f3_0.conda#bee5ed456361bfe8af502beaf5db82e2 https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda#8368d58342d0825f0843dc6acdd0c483 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 -https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py311h2a99c40_0.conda#557f5d7ca735d89d706742bc19cd7e26 -https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyhe01879c_0.conda#31e11c30bbee1682a55627f953c6725a https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.1-pyhbbac1ac_0.conda#d8f030e3730713c93a358fdb46f08281 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 -https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py311h2e04523_0.conda#cfc8f864dea571677095ebae8e6f0c07 +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311h724c32c_4.conda#d04e508f5a03162c8bab4586a65d00bf +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 +https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.0-pyhcf101f3_0.conda#b14079a39ae60ac7ad2ec3d9eab075ca +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.conda#3ac73c673df24589b5b84d43a4afd235 +https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda#d79a87dcfa726bcea8e61275feed6f83 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 +https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 +https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.3.3-pyhd8ed1ab_0.conda#cecacab21bc8f4ed17fac11bc8b08cf0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 +https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py311h2a99c40_0.conda#557f5d7ca735d89d706742bc19cd7e26 +https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 +https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.1-pyhcf101f3_0.conda#1f90643873d0cc2f7b0bf2752db71016 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda#837aaf71ddf3b27acae0e7e9015eebc6 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index fe4c561a7d1d7..e723e6e2018dd 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_463.conda#291727757c8a8613312aaa4b52e82ad8 +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_10.conda#590b5a14299d67b9669fe5eb1fdd4d3b https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d @@ -17,7 +17,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda# https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.2-h4922eb0_0.conda#2a60ab96432bc74eedbcda8a528080a1 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -31,10 +31,10 @@ https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-de https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda#f9f81ea472684d75b9dd8d0b328cf655 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 -https://conda.anaconda.org/conda-forge/linux-64/libattr-2.5.2-hb03c661_1.conda#7e7f0a692eb62b95d3010563e7f963b6 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed +https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499cd8e2d4358986dbe3b30e8fe1bf6a https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -46,7 +46,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -59,7 +59,6 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 -https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-hb03c661_1.conda#9bb149f49de3f322fca007283eaa2725 https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_102.conda#212fe5f1067445544c99dc1c847d032c https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_102.conda#2a307a17309d358c9b42afdd3199ddcc https://conda.anaconda.org/conda-forge/linux-64/charls-2.4.3-hecca717_0.conda#937ca49a245fcf2b88d51b6b52959426 @@ -77,11 +76,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda#8ee3cb7f64be0e8c4787f3a4dbe024e6 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -104,8 +104,7 @@ https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#594 https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.1-hc31b594_0.conda#68ceffc6cadae61846a207cae60de094 https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 -https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 @@ -124,8 +123,8 @@ https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_21.conda#1403ed5fe091bd7442e4e8a229d14030 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_22.conda#0b6cd616dab5e509c5c368d58a01982d https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda#b52b769cd13f7adaa6ccdc68ef801709 https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 @@ -133,7 +132,6 @@ https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda#8ee3cb7f64be0e8c4787f3a4dbe024e6 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -158,8 +156,8 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.con https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-hfa02b96_21.conda#234863e90d09d229043af1075fcf8204 -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h033eb0a_21.conda#6d74b73ab992940a79260c65e7685fcb +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h31f076a_22.conda#5e6d687088defd7740e973f604e0a8e2 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h7ab9642_22.conda#ac8519fa5fe0e5d779b5f6d658c10ed5 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -168,7 +166,7 @@ https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.2-hf7376ad_0.conda#7147b0792a803cd5b9929ce5d48f7818 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b @@ -182,7 +180,7 @@ https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7 https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 @@ -195,8 +193,8 @@ https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed https://conda.anaconda.org/conda-forge/noarch/tenacity-9.1.4-pyhcf101f3_0.conda#043f0599dc8aa023369deacdb5ac24eb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda#73b44a114241e564deb5846e7394bf19 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py311h49ec1c0_0.conda#2889f0c0b6a6d7a37bd64ec60f4cc210 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 @@ -211,7 +209,7 @@ https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.cond https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.0-h6083320_0.conda#71c2c966e17a65b08b995f571310fb9f +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d @@ -235,27 +233,27 @@ https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.con https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.5-pyhd8ed1ab_0.conda#4c8327180586e7b1cd8b6815fc8827f1 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 -https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b +https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda#d53ffc0edc8eabf4253508008493c5bc https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.0-pyhcf101f3_0.conda#bee5ed456361bfe8af502beaf5db82e2 https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h0c412b5_8.conda#80e27e7982af989ebc2e0f0d57c75ea7 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 @@ -264,7 +262,7 @@ https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#867 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 https://conda.anaconda.org/conda-forge/linux-64/pywavelets-1.8.0-py311h9f3472d_0.conda#17334e5c12abdf2db6b25bd4187cd3e4 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c +https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 diff --git a/build_tools/github/debian_32bit_lock.txt b/build_tools/github/debian_32bit_lock.txt index 020ed7fdeffc6..4a7f8993d7019 100644 --- a/build_tools/github/debian_32bit_lock.txt +++ b/build_tools/github/debian_32bit_lock.txt @@ -29,7 +29,7 @@ pluggy==1.6.0 # via # pytest # pytest-cov -pygments==2.19.2 +pygments==2.20.0 # via pytest pyproject-metadata==0.11.0 # via meson-python diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock index 324d87c4de830..475d453143bdb 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.26.0-ha770c72_0.conda#cb93c6e226a7bed5557601846555153d -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.0-hf2ce2f3_463.conda#291727757c8a8613312aaa4b52e82ad8 +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_10.conda#590b5a14299d67b9669fe5eb1fdd4d3b https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 @@ -16,7 +16,7 @@ https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.2-h4922eb0_0.conda#2a60ab96432bc74eedbcda8a528080a1 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 @@ -32,7 +32,7 @@ https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -42,7 +42,7 @@ https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 @@ -73,7 +73,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 @@ -91,14 +91,14 @@ https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98 https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda#996583ea9c796e5b915f7d7580b51ea6 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.1-hc87160b_2.conda#3a7d90d34895728f0b69107602b6e189 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-hc87160b_0.conda#dde6a3e4fe6bb2ecd2a7050dd1e701fb https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 @@ -113,20 +113,20 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.6.0-h841be55_0.conda#d45136de07e991786e04716c3f70b036 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.11-hf621c6d_0.conda#caf217f88155d551b4a586f2da37941a +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.6.0-h9b893ba_1.conda#cd4946050ecfcb3c6fd09106ae6a261e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.12-h4bacb7b_1.conda#7bc920933e5fb225aba86a788164a8f1 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa -https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.14.0-h3d65ac4_0.conda#2ef8b1658ab236df39a14f2b1126796e +https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.14.1-h3d65ac4_0.conda#fa4e76aac348ef9c27e72c79b02833fc https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 @@ -136,8 +136,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h536185d_1.conda#bc645a385e91cd3d9235174fcbd17e25 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.0-hac84f0a_1.conda#9cf66b4abc53e47857afbee27364102b +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h2d2dd48_2.conda#675ea6d90900350b1dcfa8231a5ea2dd +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-he9ea9c5_1.conda#8e77514673f5773b40ff8953583938b6 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a @@ -150,7 +150,7 @@ https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.2-py314h42812f9_0.conda#511748f9debe034ff88eef99bc215fd3 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac @@ -160,12 +160,13 @@ https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.2-hf7376ad_0.conda#7147b0792a803cd5b9929ce5d48f7818 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b -https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf +https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b @@ -177,7 +178,7 @@ https://conda.anaconda.org/conda-forge/linux-64/playwright-1.58.2-h5585027_0.con https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd @@ -185,8 +186,8 @@ https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339 https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda#23b4ba5619c4752976eb7ba1f5acb7e8 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py314h5bd0f2a_0.conda#e35f08043f54d26a1be93fdbf90d30c3 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py314h5bd0f2a_0.conda#dc1ff1e915ab35a06b6fa61efae73ab5 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py314h5bd0f2a_0.conda#494fdf358c152f9fdd0673c128c2f3dd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 @@ -196,7 +197,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h37c9286_4.conda#e9c44a6e46de739827d2eae25ed2ee32 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h6d69fc9_5.conda#4c5c16bf1133dcfe100f33dd4470998e https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e @@ -204,10 +205,10 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.0-h6083320_0.conda#71c2c966e17a65b08b995f571310fb9f +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 @@ -222,40 +223,40 @@ https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-haf8ea0b_2.conda#6f531ae41a8ac7c69c85130d16585d61 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h4c8aef7_3.conda#798a499cf76e530a992365d557ba5827 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.0-h0e700b2_463.conda#f121ddfc96e6a93a26d85906adf06208 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.58.0-pyhcf101f3_0.conda#3b886c49cf44aa133d0eb07e4d0cac89 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-pl5321h16c4a6b_6.conda#3a00bff44c15ee37bfd5eb435e1b2a51 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_2.conda#c6ba2de6b22dedf2f20eba3bde1dbe8e https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h5875eb1_mkl.conda#9d2f2e3a943d38f972ceef9cde8ba4bf +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.0-ha770c72_463.conda#325ca2c86964e8f96db949c98d21a5ad +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py314h3987850_1.conda#572aaa4811844ba16c265647f06e1106 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_0.conda#1bd12dc69c3632f1d7ee9fbfd68c0186 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.0-pyhcf101f3_0.conda#bee5ed456361bfe8af502beaf5db82e2 https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_hfef963f_mkl.conda#9b6cb3aa4b7912121c64b97a76ca43d5 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h5e43f62_mkl.conda#88155c848e1278b0990692e716c9eab4 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda#d5a4e013a30dd8dfde9ab39f45aaf9c1 https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_9_cpu.conda#b3ba3597c481a636fc161185819cf6b1 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_hdba1596_mkl.conda#d7e79a90df7e39c11296053a8d6ffd2b +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_9_cpu.conda#2dccf1b6cf9dba8857050740dbc0497e https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h7058990_103.conda#2df90510834746b1f52c5299bc99a81f https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_hcf00494_mkl.conda#ee0c98906ad5470b933af806095008ba +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py314hb4ffadd_0.conda#23fc526360815090f6bfcd7c6c8e4954 @@ -263,7 +264,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py314h969be7 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h6018c46_103.conda#a3c40f317db763f9631d078d0fb2759e https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-mkl.conda#8311682c071dadd3f10f2bdbc1fc1e0c +https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_9_cpu.conda#9c5282b7aaf2261d3dbe5a61d24d5337 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index dac2348906f9c..240a6f58bba96 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -9,9 +9,9 @@ https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda#4173a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda#627eca44e62e2b665eeec57a984a7f00 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 -https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.1-h19cb2f5_0.conda#799141ac68a99265f04bcee196b2df51 +https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.2-h19cb2f5_0.conda#ed6f7b7a35f942a0301e581d72616f7d https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 -https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.4-h991f03e_0.conda#a684eb8a19b2aa68fde0267df172a1e3 +https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.5-hcc62823_0.conda#1d6e71b8c73711e28ffe207acdc4e2f8 https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda#66a0dc7464927d0853b590b6f53ba3ea https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda#210a85a1119f97ea7887188d176db135 https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.2-h8616949_0.conda#48dda187f169f5a8f1e5e07701d5cdd9 @@ -19,7 +19,7 @@ https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda#688 https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda#ec88ba8a245855935b871a7324373105 https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda#7bb6608cf1f83578587297a158a6630b https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda#30439ff30578e504ee5e0b390afc8c65 -https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.0-h0d3cbff_0.conda#3921780bab286f2439ba483c22b90345 +https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.2-h0d3cbff_0.conda#2f82b78f43520355ae2d297fecde25fd https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda#ced34dd9929f491ca6dab6a2927aff25 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda#47f1b8b4a76ebd0cd22bd7153e54a4dc @@ -30,7 +30,7 @@ https://conda.anaconda.org/conda-forge/osx-64/lerc-4.1.0-h35c7297_0.conda#d2fe7e https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda#63186ac7a8a24b3528b4b14f21c03f54 https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda#5a088b358e37ccb4f4e5c573ff37a9f9 -https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.55-h07817ec_0.conda#4fc7ed44d55aaf1d72b8fbc18774b90c +https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.56-he930e7c_0.conda#635ddc7697d405386dcb64d777c545b5 https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.52.0-h77d7759_0.conda#d553eb96758e038b04027b30fe314b2d https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.2-h7a90416_0.conda#0c8bdbfd118f5963ab343846094932a3 @@ -43,7 +43,7 @@ https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.3-h8bce59a_1.conda#b3e https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.2-h894318c_0.conda#e77ab67215939f46bb6ec8226a242e6a -https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.2-h58fbd8d_0.conda#2e6760656fde7df787fdef045d0fc65d +https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.3-h58fbd8d_0.conda#27515b8ab8bf4abd8d3d90cf11212411 https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda#9a5cb96e43f5c2296690186e15b3296f https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.2-hd552753_0.conda#eea3155f3b4a3b75af504c871ec23858 @@ -56,7 +56,7 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.5.0-py314hd6e1bd6_0.conda#25a8718587d3d0d9114b25dfa93b864c https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.18-h90db99b_0.conda#753acc10c7277f953f168890e5397c80 -https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.2-h694c41f_0.conda#bf29ee73174c610d7cad0b081b500df7 +https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.3-h694c41f_0.conda#63b822fcf984c891f0afab2eedfcfaf4 https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda#ca52daf58cea766656266c8771d8be81 https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b @@ -65,20 +65,20 @@ https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h52bb76a_0.conda#46 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.4-py314h3d180e3_0.conda#e9dfcd5b883e35aebe6dbe2c197dddbe +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.5-py314h217eccc_0.conda#9fdead77ed9fd152b131289c6984ed7c https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.1-py314h4f144dc_0.conda#773e3141f292d9698e706da094ada8c1 https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.5-py314h77fa6c7_0.conda#c5d3ea7d5f490c69a6af7c056624fca4 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 -https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.2-h694c41f_0.conda#0959d7034baef0a8274387fde505c347 +https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.3-h694c41f_0.conda#6ab1403cc6cb284d56d0464f19251075 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda#34a9f67498721abcfef00178bcf4b190 https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.1-py314hf9dbaa9_0.conda#9a35ec32776ac587bf178233fd2176e4 diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock index 4e4ca8991769e..e75fcbe1569d8 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock @@ -12,10 +12,10 @@ https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda#62 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda#f1182c91c0de31a7abd40cedf6a5ebef https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa -https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.1-h55c6f16_0.conda#7a290d944bc0c481a55baf33fa289deb +https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.2-h55c6f16_0.conda#4280e0a7fd613b271e022e60dea0138c https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c -https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.4-hf6b4638_0.conda#a92e310ae8dfc206ff449f362fc4217f +https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.5-hf6b4638_0.conda#a32123f93e168eaa4080d87b0fb5da8a https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda#43c04d9cb46ef176bb2a4c77e324d599 https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda#4d5a7445f0b25b6a3ddbb56e790f5251 https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda#f0695fbecf1006f27f4395d64bd0c4b8 @@ -24,7 +24,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda#c0d87c3c8e075daf1daf6c31b53e8083 https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda#e5e7d467f80da752be17796b87fe6385 https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda#bc5a5721b6439f2f62a84f2548136082 -https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.0-hc7d1edf_0.conda#ff0820b5588b20be3b858552ecf8ffae +https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.2-hc7d1edf_0.conda#9c162044093d8d689836dafe3c27fe06 https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda#068d497125e4bf8a66bf707254fff5ae https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda#415816daf82e0b23a736a069a75e9da7 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda#78b548eed8227a689f93775d5d23ae09 @@ -40,7 +40,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.c https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda#58b2c5aee0ad58549bf92baead9baead -https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.55-h132b30e_0.conda#871dc88b0192ac49b6a5509932c31377 +https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.56-h132b30e_0.conda#ce25ae471d213f9dd5edb0fe8e0b102a https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.52.0-h1ae2325_0.conda#f6233a3fddc35a2ec9f617f79d6f3d71 https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.2-h5ef1a60_0.conda#b284e2b02d53ef7981613839fb86beee @@ -56,7 +56,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.3-hed4e4f5_1.conda# https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.2-h414bf82_0.conda#baeca21071729b617b20b019f85beedf -https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.2-hdfa99f5_0.conda#e726e134a392ae5d7bafa6cc4a3d5725 +https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.3-hdfa99f5_0.conda#e98ba7b5f09a5f450eca083d5a1c4649 https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda#92df6107310b1fff92c4cc84f0de247b https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.33.5-h4a5acfd_0.conda#b839e3295b66434f20969c8b940f056a https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda#c08557d00807785decafb932b5be7ef5 @@ -71,16 +71,16 @@ https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4 https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py314hc6117b3_0.conda#1289de88f884ac89144949cb97ccabe7 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.5.0-py314hf8a3a22_0.conda#eb1465d8a644ef290d18fb86af6e9bc4 https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.18-hdfa7624_0.conda#6631a7bd2335bb9699b1dbc234b19784 -https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.2-hce30654_0.conda#a3a53232936b55ffea76806aefe19e8b +https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.3-hce30654_0.conda#f73b109d49568d5d1dda43bb147ae37f https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda#c4a6f7989cffb0544bfd9207b6789971 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py314h6e9b3f0_1.conda#d33c0a15882b70255abdd54711b06a45 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b -https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.3.1-h8f1351a_1.conda#a5635df796b71f6ca400fc7026f50701 +https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.4.0-h169892a_0.conda#2845c3a1d0d8da1db92aba8323892475 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b @@ -89,21 +89,21 @@ https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda# https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda#ade77ad7513177297b1d75e351e136ce https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.4-py314h0612a62_0.conda#83e1a2d7b0c1352870bbe9d9406135cf +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py314h6c2aa35_0.conda#3f81f8b2fe2c26a82c0abf57ab2b9610 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py314h6c2aa35_0.conda#4fffb3ba871bb05f34ffb705534dfef5 https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.5-py314h6e9b3f0_0.conda#cdbafe4a3e605024e7372c9580f9d734 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 -https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.2-hce30654_0.conda#ca730d8e7d1de1f71013edfef0e08f13 +https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.3-hce30654_0.conda#6dcc75ba2e04c555e881b72793d3282f https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.3.0-py314hf9f5e1b_1.conda#036584b863246f278f4057327c36a94d https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 @@ -118,29 +118,31 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_8.conda#06c1a0f7eb6c393e16cc99e280784b36 https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_4.conda#22eb76f8d98f4d3b8319d40bda9174de -https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-5_h8d724d3_accelerate.conda#c32b3b0d73d5cb1ab2a095a69bf3a7bd +https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.32-openmp_he657e61_0.conda#3a1111a4b6626abebe8b978bb5a323bf https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.19.0-py314h6cfcd04_0.conda#0c8942bc23758aaeafed2707902fc48e https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_he8a363d_4.conda#76c651b923e048f3f3e0ecb22c966f70 -https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-5_h752f6bc_accelerate.conda#e5733907c1c77e6db5012c299e42a5ad -https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-5_hcb0d94e_accelerate.conda#3b5a735865842f8d6bf8b78b376ca9e1 +https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-6_h51639a9_openblas.conda#e551103471911260488a02155cef9c94 +https://conda.anaconda.org/conda-forge/osx-arm64/openblas-0.3.32-openmp_hea878ba_0.conda#314abb0d8622fa7d95915e53bb511922 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_4.conda#caf7c8e48827c2ad0c402716159fe0a2 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_hd01ab73_4.conda#0d059c5db9d880ff37b2da53bf06509e -https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-5_hbdd07e9_accelerate.conda#29c7d09cbe6d342ced64b0447e1f3792 +https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-6_hb0561ab_openblas.conda#805c6d31c5621fd75e53dfcf21fb243a +https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-6_hd9741b5_openblas.conda#ee33d2d05a7c5ea1f67653b37eb74db1 +https://conda.anaconda.org/conda-forge/osx-arm64/liblapacke-3.11.0-6_h1b118fd_openblas.conda#0151c0418077e835952ceee67a0ea693 https://conda.anaconda.org/conda-forge/osx-arm64/libtorch-2.10.0-cpu_generic_hf7cc835_3.conda#98f89ad42eaba858443d31336677aed2 https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.3-py314h1569ea8_0.conda#0fab9cf4fc5163131387f36742b50c79 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 -https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-5_h55bc449_accelerate.conda#6696b095e91860523bcc97303e11d30d +https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-6_h11c0a38_openblas.conda#923a8c7dd5c8ae2d5a3aff4e1e579337 https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py314hf8a3a22_4.conda#cddc851000ce131d757678c2f329eaad https://conda.anaconda.org/conda-forge/osx-arm64/pandas-3.0.1-py314h5e21a50_0.conda#840cec8154769d52f65f0fdaaf4aa4c9 https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.10.0-cpu_generic_py314_he36690f_3.conda#51da3d684a7d90b35adfd742fb551cc4 https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.1-py314hfc1f868_0.conda#7806ce54b78b0b11517b465a3398e910 -https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.305-accelerate.conda#5f941c90faaca70599ef8302d0c2738f +https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.306-openblas.conda#4cd635f3755993f4658959c2b3e1f2ef https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py314hd63e3f0_0.conda#c84152e510d41378b8758826655b6ed7 https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py314h95ce61a_1.conda#44282cc9330eb206f808c4f5be281fe2 https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.10.0-cpu_generic_hcc7c195_3.conda#e7ebf31f2c197adaba9bbf84a40dffd9 diff --git a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock index 96abccca3836d..c5cac4cedeb9c 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -12,7 +12,7 @@ https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa @@ -47,11 +47,11 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 # pip meson @ https://files.pythonhosted.org/packages/0b/78/7d049e63e624d51d0065191dae101a1e36d5d3a2360633772d9ad8afb2d5/meson-1.10.2-py3-none-any.whl#sha256=5f84ef186e6e788d9154db63620fc61b3ece69f643b94b43c8b9203c43d89b36 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa -# pip numpy @ https://files.pythonhosted.org/packages/7e/eb/7daecbea84ec935b7fc732e18f532073064a3816f0932a40a17f3349185f/numpy-2.4.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=d5f51900414fc9204a0e0da158ba2ac52b75656e7dce7e77fb9f84bfa343b4cc +# pip numpy @ https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83 # pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 # pip pillow @ https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 -# pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +# pip pygments @ https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl#sha256=81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # pip pyparsing @ https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl#sha256=850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d # pip roman-numerals @ https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl#sha256=647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7 # pip six @ https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl#sha256=4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 @@ -70,7 +70,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl#sha256=85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 -# pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 +# pip requests @ https://files.pythonhosted.org/packages/56/5d/c814546c2333ceea4ba42262d8c4d55763003e767fa169adc693bd524478/requests-2.33.0-py3-none-any.whl#sha256=3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b # pip scipy @ https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 # pip lightgbm @ https://files.pythonhosted.org/packages/42/86/dabda8fbcb1b00bcfb0003c3776e8ade1aa7b413dff0a2c08f457dace22f/lightgbm-4.6.0-py3-none-manylinux_2_28_x86_64.whl#sha256=cb19b5afea55b5b61cbb2131095f50538bd608a00655f23ad5d25ae3e3bf1c8d # pip matplotlib @ https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index e160be9560933..1428eb0a8af20 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -25,7 +25,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.cond https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda#e7df0aab10b9cbb73ab2a467ebfaf8c7 https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d5cf_1.conda#8ec1d03f3000108899d1799d9964f281 https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda#a9138815598fe6b91a1d6782ca657b0c -https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.4-hfae3067_0.conda#57f3b3da02a50a1be2a6fe847515417d +https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.5-hfae3067_0.conda#05d1e0b30acd816a192c03dc6e164f4d https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda#2f364feefb6a7c00423e80dcb12db62a https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda#4feebd0fbf61075a1a9c2e9b3936c257 https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda#574d88ce3348331e962cfa5ed451b247 @@ -34,7 +34,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5c https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda#96944e3c92386a12755b94619bae0b35 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.55-h1abf092_0.conda#be4088903b94ea297975689b3c3aeb27 +https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.56-h1abf092_0.conda#d5aff85583507906d19696d4961f4738 https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda#cf2861212053d05f27ec49c3784ff8bb https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af @@ -54,7 +54,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlidec-1.2.0-he30d5cf https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf_1.conda#6553a5d017fe14859ea8a4e6ea5def8f https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda#2079727b538f6dd16f3fa579d4c3c53f https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda#fb640d776fc92b682a14e001980825b1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.2-hdae7a39_0.conda#69d1cdfdabb66464cbde17890e8be3b9 +https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda#b99ed99e42dafb27889483b3098cace7 https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda#41f261f5e4e2e8cbd236c2f1f15dae1b https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.3.0-h5ad3122_1.conda#c11818b31f7c054ce220041b2459aacb https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 @@ -71,9 +71,9 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.co https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.2-h185addb_0.conda#728e129e280ddc3b4885fd3bc64a9f58 https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda#d9ca108bd680ea86a963104b6b3e95ca -https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.2-h8af1aa0_0.conda#93bce8dee6a0a4906331db294ec250fe +https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda#a229e22d4d8814a07702b0919d8e6701 https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_1.conda#4ac4372fc4d7f20630a91314cdac8afd -https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.30-pthreads_h9d3fd7e_4.conda#11d7d57b7bdd01da745bbf2b67020b2e +https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.32-pthreads_h9d3fd7e_0.conda#5d2ce5cf40443d055ec6d33840192265 https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda#77891484f18eca74b8ad83694da9815e https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda#e3ec9079759d35b875097d6a9a69e744 @@ -87,13 +87,13 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-hd651790_1.con https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.28-h6598af7_1.conda#f4fbf4001970e3e58984281a12c99969 https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda#a4b6b82427d15f0489cef0df2d82f926 https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda#0fed1ff55f4938a65907f3ecf62609db -https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.2-h8af1aa0_0.conda#9cb47d7bbb36646c44d7cf1cb8047887 +https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.3-h8af1aa0_0.conda#f11edf8adf0d119148b97f745548390d https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda#bb960f01525b5e001608afef9d47b79c -https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-5_haddc8a3_openblas.conda#5afcea37a46f76ec1322943b3c4dfdc0 +https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-6_haddc8a3_openblas.conda#652bb20bb4618cacd11e17ae070f47ce https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h4f2b762_6.conda#67828c963b17db7dc989fe5d509ef04a https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda#19de96909ee1198e2853acd8aba89f6c -https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.30-pthreads_h3a8cbd8_4.conda#e3f245ed352bd66d181b73a78d886038 +https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.32-pthreads_h3a8cbd8_0.conda#62e1383bcaf8f5244d2598bbda509e3b https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.15-h91f4b29_0_cpython.conda#bb09184ea3313703da05516cd730e8f8 https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-image-0.4.0-h5c728e9_2.conda#b82e5c78dbbfa931980e8bfe83bce913 @@ -108,10 +108,11 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.4-py311hdc11669_ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.5.0-py311h229e7f7_0.conda#aeade47300d466d9d6ba01daaca31a86 -https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-5_hd72aa62_openblas.conda#0b2f1143ae2d0aa4c991959d0daaf256 +https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-6_hd72aa62_openblas.conda#939e300b110db241a96a1bed438c315b https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda#0d00176464ebb25af83d40736a2cd3bb -https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-5_h88aeb00_openblas.conda#88d1e4133d1182522b403e9ba7435f04 -https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.1-hfd2ba90_0.conda#9684eec87b0eb9c81c6b95dfcbe574a0 +https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-6_h88aeb00_openblas.conda#e23a27b52fb320687239e2c5ae4d7540 +https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm21-21.1.8-hfd2ba90_0.conda#de59c5148c2a8347c02e437e3ed242a0 +https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.2-hfd2ba90_0.conda#c1911bb134ed245ce090fdf23079a6f8 https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b @@ -120,14 +121,14 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h2fb54aa_1. https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.1-py311h8e17b9e_0.conda#2f611dceeef334e4d3448944bf714277 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.3-py311hb9158a3_0.conda#e3afe76a49a1a9f85e0c5cd42a408e68 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.5-py311hb9158a3_0.conda#8776b78b9f2532ef4f0e2acc8f03f755 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-aarch64/unicodedata2-17.0.1-py311h19352d5_0.conda#22df73a2e312d88d56f6986e0a287edb https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-cursor-0.1.6-he30d5cf_0.conda#8b70063c86f7f9a0b045e78d2d9971f7 @@ -140,11 +141,11 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.7-he30d https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.5-py311h2dad8b0_0.conda#d3bcad889948820993ded0b13c2ae906 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.62.0-py311h164a683_0.conda#d3ef6350930100e30aaf0ecdf4e4dd3a -https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-13.2.0-h1134a53_0.conda#68508785d05856e4a053bf3d152fba95 +https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-13.2.1-h1134a53_0.conda#05d65a2cf410adc331c9ea61f59f1013 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp22.1-22.1.0-default_he95a3c9_0.conda#1519a50e2f4caca01098a33d39f45f5c +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_3.conda#4ba7653ca09e74e8968120c6aea4bfb1 https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.0-default_h94a09a5_0.conda#4e1023aa62d0919a4014954d57bcb786 -https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-5_hb558247_openblas.conda#8046d5ae90150f00c8b40455d9b2e180 +https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-6_hb558247_openblas.conda#12da32239ec4cc63d4f94d83b8425947 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.3-h7d4fc67_0.conda#7eb18b198b1d35da9352062c69c4ee64 https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.341.0-h8b8848b_0.conda#06bb91a87fb97ea09398d2e121e00c39 https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py311h669026d_0.conda#23c6d37dec83159283cfeee4fceebf84 @@ -152,16 +153,16 @@ https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 -https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-5_h9678261_openblas.conda#33a0e650392a79b56ae0bfa3db02ddbf +https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-6_h9678261_openblas.conda#64fe76410feeef76a105b2343edc4af7 https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311h04741b4_4.conda#1eeea54b0c520a475db39f8c711de661 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.10.2-pl5321h598db47_6.conda#a2be7073b12891aab9fa91ca005c5a6b +https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.11.0-pl5321h598db47_2.conda#811e17440391dbcbb67032931cd2e752 https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.1-py311h399493a_0.conda#be28b3d39c6942f89652b505e85ae3d6 -https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.305-openblas.conda#2efe635198609d0d2a122c6a0923b8f8 +https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.306-openblas.conda#cc7cac46a53a5c76f20439cb298d10a2 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 -https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.10.2-py311hb02cd75_1.conda#3db17f3d74ea130f9c0058f0567d5f44 +https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.11.0-py311hb02cd75_0.conda#8a634ae402ca677dd0fc4d6e08226389 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.8-py311hfecb2dc_0.conda#3920b856b59a909812f1913b96adaad8 diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 9058684192285..fea5857318fc9 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -12,7 +12,7 @@ https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.0-h4922eb0_0.conda#5e7da5333653c631d27732893b934351 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.2-h4922eb0_0.conda#2a60ab96432bc74eedbcda8a528080a1 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 @@ -26,9 +26,9 @@ https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2f https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda#f9f81ea472684d75b9dd8d0b328cf655 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 -https://conda.anaconda.org/conda-forge/linux-64/libattr-2.5.2-hb03c661_1.conda#7e7f0a692eb62b95d3010563e7f963b6 +https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499cd8e2d4358986dbe3b30e8fe1bf6a https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -41,7 +41,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb03c661_3.conda# https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 @@ -55,7 +55,6 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.2-hb03c661_1.conda#9bb149f49de3f322fca007283eaa2725 https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.8.23-hd590300_0.conda#cc4f06f7eedb1523f3b83fd0fb3942ff https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d @@ -68,11 +67,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de +https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda#8ee3cb7f64be0e8c4787f3a4dbe024e6 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -95,9 +95,8 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb5 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda#d1db1b8be7c3a8983dcbbbfe4f0765de https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.conda#081aa22f4581c08e4372b0b6c2f8478e https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.conda#1f0a03af852a9659ed2bf08f2f1704fd -https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-h3ff7636_0.conda#09c264d40c67b82b49a3f3b89037bd2e https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d @@ -121,7 +120,7 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.cond https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.2-ha770c72_0.conda#eeec961fec28e747e1e1dc0446277452 +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda#b52b769cd13f7adaa6ccdc68ef801709 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 @@ -129,7 +128,6 @@ https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 -https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda#8ee3cb7f64be0e8c4787f3a4dbe024e6 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -160,7 +158,7 @@ https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.2-hf7376ad_0.conda#7147b0792a803cd5b9929ce5d48f7818 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 @@ -173,15 +171,15 @@ https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7 https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.2.0-pyha21a80b_0.conda#978d03388b62173b8e6f79162cf52b86 https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.3-py311h49ec1c0_0.conda#a0d8cab7384ccfca582b952d9c8c619a +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda#73b44a114241e564deb5846e7394bf19 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py311h49ec1c0_0.conda#2889f0c0b6a6d7a37bd64ec60f4cc210 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 @@ -195,7 +193,7 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.0-h6083320_0.conda#71c2c966e17a65b08b995f571310fb9f +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a @@ -211,7 +209,7 @@ https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.con https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 -https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hadf4263_0.conda#79f71230c069a287efe3a8614069ddf1 +https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda#d53ffc0edc8eabf4253508008493c5bc https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 @@ -228,7 +226,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h7b9373a_16. https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h0c412b5_8.conda#80e27e7982af989ebc2e0f0d57c75ea7 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.0-pyhcf101f3_0.conda#bee5ed456361bfe8af502beaf5db82e2 https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 763d14eebab18..cb602ebd902d8 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -13,14 +13,14 @@ https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_ https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -33,7 +33,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.c https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.2-h73754d4_0.conda#8eaba3d1a4d7525c6814e861614457fd +https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -42,13 +42,13 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 -https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.2-ha770c72_0.conda#26c746d14402a3b6c684d045b23b9437 -https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 +https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 -https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-pthreads_h6ec200e_4.conda#379ec5261b0b8fc54f2e7bd055360b0c +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e +https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.32-pthreads_h6ec200e_0.conda#2e9cf6ff9a29b98a4faf627f2eb2cdb7 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a @@ -66,14 +66,14 @@ https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd @@ -81,28 +81,28 @@ https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339 https://conda.anaconda.org/conda-forge/noarch/snowballstemmer-3.0.1-pyhd8ed1ab_0.conda#755cf22df8693aa0d1aec1c123fa5863 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_h6ae95b6_openblas.conda#af6df8ece92110c951032683af64f1fa https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py311h2e04523_0.conda#cfc8f864dea571677095ebae8e6f0c07 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_h1ea3ea9_openblas.conda#064f82e2cd0146b28a0bda3ca9b6fb7e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.conda#3ac73c673df24589b5b84d43a4afd235 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-openblas.conda#81122e5749efe4c34c07471ad866eab1 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.32.5-pyhcf101f3_1.conda#c65df89a0b2e321045a9e01d1337b182 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.0-pyhcf101f3_0.conda#bee5ed456361bfe8af502beaf5db82e2 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda#16e3f039c0aa6446513e94ab18a8784b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda#910f28a05c178feba832f842155cbfff diff --git a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock index fe77ea4ada29f..7031254c0123d 100644 --- a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock @@ -25,13 +25,13 @@ https://conda.anaconda.org/conda-forge/win-64/icu-78.3-h637d24d_0.conda#0097b248 https://conda.anaconda.org/conda-forge/win-64/lerc-4.1.0-hd936e49_0.conda#54b231d595bc1ff9bff668dd443ee012 https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda#444b0a45bbd1cb24f82eedb56721b9c4 https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e -https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.4-hac47afa_0.conda#1c1ced969021592407f16ada4573586d +https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.5-hac47afa_0.conda#bfb43f52f13b7c56e7677aa7a8efdf0c https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda#720b39f5ec0610457b725eb3f396219a https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda#b085746891cca3bd2704a450a7b4b5ce https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#64571d1dd6cdcfa25d0664a5950fdaa2 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda#56a686f92ac0273c0f6af58858a3f013 https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda#ba0bfd4c3cf73f299ffe46ff0eaeb8e3 -https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.30-pthreads_h877e47f_4.conda#f551f8ae0ae6535be1ffde181f9377f3 +https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.32-pthreads_h877e47f_0.conda#cb7bb86e848c806cf3f0a182fcdf77da https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda#8830689d537fda55f990620680934bb1 https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.341.0-h477610d_0.conda#804880b2674119b84277d6c16b01677d https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda#f9bbae5e2537e3b06e0f7310ba76c893 @@ -43,13 +43,13 @@ https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda#854f https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda#0481bfd9814bf525bd4b3ee4b51494c4 https://conda.anaconda.org/conda-forge/win-64/zlib-ng-2.3.3-h0261ad2_1.conda#46a21c0a4e65f1a135251fc7c8663f83 https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda#4432f52dc0c8eb6a7a6abc00a037d93c -https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-5_h0adab6e_openblas.conda#bae34d8f039de36cc4384371aa12bd61 +https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-6_h0adab6e_openblas.conda#11b6a32e75b36340f4d86e19dad1b1dc https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda#450e3ae947fc46b60f1d8f8f318b40d4 https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda#ccd93cfa8e54fd9df4e83dbe55ff6e8c https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda#2cf0cf76cc15d360dfa2f17fd6cf9772 -https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.55-h7351971_0.conda#43f47a9151b9b8fc100aeefcf350d1a0 +https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.56-h7351971_0.conda#bedc0fc6a8fb31b8013878ea20c76bae https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h3cfd58e_0.conda#f6dd496a1f2b66951110a3a0817f699b -https://conda.anaconda.org/conda-forge/win-64/openblas-0.3.30-pthreads_h4a7f399_4.conda#482e61f83248a880d180629bf8ed36b2 +https://conda.anaconda.org/conda-forge/win-64/openblas-0.3.32-pthreads_h4a7f399_0.conda#d7b743c101c58cf009ec7a887e49489f https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda#77eaf2336f3ae749e712f63e36b0f0a1 https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda#3c8f2573569bb816483e5cf57efbbe29 https://conda.anaconda.org/conda-forge/win-64/python-3.11.15-h0159041_0_cpython.conda#d09dbf470b41bca48cbe6a78ba1e009b @@ -63,11 +63,11 @@ https://conda.anaconda.org/conda-forge/win-64/cython-3.2.4-py311h9990397_0.conda https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.5.0-py311h275cad7_0.conda#e50d15677f2673c114f18d60c88d9196 -https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-5_h2a8eebe_openblas.conda#1db756824d3aec6a25599c7821cb3e24 +https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-6_h2a8eebe_openblas.conda#56ab25cf3cbce9e3a809e3e89739b5a8 https://conda.anaconda.org/conda-forge/win-64/libclang13-22.1.0-default_ha2db4b5_0.conda#7ad437870ea7d487e1b0e663503b6b1d -https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.2-hdbac1cb_0.conda#c21a474a38982cdb56b3454cf4f78389 +https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_0.conda#f9975a0177ee6cdda10c86d1db1186b0 https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.4-h0c9aed9_1.conda#0329a7e92c8c8b61fcaaf7ad44642a96 -https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-5_hd232482_openblas.conda#78240c2b4322025a74e7e6edad247103 +https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-6_hd232482_openblas.conda#06d2ad5bf21e9b86c46783833b2e3c42 https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h779ef1b_0.conda#be3843e412c9f9d697958aa68c72d09d @@ -75,14 +75,14 @@ https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.4-py311h3485c13_0.conda#6e8d1faf5c0c08641c151e0fb79cb4db +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py311h3485c13_0.conda#b004afcc680af88cb877978e71d42667 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.1-py311h3485c13_0.conda#e6badeb53d9bc5cccebe46a62c5a7336 https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda#bc58fdbced45bb096364de0fba1637af @@ -90,30 +90,30 @@ https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.5-py311h3f79411_0.co https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/win-64/lcms2-2.18-hf2c6c5f_0.conda#b6c68d6b829b044cd17a41e0a8a23ca1 -https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.2-h57928b3_0.conda#153d52fd0e4ba2a5bd5bb4f4afa41417 -https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-5_hbb0e6ff_openblas.conda#b96fdd694dc8b7a5869613121c40d086 +https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_0.conda#d9f70dd06674e26b6d5a657ddd22b568 +https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-6_hbb0e6ff_openblas.conda#7111f949f68a554498655d268b5fa7a5 https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.3-py311h65cb7f3_0.conda#e37a9cfab4d96b7945119a3095087648 https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h0e57b4f_0.conda#e723ab7cc2794c954e1b22fde51c16e4 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f -https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-5_ha590de0_openblas.conda#e19a49b16cf765708e6d8676a50f74e1 +https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-6_ha590de0_openblas.conda#085478f89f9e91d9e2cf6e81b9f4665b https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h275cad7_4.conda#9fb1f375c704c5287c97c60f6a88d137 https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda#a0b1b87e871011ca3b783bbf410bc39f https://conda.anaconda.org/conda-forge/win-64/fonttools-4.62.0-py311h3f79411_0.conda#5abfb5569386a6a7e8f6f88d4845af10 -https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.2-h57928b3_0.conda#c360b467564b875a9f5dc481b8726cee +https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_0.conda#507b36518b5a595edda64066c820a6ef https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.1-py311h17b8079_0.conda#b17fe050184f2f7fd03e094a5fdc56ae https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.1-py311h9c22a71_0.conda#24047b0ff1fa264427c456e4c7f68283 -https://conda.anaconda.org/conda-forge/win-64/blas-2.305-openblas.conda#19bbf270f61bbef238e16a9509377a52 +https://conda.anaconda.org/conda-forge/win-64/blas-2.306-openblas.conda#8fe2bc7bfe72359526e4e94b018853a3 https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda#52ea1beba35b69852d210242dd20f97d https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/win-64/harfbuzz-13.2.0-h5a1b470_0.conda#92901fd2086b94a243abc5da33cfa87d -https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.10.2-pl5321hfcac499_6.conda#d5a2b237ad30f01d4f9474313c1ef1c4 -https://conda.anaconda.org/conda-forge/win-64/pyside6-6.10.2-py311he824864_1.conda#980f3c2f9a93d8b68990133a76d2b667 +https://conda.anaconda.org/conda-forge/win-64/harfbuzz-13.2.1-h5a1b470_0.conda#f6414f2f905326bcf0e7c87a04d175a2 +https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.0-pl5321hfcac499_3.conda#b53193a38f677045dae28f7039122035 +https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.0-py311he824864_0.conda#4f0afbd4b6e9d6e5d6c32cd5edcb0eb7 https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py311h1ea47a8_0.conda#64fe28aa2486e41918239d385336e88e diff --git a/build_tools/github/ubuntu_atlas_lock.txt b/build_tools/github/ubuntu_atlas_lock.txt index 99eeff36b60bc..dacb78ac3024b 100644 --- a/build_tools/github/ubuntu_atlas_lock.txt +++ b/build_tools/github/ubuntu_atlas_lock.txt @@ -25,7 +25,7 @@ packaging==26.0 # pytest pluggy==1.6.0 # via pytest -pygments==2.19.2 +pygments==2.20.0 # via pytest pyproject-metadata==0.11.0 # via meson-python From 2bc926fb00ca48a72ff25dbbb3650931baa1072b Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 30 Mar 2026 04:20:24 -0400 Subject: [PATCH 312/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33661) Co-authored-by: Lock file bot <noreply@github.com> --- ...a_forge_cuda_array-api_linux-64_conda.lock | 97 ++++++++++--------- 1 file changed, 50 insertions(+), 47 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index d8b6052e3fe2d..507e2b98f7e87 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -8,8 +8,8 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.26.0-ha770c72_0.conda#cb93c6e226a7bed5557601846555153d +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_10.conda#590b5a14299d67b9669fe5eb1fdd4d3b https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 -https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a66894dfd07c4510beb6b3f9672ccc0 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 @@ -24,7 +24,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/noarch/libnvptxcompiler-dev_linux-64-12.9.86-ha770c72_2.conda#a66a909acf08924aced622903832a937 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.1-h4922eb0_0.conda#0e6b63a4861d9b63cde30993bfc0846d +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.2-h4922eb0_0.conda#2a60ab96432bc74eedbcda8a528080a1 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_linux-64-12.9.79-h3f2d84a_0.conda#86e40eb67d83f1a58bdafdd44e5a77c6 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -46,7 +46,7 @@ https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499cd8e2d4358986dbe3b30e8fe1bf6a https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -57,7 +57,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb9d3cd8_0.conda#db63358239cbe1ff86242406d440e44a https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.55-h421ea60_0.conda#5f13ffc7d30ffec87864e678df9957b4 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 @@ -135,7 +135,6 @@ https://conda.anaconda.org/conda-forge/linux-64/libcusparse-12.5.10.65-hecca717_ https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d -https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-openmp_hd680484_4.conda#c0512e4f60d62ccccb4c3c8333b33608 https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 https://conda.anaconda.org/rapidsai/linux-64/librmm-26.02.00-cuda12_260204_498dafcf.conda#057e94dab29e9c69b4542eb0c61b161e @@ -160,7 +159,6 @@ https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce9 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 https://conda.anaconda.org/conda-forge/linux-64/libcublas-dev-12.9.1.4-h676940d_1.conda#f90f4ff087ac29005c6989ea0fb2735a https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.conda#a178a1f3642521f104ecceeefa138d01 https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_1.conda#c5b8ea827c65e5811d61aa49cd0bae9a @@ -173,7 +171,6 @@ https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8 https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-26.02.00-cuda12_260204_c212ab9b.conda#702a98df50c3b8be134516647a217fde https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa -https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.30-openmp_hd77311e_4.conda#525e2455ed342f2aef93c59ac5db2e28 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d @@ -190,27 +187,27 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.4.4-pyhc364b38_0.conda#e596a2fd285b8c9561aaf37b65b00e94 +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.0-pyhc364b38_0.conda#a18297fed4097f00f58d64a8191f9881 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.2.0-pyhd8ed1ab_0.conda#496c6c9411a6284addf55c898d6ed8d7 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py313hc8edb43_0.conda#b81883b9dbf5069821c2fb09a8ba1407 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-dev-11.7.5.82-h676940d_2.conda#0fe12e558abf507458bcec839e29778d https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.1-hf7376ad_0.conda#97cc6dad22677304846a798c8a65064d +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f +https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.2-hf7376ad_0.conda#7147b0792a803cd5b9929ce5d48f7818 https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/llvmlite-0.44.0-py313hfdae721_2.conda#dd0d7947635c0c524608eab7db55dcc9 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda#aeb9b9da79fd0258b3db091d1fefcd71 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b -https://conda.anaconda.org/conda-forge/linux-64/mpc-1.3.1-h24ddda3_1.conda#aa14b9a5196a6d8dd364164b7ce56acf +https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b @@ -222,14 +219,14 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.4-py313hd02dea0_0.conda#442d7ac35e5d6bc89eba2998a9e1de06 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda#6c0b0ae017b5bfd9c8d718217efd8f14 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 @@ -249,70 +246,76 @@ https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py313h86d8783_1.cond https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-5_h6ae95b6_openblas.conda#e487a0e38d89da76410cb92a5db39ec5 -https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.12-h4df99d1_100.conda#3d92938d5b83c49162ade038aab58a59 +https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py313h246eb7c_1.conda#8526afdb4ae2d95db733c4188f092f01 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h4c8aef7_3.conda#798a499cf76e530a992365d557ba5827 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-5_h1ea3ea9_openblas.conda#45c6e304872e33ebc43b2456d68fe00d -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 -https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.6.0-cuda12_py313hacc9b55_0.conda#1986c17fb0b8184289ea7d6fc8ba4b34 https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.conda#8d3dbe5292af711edd6df92c68e55a89 -https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py313h28b6081_0.conda#fe933a91c19fa88788b4204b6ba67ba2 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac -https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_generic_hb019b6b_203.conda#5e373fc37a76270b4454c02cb126ab34 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.conda#84cef0ce56c6db53edb3f8b83bdbb364 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py313h7037e92_0.conda#21f1c403983c8a4e067ba6eec6b878ec -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py313hbfd7664_0.conda#1c8807728f0333228766dee685394e16 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.10.2-pl5321h16c4a6b_6.conda#3a00bff44c15ee37bfd5eb435e1b2a51 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_2.conda#c6ba2de6b22dedf2f20eba3bde1dbe8e https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.305-openblas.conda#b5a8cdf31d419b93058163399b691c75 -https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py313h7fc6698_0.conda#41368ea5c4c7c607ac98ecab56833535 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 -https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba -https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.10.2-py313hcd51b16_1.conda#745f9c0ffaf06cea2e68e12259ace5b5 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py313hcd51b16_0.conda#81412e7d848362a09a30ede0776e657b https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_generic_py313_hb8e8477_203.conda#6cfb64f7fc401f2c7c789214237aea24 -https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f -https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda#d5a4e013a30dd8dfde9ab39f45aaf9c1 -https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_generic_h1715cf7_203.conda#969fd0ea1b469425630712ba3513deff -https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_9_cpu.conda#b3ba3597c481a636fc161185819cf6b1 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 +https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_9_cpu.conda#2dccf1b6cf9dba8857050740dbc0497e -https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 +https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 +https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.6.0-cuda12_py313hacc9b55_0.conda#1986c17fb0b8184289ea7d6fc8ba4b34 +https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py313h28b6081_0.conda#fe933a91c19fa88788b4204b6ba67ba2 https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 -https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be -https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea +https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_mkl_hd6d2a1f_303.conda#5b8a8672aca66f3871aab4d0d1a8f796 +https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.conda#84cef0ce56c6db53edb3f8b83bdbb364 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py313hbfd7664_0.conda#1c8807728f0333228766dee685394e16 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py313h98bfbea_0_cpu.conda#d2b771a9050c52941a61a72f2d161c64 +https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 +https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 +https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py313h7fc6698_0.conda#41368ea5c4c7c607ac98ecab56833535 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_9_cpu.conda#9c5282b7aaf2261d3dbe5a61d24d5337 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 +https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 +https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_mkl_py313_h623d66f_303.conda#14135d5ee1f06598b4714f2fce2af13c +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_9_cpu.conda#d5338f154126253750e8ccc539386b92 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b +https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_mkl_h0d04637_303.conda#1050dc8cf80cd0a9e63f361c12ee0e82 +https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 +https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py313h78bf25f_0.conda#bd299f66ab2d10d1e03d4148397fe263 +https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be +https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.02.00-cuda12_260204_a2f5a8b7.conda#361cae27e77618c6ba9f943807471f9f https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.02.00-cuda12_py313_260204_c212ab9b.conda#14933b753ec82f9d5a61d7cb4b5e2e71 https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.02.00-cuda12_py313_260204_a2f5a8b7.conda#c46807878ad576379e7be3acc187d13a -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_9_cpu.conda#d5338f154126253750e8ccc539386b92 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py313h78bf25f_0.conda#bd299f66ab2d10d1e03d4148397fe263 From 0be102558041da19a0e50784ae92164f59fb17a7 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 30 Mar 2026 04:20:48 -0400 Subject: [PATCH 313/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33660) Co-authored-by: Lock file bot <noreply@github.com> --- .../pylatest_free_threaded_linux-64_conda.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index f41d4fc00e08a..f8d859674b47c 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -12,7 +12,7 @@ https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 @@ -29,24 +29,24 @@ https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.cond https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 -https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.30-pthreads_h94d23a6_4.conda#be43915efc66345cccb3c310b6ed0374 +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-5_h4a7cf45_openblas.conda#c160954f7418d7b6e87eaf05a8913fa9 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-he1279bd_1_cp314t.conda#19b5d632d02f56f9f95ce07dc1e086b5 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_1.conda#83eaa6b45bd9d99a26d673a4d50138b3 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.conda#cc2fcbfdf0628b5ad05b319866187bbc https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-5_h0358290_openblas.conda#6636a2b6f1a87572df2970d3ebc87cc0 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-5_h47877c9_openblas.conda#b38076eb5c8e40d0106beda6f95d7609 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/noarch/pygments-2.19.2-pyhd8ed1ab_0.conda#6b6ece66ebcae2d5f326c77ef2c5a066 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.0-pyhcf101f3_0.conda#72e780e9aa2d0a3295f59b1874e3768b +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 From ca6a8919abff3cfbbf19939cd69bea5cba85cf7b Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 30 Mar 2026 04:21:11 -0400 Subject: [PATCH 314/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33659) Co-authored-by: Lock file bot <noreply@github.com> --- .../github/pylatest_pip_scipy_dev_linux-64_conda.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index 7983090053384..86df152ce5556 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -12,7 +12,7 @@ https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.4-hecca717_0.conda#e7f7ce06ec24cfcfb9e36d28cf82ba57 +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa @@ -45,7 +45,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 # pip platformdirs @ https://files.pythonhosted.org/packages/63/d7/97f7e3a6abb67d8080dd406fd4df842c2be0efaf712d1c899c32a075027c/platformdirs-4.9.4-py3-none-any.whl#sha256=68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 -# pip pygments @ https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl#sha256=86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b +# pip pygments @ https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl#sha256=81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # pip roman-numerals @ https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl#sha256=647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7 # pip six @ https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl#sha256=4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 # pip snowballstemmer @ https://files.pythonhosted.org/packages/c8/78/3565d011c61f5a43488987ee32b6f3f656e7f107ac2782dd57bdd7d91d9a/snowballstemmer-3.0.1-py3-none-any.whl#sha256=6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064 @@ -61,7 +61,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl#sha256=85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 -# pip requests @ https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl#sha256=2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6 +# pip requests @ https://files.pythonhosted.org/packages/56/5d/c814546c2333ceea4ba42262d8c4d55763003e767fa169adc693bd524478/requests-2.33.0-py3-none-any.whl#sha256=3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b # pip meson-python @ https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl#sha256=67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298 # pip pooch @ https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl#sha256=f265597baa9f760d25ceb29d0beb8186c243d6607b0f60b83ecf14078dbc703b # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 From bbde180eb1cd90b042a8546f5c7bcac917e6eddf Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Mon, 30 Mar 2026 10:28:34 +0200 Subject: [PATCH 315/462] DOC Fix typo and add interactive mode to imports in example (#33612) --- examples/classification/plot_classification_probability.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/classification/plot_classification_probability.py b/examples/classification/plot_classification_probability.py index 737587c1f7596..54f9095d0b8e2 100644 --- a/examples/classification/plot_classification_probability.py +++ b/examples/classification/plot_classification_probability.py @@ -8,7 +8,7 @@ probabilities of various classifiers in a 2D feature space, mostly for didactic purposes. -The first three columns shows the predicted probability for varying values of +The first three columns show the predicted probability for varying values of the two features. Round markers represent the test data that was predicted to belong to that class. @@ -20,6 +20,7 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause +# %% import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np @@ -151,6 +152,7 @@ response_method="predict_proba", class_of_interest=None, ax=axes[classifier_idx, len(y_unique)], + multiclass_colors="viridis", vmin=0, vmax=1, levels=levels, @@ -198,7 +200,6 @@ # ----------------------- pd.DataFrame(evaluation_results).round(2) - # %% # Analysis # -------- From 6c3ec75200d795d4069ab66ebda56d444e79c9a7 Mon Sep 17 00:00:00 2001 From: "Christine P. Chai" <star1327p@gmail.com> Date: Mon, 30 Mar 2026 02:16:08 -0700 Subject: [PATCH 316/462] DOC: Correct a few typos in scikit-learn documentation (#33657) --- doc/developers/minimal_reproducer.rst | 4 ++-- examples/applications/plot_out_of_core_classification.py | 2 +- examples/cluster/plot_face_compress.py | 2 +- examples/covariance/plot_mahalanobis_distances.py | 4 ++-- sklearn/datasets/_base.py | 2 +- sklearn/ensemble/tests/test_gradient_boosting.py | 2 +- sklearn/linear_model/tests/test_sgd.py | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/doc/developers/minimal_reproducer.rst b/doc/developers/minimal_reproducer.rst index 147efd8d71a06..11ea0d886c74e 100644 --- a/doc/developers/minimal_reproducer.rst +++ b/doc/developers/minimal_reproducer.rst @@ -34,13 +34,13 @@ In this section we will focus on the **Steps/Code to Reproduce** section of the `Issue template <https://github.com/scikit-learn/scikit-learn/blob/main/.github/ISSUE_TEMPLATE/bug_report.yml>`_. We will start with a snippet of code that already provides a failing example but -that has room for readability improvement. We then craft a MCVE from it. +that has room for readability improvement. We then craft an MCVE from it. **Example** .. code-block:: python - # I am currently working in a ML project and when I tried to fit a + # I am currently working in an ML project and when I tried to fit a # GradientBoostingRegressor instance to my_data.csv I get a UserWarning: # "X has feature names, but DecisionTreeRegressor was fitted without # feature names". You can get a copy of my dataset from diff --git a/examples/applications/plot_out_of_core_classification.py b/examples/applications/plot_out_of_core_classification.py index 52ebd0862150d..2b0df1eed6640 100644 --- a/examples/applications/plot_out_of_core_classification.py +++ b/examples/applications/plot_out_of_core_classification.py @@ -52,7 +52,7 @@ def _not_in_sphinx(): class ReutersParser(HTMLParser): - """Utility class to parse a SGML file and yield documents one at a time.""" + """Utility class to parse an SGML file and yield documents one at a time.""" def __init__(self, encoding="latin-1"): HTMLParser.__init__(self) diff --git a/examples/cluster/plot_face_compress.py b/examples/cluster/plot_face_compress.py index 7a078d24fe16d..2c7541e645cde 100644 --- a/examples/cluster/plot_face_compress.py +++ b/examples/cluster/plot_face_compress.py @@ -28,7 +28,7 @@ # %% # Thus the image is a 2D array of 768 pixels in height and 1024 pixels in width. Each -# value is a 8-bit unsigned integer, which means that the image is encoded using 8 +# value is an 8-bit unsigned integer, which means that the image is encoded using 8 # bits per pixel. The total memory usage of the image is 786 kilobytes (1 byte equals # 8 bits). # diff --git a/examples/covariance/plot_mahalanobis_distances.py b/examples/covariance/plot_mahalanobis_distances.py index a1507c3ef162e..1298524734243 100644 --- a/examples/covariance/plot_mahalanobis_distances.py +++ b/examples/covariance/plot_mahalanobis_distances.py @@ -109,9 +109,9 @@ from sklearn.covariance import EmpiricalCovariance, MinCovDet -# fit a MCD robust estimator to data +# fit an MCD robust estimator to data robust_cov = MinCovDet().fit(X) -# fit a MLE estimator to data +# fit an MLE estimator to data emp_cov = EmpiricalCovariance().fit(X) print( "Estimated covariance matrix:\nMCD (Robust):\n{}\nMLE:\n{}".format( diff --git a/sklearn/datasets/_base.py b/sklearn/datasets/_base.py index 39a84d9a45ff8..de8b954e2dc90 100644 --- a/sklearn/datasets/_base.py +++ b/sklearn/datasets/_base.py @@ -911,7 +911,7 @@ def load_breast_cancer(*, return_X_y=False, as_frame=False): def load_digits(*, n_class=10, return_X_y=False, as_frame=False): """Load and return the digits dataset (classification). - Each datapoint is a 8x8 image of a digit. + Each datapoint is an 8x8 image of a digit. ================= ============== Classes 10 diff --git a/sklearn/ensemble/tests/test_gradient_boosting.py b/sklearn/ensemble/tests/test_gradient_boosting.py index 5434c12b5208a..51c090f747a90 100644 --- a/sklearn/ensemble/tests/test_gradient_boosting.py +++ b/sklearn/ensemble/tests/test_gradient_boosting.py @@ -1391,7 +1391,7 @@ def test_gradient_boosting_with_init_pipeline(): # Passing sample_weight to a pipeline raises a ValueError. This test makes # sure we make the distinction between ValueError raised by a pipeline that - # was passed sample_weight, and a InvalidParameterError raised by a regular + # was passed sample_weight, and an InvalidParameterError raised by a regular # estimator whose input checking failed. invalid_nu = 1.5 err_msg = ( diff --git a/sklearn/linear_model/tests/test_sgd.py b/sklearn/linear_model/tests/test_sgd.py index 4dc0aaf3e4f1f..fadb0f8f0fdff 100644 --- a/sklearn/linear_model/tests/test_sgd.py +++ b/sklearn/linear_model/tests/test_sgd.py @@ -2136,11 +2136,11 @@ def test_SGDClassifier_fit_for_all_backends(backend): X = _sparse_random_array((500, 2000), density=0.02, format="csr", rng=random_state) y = random_state.choice(20, 500) - # Begin by fitting a SGD classifier sequentially + # Begin by fitting an SGD classifier sequentially clf_sequential = SGDClassifier(max_iter=1000, n_jobs=1, random_state=42) clf_sequential.fit(X, y) - # Fit a SGDClassifier using the specified backend, and make sure the + # Fit an SGDClassifier using the specified backend, and make sure the # coefficients are equal to those obtained using a sequential fit clf_parallel = SGDClassifier(max_iter=1000, n_jobs=4, random_state=42) with joblib.parallel_backend(backend=backend): From cc4843adf8bcbbe8a6d70ae0b4f490e11c010fa5 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Mon, 30 Mar 2026 17:45:02 +0200 Subject: [PATCH 317/462] CI increase atol for `float32` and `array_api_strict` to make test pass for all seeds (#33639) --- sklearn/_loss/tests/test_link.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sklearn/_loss/tests/test_link.py b/sklearn/_loss/tests/test_link.py index 230538668eea0..08e63ad7b1671 100644 --- a/sklearn/_loss/tests/test_link.py +++ b/sklearn/_loss/tests/test_link.py @@ -11,6 +11,7 @@ _inclusive_low_high, ) from sklearn.utils._array_api import ( + _atol_for_type, move_to, yield_namespace_device_dtype_combinations, ) @@ -118,6 +119,7 @@ def test_link_inverse_array_api( rtol = 1e-3 if n_classes else 1e-4 else: rtol = 1e-8 + atol = _atol_for_type(dtype_name) with config_context(array_api_dispatch=True): raw_prediction_xp = xp.asarray(raw_prediction.astype(dtype_name), device=device) @@ -133,4 +135,5 @@ def test_link_inverse_array_api( move_to(link.link(y_pred_xp), xp=np, device="cpu"), link.link(y_pred), rtol=rtol, + atol=atol, ) From 70b05c98024aa3996ef82437932df1124251029f Mon Sep 17 00:00:00 2001 From: Reshama Shaikh <reshama.stat@gmail.com> Date: Wed, 1 Apr 2026 11:33:49 -0400 Subject: [PATCH 318/462] DOC update Comms team (#33604) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- build_tools/generate_authors_table.py | 4 +--- doc/communication_team.rst | 4 ---- doc/communication_team_emeritus.rst | 1 + 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/build_tools/generate_authors_table.py b/build_tools/generate_authors_table.py index 6dcddda40af4d..500a6dddd4fdb 100644 --- a/build_tools/generate_authors_table.py +++ b/build_tools/generate_authors_table.py @@ -104,13 +104,11 @@ def get_contributors(): emeritus_contributor_experience_team = { "cmarmo", } - emeritus_comm_team = {"reshamas"} + emeritus_comm_team = {"reshamas", "laurburke"} # Up-to-now, we can subtract the team emeritus from the original emeritus emeritus -= emeritus_contributor_experience_team | emeritus_comm_team - comm_team -= {"reshamas"} # in the comm team but not on the web page - # get profiles from GitHub core_devs = [get_profile(login) for login in core_devs] emeritus = [get_profile(login) for login in emeritus] diff --git a/doc/communication_team.rst b/doc/communication_team.rst index fb9666f0b42f7..cae5f9421c980 100644 --- a/doc/communication_team.rst +++ b/doc/communication_team.rst @@ -6,10 +6,6 @@ img.avatar {border-radius: 10px;} </style> <div> - <a href='https://github.com/laurburke'><img src='https://avatars.githubusercontent.com/u/35973528?v=4' class='avatar' /></a> <br /> - <p>Lauren Burke-McCarthy</p> - </div> - <div> <a href='https://github.com/francoisgoupil'><img src='https://avatars.githubusercontent.com/u/98105626?v=4' class='avatar' /></a> <br /> <p>François Goupil</p> </div> diff --git a/doc/communication_team_emeritus.rst b/doc/communication_team_emeritus.rst index d5ef7df59238e..858b605c73c5c 100644 --- a/doc/communication_team_emeritus.rst +++ b/doc/communication_team_emeritus.rst @@ -1 +1,2 @@ +- Lauren Burke-McCarthy - Reshama Shaikh From 94af1dff678e8a7a6fc627b85a5489980c063331 Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Thu, 2 Apr 2026 20:34:51 +1100 Subject: [PATCH 319/462] DOC Update docstring of `_array_api_for_tests` (#33673) --- sklearn/utils/_testing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/utils/_testing.py b/sklearn/utils/_testing.py index 1d89621858094..e0e4387606db2 100644 --- a/sklearn/utils/_testing.py +++ b/sklearn/utils/_testing.py @@ -1316,7 +1316,7 @@ def _array_api_for_tests(array_namespace, device_name=None): ------- xp : module The module object for the requested array namespace. - device : object or None + device : object, str or None The library specific device object that can be passed to xp.asarray(..., device=device). This might be a string and not a library specific device object. From 5014b30844bbd7f3fb5e368d1ae0d108f7736346 Mon Sep 17 00:00:00 2001 From: Shruti Nath <51656807+snath-xoc@users.noreply.github.com> Date: Fri, 3 Apr 2026 13:04:02 +0100 Subject: [PATCH 320/462] API Deprecate probA_ and probB_ in SVC and NuSVC (#33388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../upcoming_changes/sklearn.svm/33388.api.rst | 4 ++++ sklearn/svm/_base.py | 13 ++++++++++++- sklearn/svm/_classes.py | 14 +++++++++++++- sklearn/svm/tests/test_svm.py | 11 +++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.svm/33388.api.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.svm/33388.api.rst b/doc/whats_new/upcoming_changes/sklearn.svm/33388.api.rst new file mode 100644 index 0000000000000..ff03d806028e1 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.svm/33388.api.rst @@ -0,0 +1,4 @@ +- The `probA_` and `probB_` attributes of :class:`sklearn.svm.SVC` and + :class:`sklearn.svm.NuSVC` are deprecated due to deprecation of the + `probability` parameter and will be removed in 1.11. + By :user:`Shruti Nath <snath-xoc>`. diff --git a/sklearn/svm/_base.py b/sklearn/svm/_base.py index 855658bc3e3f8..ec4da689dc1c2 100644 --- a/sklearn/svm/_base.py +++ b/sklearn/svm/_base.py @@ -22,6 +22,7 @@ check_random_state, column_or_1d, compute_class_weight, + deprecated, ) from sklearn.utils._param_validation import Hidden, Interval, StrOptions from sklearn.utils._sparse import _align_api_if_sparse @@ -900,7 +901,7 @@ def predict_proba(self, X): datasets. """ X = self._validate_for_predict(X) - if self.probA_.size == 0 or self.probB_.size == 0: + if self._probA.size == 0 or self._probB.size == 0: raise NotFittedError( "predict_proba is not available when fitted with probability=False" ) @@ -1017,6 +1018,11 @@ def _get_coef(self): return coef + @deprecated( # type: ignore[prop-decorator] + "Attribute `probA_` was deprecated in version 1.9 and will be removed in " + "1.11 as the `probability=True` option for SVC and NuSVC was deprecated " + "and will be removed in 1.11." + ) @property def probA_(self): """Parameter learned in Platt scaling when `probability=True`. @@ -1027,6 +1033,11 @@ def probA_(self): """ return self._probA + @deprecated( # type: ignore[prop-decorator] + "Attribute `probB_` was deprecated in version 1.9 and will be removed in " + "1.11 as the `probability=True` option for SVC and NuSVC was deprecated " + "and will be removed in 1.11." + ) @property def probB_(self): """Parameter learned in Platt scaling when `probability=True`. diff --git a/sklearn/svm/_classes.py b/sklearn/svm/_classes.py index bf1fdac34e95d..54ce5b4feec54 100644 --- a/sklearn/svm/_classes.py +++ b/sklearn/svm/_classes.py @@ -811,16 +811,23 @@ class SVC(BaseSVC): Number of support vectors for each class. probA_ : ndarray of shape (n_classes * (n_classes - 1) / 2) - probB_ : ndarray of shape (n_classes * (n_classes - 1) / 2) If `probability=True`, it corresponds to the parameters learned in Platt scaling to produce probability estimates from decision values. If `probability=False`, it's an empty array. Platt scaling uses the logistic function + + probB_ : ndarray of shape (n_classes * (n_classes - 1) / 2) + If `probability=True`, it corresponds to the parameters learned in + Platt scaling. Platt scaling uses the logistic function ``1 / (1 + exp(decision_value * probA_ + probB_))`` where ``probA_`` and ``probB_`` are learned from the dataset [2]_. For more information on the multiclass case and training procedure see section 8 of [1]_. + .. deprecated:: 1.9 + The attributes `probA_` and `probB_` are deprecated in version 1.9 and will + be removed in 1.11. + shape_fit_ : tuple of int of shape (n_dimensions_of_X,) Array dimensions of training vector ``X``. @@ -1078,6 +1085,7 @@ class NuSVC(BaseSVC): 0 if correctly fitted, 1 if the algorithm did not converge. probA_ : ndarray of shape (n_classes * (n_classes - 1) / 2,) + If `probability=True`, parameters learned in Platt scaling. probB_ : ndarray of shape (n_classes * (n_classes - 1) / 2,) If `probability=True`, it corresponds to the parameters learned in @@ -1089,6 +1097,10 @@ class NuSVC(BaseSVC): more information on the multiclass case and training procedure see section 8 of [1]_. + .. deprecated:: 1.9 + The attributes `probA_` and `probB_` are deprecated in version 1.9 and will + be removed in 1.11. + shape_fit_ : tuple of int of shape (n_dimensions_of_X,) Array dimensions of training vector ``X``. diff --git a/sklearn/svm/tests/test_svm.py b/sklearn/svm/tests/test_svm.py index da5b6efb6a8c9..2a26450ed6007 100644 --- a/sklearn/svm/tests/test_svm.py +++ b/sklearn/svm/tests/test_svm.py @@ -1524,3 +1524,14 @@ def test_probability_raises_futurewarning(Estimator, name, probability): X, y = make_classification() with pytest.warns(FutureWarning, match="probability.+parameter.+deprecated"): Estimator(probability=probability).fit(X, y) + + +@pytest.mark.parametrize("est", [svm.SVC, svm.NuSVC]) +def test_svc_nusvc_probA_probB_deprecated(est): + """Test that accessing probA_ and probB_ raises FutureWarning for SVC and NuSVC.""" + X, y = make_classification(n_samples=50, n_informative=5, random_state=0) + est = est().fit(X, y) + with pytest.warns(FutureWarning, match="Attribute `probA_` was deprecated"): + _ = est.probA_ + with pytest.warns(FutureWarning, match="Attribute `probB_` was deprecated"): + _ = est.probB_ From 6625a05a3178ab9f938197b366d78f92868a9b1c Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Fri, 3 Apr 2026 18:16:41 +0200 Subject: [PATCH 321/462] DOC Improve description of `y_score` param in classification metrics (#33443) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- doc/modules/model_evaluation.rst | 18 +++++------ sklearn/metrics/_base.py | 3 +- sklearn/metrics/_plot/det_curve.py | 8 ++--- sklearn/metrics/_plot/roc_curve.py | 8 ++--- sklearn/metrics/_ranking.py | 48 +++++++++++++++--------------- 5 files changed, 43 insertions(+), 42 deletions(-) diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index 1ab12270e4c48..5613e1d3554b1 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -466,12 +466,12 @@ Classification metrics .. currentmodule:: sklearn.metrics -The :mod:`sklearn.metrics` module implements several loss, score, and utility -functions to measure classification performance. -Some metrics might require probability estimates of the positive class, -confidence values, or binary decisions values. -Most implementations allow each sample to provide a weighted contribution -to the overall score, through the ``sample_weight`` parameter. +The :mod:`sklearn.metrics` module implements several loss, score, and utility functions +to measure classification performance. Some metrics might require probability estimates +of the positive class or non-thresholded decision values (as returned by +:term:`decision_function` on some classifiers). Most implementations allow each sample +to provide a weighted contribution to the overall score, through the ``sample_weight`` +parameter. Some of these are restricted to the binary classification case: @@ -1578,9 +1578,9 @@ Quoting Wikipedia : sensitivity, and FPR is one minus the specificity or true negative rate." This function requires the true binary value and the target scores, which can -either be probability estimates of the positive class, confidence values, or -binary decisions. Here is a small example of how to use the :func:`roc_curve` -function:: +either be probability estimates of the positive class or non-thresholded decision values +(as returned by :term:`decision_function` on some classifiers). Here is a small example +of how to use the :func:`roc_curve` function:: >>> import numpy as np >>> from sklearn.metrics import roc_curve diff --git a/sklearn/metrics/_base.py b/sklearn/metrics/_base.py index 03547142ffbaa..e2305c82d350c 100644 --- a/sklearn/metrics/_base.py +++ b/sklearn/metrics/_base.py @@ -33,7 +33,8 @@ def _average_binary_score(binary_metric, y_true, y_score, average, sample_weight y_score : array, shape = [n_samples] or [n_samples, n_classes] Target scores, can either be probability estimates of the positive - class, confidence values, or binary decisions. + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). average : {None, 'micro', 'macro', 'samples', 'weighted'}, default='macro' If ``None``, the scores for each class are returned. Otherwise, diff --git a/sklearn/metrics/_plot/det_curve.py b/sklearn/metrics/_plot/det_curve.py index 01b6f34e776df..b428aca90177a 100644 --- a/sklearn/metrics/_plot/det_curve.py +++ b/sklearn/metrics/_plot/det_curve.py @@ -231,8 +231,8 @@ def from_predictions( y_score : array-like of shape (n_samples,) Target scores, can either be probability estimates of the positive - class, confidence values, or non-thresholded measure of decisions - (as returned by `decision_function` on some classifiers). + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). .. versionadded:: 1.8 `y_pred` has been renamed to `y_score`. @@ -262,8 +262,8 @@ def from_predictions( y_pred : array-like of shape (n_samples,) Target scores, can either be probability estimates of the positive - class, confidence values, or non-thresholded measure of decisions - (as returned by “decision_function” on some classifiers). + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). .. deprecated:: 1.8 `y_pred` is deprecated and will be removed in 1.10. Use diff --git a/sklearn/metrics/_plot/roc_curve.py b/sklearn/metrics/_plot/roc_curve.py index 50f6da1b1be1c..4d68594fac24d 100644 --- a/sklearn/metrics/_plot/roc_curve.py +++ b/sklearn/metrics/_plot/roc_curve.py @@ -494,8 +494,8 @@ def from_predictions( y_score : array-like of shape (n_samples,) Target scores, can either be probability estimates of the positive - class, confidence values, or non-thresholded measure of decisions - (as returned by “decision_function” on some classifiers). + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). .. versionadded:: 1.7 `y_pred` has been renamed to `y_score`. @@ -545,8 +545,8 @@ def from_predictions( y_pred : array-like of shape (n_samples,) Target scores, can either be probability estimates of the positive - class, confidence values, or non-thresholded measure of decisions - (as returned by “decision_function” on some classifiers). + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). .. deprecated:: 1.7 `y_pred` is deprecated and will be removed in 1.9. Use diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index 3149d6d3d5308..7183a58634a95 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -153,8 +153,8 @@ def average_precision_score( y_score : array-like of shape (n_samples,) or (n_samples, n_classes) Target scores, can either be probability estimates of the positive - class, confidence values, or non-thresholded measure of decisions - (as returned by :term:`decision_function` on some classifiers). + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). For :term:`decision_function` scores, values greater than or equal to zero should indicate the positive class. @@ -337,8 +337,8 @@ def det_curve( y_score : ndarray of shape of (n_samples,) Target scores, can either be probability estimates of the positive - class, confidence values, or non-thresholded measure of decisions - (as returned by "decision_function" on some classifiers). + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). For :term:`decision_function` scores, values greater than or equal to zero should indicate the positive class. @@ -1233,8 +1233,8 @@ def roc_curve( y_score : array-like of shape (n_samples,) Target scores, can either be probability estimates of the positive - class, confidence values, or non-thresholded measure of decisions - (as returned by "decision_function" on some classifiers). + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). For :term:`decision_function` scores, values greater than or equal to zero should indicate the positive class. @@ -1402,8 +1402,8 @@ def label_ranking_average_precision_score(y_true, y_score, *, sample_weight=None y_score : array-like of shape (n_samples, n_labels) Target scores, can either be probability estimates of the positive - class, confidence values, or non-thresholded measure of decisions - (as returned by "decision_function" on some classifiers). + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). For :term:`decision_function` scores, values greater than or equal to zero should indicate the positive class. @@ -1504,8 +1504,8 @@ def coverage_error(y_true, y_score, *, sample_weight=None): y_score : array-like of shape (n_samples, n_labels) Target scores, can either be probability estimates of the positive - class, confidence values, or non-thresholded measure of decisions - (as returned by "decision_function" on some classifiers). + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). For :term:`decision_function` scores, values greater than or equal to zero should indicate the positive class. @@ -1581,8 +1581,8 @@ def label_ranking_loss(y_true, y_score, *, sample_weight=None): y_score : array-like of shape (n_samples, n_labels) Target scores, can either be probability estimates of the positive - class, confidence values, or non-thresholded measure of decisions - (as returned by "decision_function" on some classifiers). + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). For :term:`decision_function` scores, values greater than or equal to zero should indicate the positive class. @@ -1668,9 +1668,9 @@ def _dcg_sample_scores(y_true, y_score, k=None, log_base=2, ignore_ties=False): to be ranked. y_score : ndarray of shape (n_samples, n_labels) - Target scores, can either be probability estimates, confidence values, - or non-thresholded measure of decisions (as returned by - "decision_function" on some classifiers). + Target scores, can either be probability estimates of the positive + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). k : int, default=None Only consider the highest k scores in the ranking. If `None`, use all @@ -1807,9 +1807,9 @@ def dcg_score( to be ranked. y_score : array-like of shape (n_samples, n_labels) - Target scores, can either be probability estimates, confidence values, - or non-thresholded measure of decisions (as returned by - "decision_function" on some classifiers). + Target scores, can either be probability estimates of the positive + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). k : int, default=None Only consider the highest k scores in the ranking. If None, use all @@ -1913,9 +1913,9 @@ def _ndcg_sample_scores(y_true, y_score, k=None, ignore_ties=False): to be ranked. y_score : ndarray of shape (n_samples, n_labels) - Target scores, can either be probability estimates, confidence values, - or non-thresholded measure of decisions (as returned by - "decision_function" on some classifiers). + Target scores, can either be probability estimates of the positive + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). k : int, default=None Only consider the highest k scores in the ranking. If None, use all @@ -1975,9 +1975,9 @@ def ndcg_score(y_true, y_score, *, k=None, sample_weight=None, ignore_ties=False that is not between 0 and 1. y_score : array-like of shape (n_samples, n_labels) - Target scores, can either be probability estimates, confidence values, - or non-thresholded measure of decisions (as returned by - "decision_function" on some classifiers). + Target scores, can either be probability estimates of the positive + class or non-thresholded decision values (as returned by + :term:`decision_function` on some classifiers). k : int, default=None Only consider the highest k scores in the ranking. If `None`, use all From 236f5e22ce09c7e501997ce401fa7621b286d79a Mon Sep 17 00:00:00 2001 From: Stanislav Terliakov <50529348+sterliakov@users.noreply.github.com> Date: Fri, 3 Apr 2026 18:54:35 +0200 Subject: [PATCH 322/462] PERF Cache `inspect.signature` in GPR kernels (#33067) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> Co-authored-by: Tim Head <betatim@gmail.com> Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.gaussian_process/33067.efficiency.rst | 3 +++ sklearn/gaussian_process/kernels.py | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.gaussian_process/33067.efficiency.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.gaussian_process/33067.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.gaussian_process/33067.efficiency.rst new file mode 100644 index 0000000000000..4ea6331076753 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.gaussian_process/33067.efficiency.rst @@ -0,0 +1,3 @@ +- Constructor signature of Gaussian process kernels is now cached, + improving performance on small and medium datasets. + By :user:`Stanislav Terliakov <sterliakov>` \ No newline at end of file diff --git a/sklearn/gaussian_process/kernels.py b/sklearn/gaussian_process/kernels.py index c6cf14518753a..01cbac22a3713 100644 --- a/sklearn/gaussian_process/kernels.py +++ b/sklearn/gaussian_process/kernels.py @@ -21,11 +21,12 @@ # Note: this module is strongly inspired by the kernel module of the george # package. +import inspect import math import warnings from abc import ABCMeta, abstractmethod from collections import namedtuple -from inspect import signature +from functools import lru_cache import numpy as np from scipy.spatial.distance import cdist, pdist, squareform @@ -36,6 +37,11 @@ from sklearn.metrics.pairwise import pairwise_kernels from sklearn.utils.validation import _num_samples +# Cache constructor signature inspection for kernels as it empirically +# proves to account for 15% or more of the total grid-search time of GP +# model on small to medium data. +signature = lru_cache(maxsize=32)(inspect.signature) + def _check_length_scale(X, length_scale): length_scale = np.squeeze(length_scale).astype(float) From b0c9c3a1fda2f3433ed896208fbee3950aeb15ed Mon Sep 17 00:00:00 2001 From: "Thomas S." <2565098+thomass-dev@users.noreply.github.com> Date: Fri, 3 Apr 2026 23:02:38 +0200 Subject: [PATCH 323/462] CI Disable [all random seeds] detection outside pull-request (#32558) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 0af5c5ee92676..7dba59e0f7585 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -84,7 +84,7 @@ jobs: # ... name: Retrieve the selected tests runs-on: ubuntu-latest - if: github.repository == 'scikit-learn/scikit-learn' + if: ${{ github.repository == 'scikit-learn/scikit-learn' && github.event_name == 'pull_request' }} outputs: tests: ${{ steps.selected-tests.outputs.tests }} needs: [retrieve-commit-message] From 56ad623437cf2dd0dbd56b56a7a74505e453fe3a Mon Sep 17 00:00:00 2001 From: Arturo Amor <86408019+ArturoAmorQ@users.noreply.github.com> Date: Fri, 3 Apr 2026 15:18:02 -0600 Subject: [PATCH 324/462] DOC Add demo on estimating the variability of the coverage fraction (#29499) Co-authored-by: ArturoAmorQ <arturo.amor-quiroz@polytechnique.edu> Co-authored-by: Christian Lorentzen <lorentzen.ch@gmail.com> --- .../plot_gradient_boosting_quantile.py | 165 +++++++++++------- 1 file changed, 101 insertions(+), 64 deletions(-) diff --git a/examples/ensemble/plot_gradient_boosting_quantile.py b/examples/ensemble/plot_gradient_boosting_quantile.py index 37d897449cc97..3086482d614ac 100644 --- a/examples/ensemble/plot_gradient_boosting_quantile.py +++ b/examples/ensemble/plot_gradient_boosting_quantile.py @@ -55,8 +55,8 @@ def f(x): # Fit gradient boosting models trained with the quantile loss and `alpha=0.05`, # `alpha=0.5`, `alpha=0.95`. # -# The models obtained for `alpha=0.05` and `alpha=0.95` produce a 90% -# confidence interval (95% - 5% = 90%). +# The models obtained for `alpha=0.05` and `alpha=0.95` produce a 90% coverage +# interval (95% - 5% = 90%). # # The model trained with `alpha=0.5` produces a regression of the median: on # average, there should be the same number of target observations above and @@ -90,7 +90,7 @@ def f(x): # %% # Create an evenly spaced evaluation set of input values spanning the [0, 10] # range. -xx = np.atleast_2d(np.linspace(0, 10, 1000)).T +x_plot = np.atleast_2d(np.linspace(0, 10, 1000)).T # %% # Plot the true conditional mean function f, the predictions of the conditional @@ -98,18 +98,18 @@ def f(x): # 90% interval (from 5th to 95th conditional percentiles). import matplotlib.pyplot as plt -y_pred = all_models["mse"].predict(xx) -y_lower = all_models["q 0.05"].predict(xx) -y_upper = all_models["q 0.95"].predict(xx) -y_med = all_models["q 0.50"].predict(xx) +y_pred = all_models["mse"].predict(x_plot) +y_lower = all_models["q 0.05"].predict(x_plot) +y_upper = all_models["q 0.95"].predict(x_plot) +y_med = all_models["q 0.50"].predict(x_plot) fig = plt.figure(figsize=(10, 10)) -plt.plot(xx, f(xx), "black", linewidth=3, label=r"$f(x) = x\,\sin(x)$") +plt.plot(x_plot, f(x_plot), "black", linewidth=3, label=r"$f(x) = x\,\sin(x)$") plt.plot(X_test, y_test, "b.", markersize=10, label="Test observations") -plt.plot(xx, y_med, "tab:orange", linewidth=3, label="Predicted median") -plt.plot(xx, y_pred, "tab:green", linewidth=3, label="Predicted mean") +plt.plot(x_plot, y_med, "tab:orange", linewidth=3, label="Predicted median") +plt.plot(x_plot, y_pred, "tab:green", linewidth=3, label="Predicted mean") plt.fill_between( - xx.ravel(), y_lower, y_upper, alpha=0.4, label="Predicted 90% interval" + x_plot.ravel(), y_lower, y_upper, alpha=0.4, label="Predicted 90% interval" ) plt.xlabel("$x$") plt.ylabel("$f(x)$") @@ -193,39 +193,6 @@ def highlight_min(x): # (underestimation for this asymmetric noise) but is also naturally robust to # outliers and overfits less. # -# .. _calibration-section: -# -# Calibration of the confidence interval -# -------------------------------------- -# -# We can also evaluate the ability of the two extreme quantile estimators at -# producing a well-calibrated conditional 90%-confidence interval. -# -# To do this we can compute the fraction of observations that fall between the -# predictions: -def coverage_fraction(y, y_low, y_high): - return np.mean(np.logical_and(y >= y_low, y <= y_high)) - - -coverage_fraction( - y_train, - all_models["q 0.05"].predict(X_train), - all_models["q 0.95"].predict(X_train), -) - -# %% -# On the training set the calibration is very close to the expected coverage -# value for a 90% confidence interval. -coverage_fraction( - y_test, all_models["q 0.05"].predict(X_test), all_models["q 0.95"].predict(X_test) -) - - -# %% -# On the test set, the estimated confidence interval is slightly too narrow. -# Note, however, that we would need to wrap those metrics in a cross-validation -# loop to assess their variability under data resampling. -# # Tuning the hyper-parameters of the quantile regressors # ------------------------------------------------------ # @@ -238,7 +205,7 @@ def coverage_fraction(y, y_low, y_high): # # To confirm this hypothesis, we tune the hyper-parameters of a new regressor # of the 5th percentile by selecting the best model parameters by -# cross-validation on the pinball loss with alpha=0.05: +# cross-validation on the pinball loss with `alpha=0.05`: # %% from pprint import pprint @@ -253,13 +220,12 @@ def coverage_fraction(y, y_low, y_high): min_samples_leaf=[1, 5, 10, 20], min_samples_split=[5, 10, 20, 30, 50], ) -alpha = 0.05 neg_mean_pinball_loss_05p_scorer = make_scorer( mean_pinball_loss, - alpha=alpha, + alpha=0.05, greater_is_better=False, # maximize the negative loss ) -gbr = GradientBoostingRegressor(loss="quantile", alpha=alpha, random_state=0) +gbr = GradientBoostingRegressor(loss="quantile", alpha=0.05, random_state=0) search_05p = HalvingRandomSearchCV( gbr, param_grid, @@ -279,18 +245,17 @@ def coverage_fraction(y, y_low, y_high): # # Let's now tune the hyper-parameters for the 95th percentile regressor. We # need to redefine the `scoring` metric used to select the best model, along -# with adjusting the alpha parameter of the inner gradient boosting estimator +# with adjusting the `alpha` parameter of the inner gradient boosting estimator # itself: from sklearn.base import clone -alpha = 0.95 neg_mean_pinball_loss_95p_scorer = make_scorer( mean_pinball_loss, - alpha=alpha, + alpha=0.95, greater_is_better=False, # maximize the negative loss ) search_95p = clone(search_05p).set_params( - estimator__alpha=alpha, + estimator__alpha=0.95, scoring=neg_mean_pinball_loss_95p_scorer, ) search_95p.fit(X_train, y_train) @@ -301,18 +266,22 @@ def coverage_fraction(y, y_low, y_high): # identified by the search procedure are roughly in the same range as the hand-tuned # hyper-parameters for the median regressor and the hyper-parameters # identified by the search procedure for the 5th percentile regressor. However, -# the hyper-parameter searches did lead to an improved 90% confidence interval +# the hyper-parameter searches did lead to an improved 90% coverage interval # that is comprised by the predictions of those two tuned quantile regressors. # Note that the prediction of the upper 95th percentile has a much coarser shape # than the prediction of the lower 5th percentile because of the outliers: -y_lower = search_05p.predict(xx) -y_upper = search_95p.predict(xx) +y_lower_plot = search_05p.predict(x_plot) +y_upper_plot = search_95p.predict(x_plot) fig = plt.figure(figsize=(10, 10)) -plt.plot(xx, f(xx), "black", linewidth=3, label=r"$f(x) = x\,\sin(x)$") +plt.plot(x_plot, f(x_plot), "black", linewidth=3, label=r"$f(x) = x\,\sin(x)$") plt.plot(X_test, y_test, "b.", markersize=10, label="Test observations") plt.fill_between( - xx.ravel(), y_lower, y_upper, alpha=0.4, label="Predicted 90% interval" + x_plot.ravel(), + y_lower_plot, + y_upper_plot, + alpha=0.4, + label="Predicted 90% interval", ) plt.xlabel("$x$") plt.ylabel("$f(x)$") @@ -325,14 +294,82 @@ def coverage_fraction(y, y_low, y_high): # The plot looks qualitatively better than for the untuned models, especially # for the shape of the of lower quantile. # -# We now quantitatively evaluate the joint-calibration of the pair of -# estimators: +# .. _calibration-section: +# +# Calibration of the confidence interval +# -------------------------------------- +# +# We can also evaluate the ability of the two extreme quantile estimators at +# producing well-calibrated predictions of the 90%-coverage interval +# (conditional on `X`), meaning that on average 90% of the observations should +# lie within this interval. +# +# To do this we can compute the coverage fraction, i.e. the proportion of +# observations that fall within the prediction intervals: + + +def coverage_fraction(y, y_low, y_high): + return np.mean(np.logical_and(y >= y_low, y <= y_high)) + + coverage_fraction(y_train, search_05p.predict(X_train), search_95p.predict(X_train)) + # %% +# On the training set the calibration is very close to the expected coverage +# value of 90%. coverage_fraction(y_test, search_05p.predict(X_test), search_95p.predict(X_test)) + # %% -# The calibration of the tuned pair is sadly not better on the test set: the -# width of the estimated confidence interval is still too narrow. -# -# Again, we would need to wrap this study in a cross-validation loop to -# better assess the variability of those estimates. +# On the test set, the estimated interval is too narrow to cover 90% of the test +# points, but it may still hit the right coverage within reasonable statistical +# uncertainty. We can use :func:`scipy.stats.bootstrap` to measure the +# variability of the coverage fraction at prediction time, without retraining +# the models. We use a 95% confidence level for the estimated (bootstrapped) +# interval of coverage; this is not to be confused with the 90% coverage +# stemming from our 5% and 95% quantile predictions: + +from scipy.stats import bootstrap + +train_coverage_bs = bootstrap( + ( + y_train, + search_05p.predict(X_train), + search_95p.predict(X_train), + ), + coverage_fraction, + paired=True, + confidence_level=0.95, + n_resamples=1000, +) +ci = train_coverage_bs.confidence_interval +print( + f"Training-set coverage lies between {ci.low:.1%} and {ci.high:.1%}, " + f"based on a 95% bootstrap confidence interval." +) + +# %% +# Notice that the interval contains the target value of 90% coverage. + +# %% +test_coverage_bs = bootstrap( + ( + y_test, + search_05p.predict(X_test), + search_95p.predict(X_test), + ), + coverage_fraction, + paired=True, + confidence_level=0.95, + n_resamples=1000, +) +ci = test_coverage_bs.confidence_interval +print( + f"Test-set coverage lies between {ci.low:.1%} and {ci.high:.1%}, " + f"based on a 95% bootstrap confidence interval." +) + + +# %% +# The quantile estimates from the tuned models are sadly not well-calibrated on +# the test set: the width of the estimated confidence interval is too narrow +# even when taking it's variations into account. From b398214aa4def5a64a01f83acf76062ead516622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= <jeremie@probabl.ai> Date: Fri, 3 Apr 2026 23:10:40 +0200 Subject: [PATCH 325/462] revert #32558 --- .github/workflows/unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 7dba59e0f7585..0af5c5ee92676 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -84,7 +84,7 @@ jobs: # ... name: Retrieve the selected tests runs-on: ubuntu-latest - if: ${{ github.repository == 'scikit-learn/scikit-learn' && github.event_name == 'pull_request' }} + if: github.repository == 'scikit-learn/scikit-learn' outputs: tests: ${{ steps.selected-tests.outputs.tests }} needs: [retrieve-commit-message] From 319e7c64e2794b8f46b9097491e753a4058fbd58 Mon Sep 17 00:00:00 2001 From: holodata-ej <black.ej@outlook.com> Date: Sat, 4 Apr 2026 01:30:22 +0100 Subject: [PATCH 326/462] MNT Use minlength=n_bins instead of len(bins) (#33229) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- sklearn/calibration.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sklearn/calibration.py b/sklearn/calibration.py index 7917fc0897974..f1b142720329c 100644 --- a/sklearn/calibration.py +++ b/sklearn/calibration.py @@ -1329,9 +1329,9 @@ def calibration_curve( binids = np.searchsorted(bins[1:-1], y_prob) - bin_sums = np.bincount(binids, weights=y_prob, minlength=len(bins)) - bin_true = np.bincount(binids, weights=y_true, minlength=len(bins)) - bin_total = np.bincount(binids, minlength=len(bins)) + bin_sums = np.bincount(binids, weights=y_prob, minlength=n_bins) + bin_true = np.bincount(binids, weights=y_true, minlength=n_bins) + bin_total = np.bincount(binids, minlength=n_bins) nonzero = bin_total != 0 prob_true = bin_true[nonzero] / bin_total[nonzero] From c8e7f39713c20868c56d2afc9e95e69226c1508a Mon Sep 17 00:00:00 2001 From: Balaji Seshadri <ashwath.balaji@gmail.com> Date: Sat, 4 Apr 2026 13:00:40 -0400 Subject: [PATCH 327/462] TST use global_random_seed in sklearn/linear_model/tests/test_bayes.py (#33465) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- sklearn/linear_model/tests/test_bayes.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sklearn/linear_model/tests/test_bayes.py b/sklearn/linear_model/tests/test_bayes.py index 9f7fabb749f52..e44d1ebf46027 100644 --- a/sklearn/linear_model/tests/test_bayes.py +++ b/sklearn/linear_model/tests/test_bayes.py @@ -152,12 +152,12 @@ def test_bayesian_initial_params(): assert_almost_equal(r2, 1.0) -def test_prediction_bayesian_ridge_ard_with_constant_input(): +def test_prediction_bayesian_ridge_ard_with_constant_input(global_random_seed): # Test BayesianRidge and ARDRegression predictions for edge case of # constant target vectors n_samples = 4 n_features = 5 - random_state = check_random_state(42) + random_state = check_random_state(global_random_seed) constant_value = random_state.rand() X = random_state.random_sample((n_samples, n_features)) y = np.full(n_samples, constant_value, dtype=np.array(constant_value).dtype) @@ -168,13 +168,13 @@ def test_prediction_bayesian_ridge_ard_with_constant_input(): assert_array_almost_equal(y_pred, expected) -def test_std_bayesian_ridge_ard_with_constant_input(): +def test_std_bayesian_ridge_ard_with_constant_input(global_random_seed): # Test BayesianRidge and ARDRegression standard dev. for edge case of # constant target vector # The standard dev. should be relatively small (< 0.01 is tested here) n_samples = 10 n_features = 5 - random_state = check_random_state(42) + random_state = check_random_state(global_random_seed) constant_value = random_state.rand() X = random_state.random_sample((n_samples, n_features)) y = np.full(n_samples, constant_value, dtype=np.array(constant_value).dtype) @@ -226,13 +226,15 @@ def test_ard_accuracy_on_easy_problem(global_random_seed, n_samples, n_features) @pytest.mark.parametrize("constructor_name", ["array", "dataframe"]) -def test_return_std(constructor_name): +def test_return_std(constructor_name, global_random_seed): # Test return_std option for both Bayesian regressors + rng = np.random.RandomState(global_random_seed) + def f(X): return np.dot(X, w) + b def f_noise(X, noise_mult): - return f(X) + np.random.randn(X.shape[0]) * noise_mult + return f(X) + rng.randn(X.shape[0]) * noise_mult d = 5 n_train = 50 @@ -241,10 +243,10 @@ def f_noise(X, noise_mult): w = np.array([1.0, 0.0, 1.0, -1.0, 0.0]) b = 1.0 - X = np.random.random((n_train, d)) + X = rng.random_sample((n_train, d)) X = _convert_container(X, constructor_name) - X_test = np.random.random((n_test, d)) + X_test = rng.random_sample((n_test, d)) X_test = _convert_container(X_test, constructor_name) for decimal, noise_mult in enumerate([1, 0.1, 0.01]): From cb27843bb533799aa7b9cc523f6d44dd636133ac Mon Sep 17 00:00:00 2001 From: marikabergengren <113436979+marikabergengren@users.noreply.github.com> Date: Mon, 6 Apr 2026 14:32:16 +0200 Subject: [PATCH 328/462] FIX GroupKFold use stable sort to produce consistent splits across installs (#28464) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: adrinjalali <adrin.jalali@gmail.com> Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.model_selection/28464.enhancement.rst | 4 ++++ sklearn/model_selection/_split.py | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.model_selection/28464.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.model_selection/28464.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.model_selection/28464.enhancement.rst new file mode 100644 index 0000000000000..8ac8c36fa831a --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.model_selection/28464.enhancement.rst @@ -0,0 +1,4 @@ +- :class:`~sklearn.model_selection.GroupKFold` now uses `stable` sorting when doing + the group distribution. This ensures that the splits are consistent across + runs. + By :user:`marikabergengren <marikabergengren>` and `Adrin Jalali`_ diff --git a/sklearn/model_selection/_split.py b/sklearn/model_selection/_split.py index 3b1dfefc36038..64517af6a05ad 100644 --- a/sklearn/model_selection/_split.py +++ b/sklearn/model_selection/_split.py @@ -637,7 +637,7 @@ def _iter_test_indices(self, X, y, groups): n_samples_per_group = np.bincount(group_idx) # Distribute the most frequent groups first - indices = np.argsort(n_samples_per_group)[::-1] + indices = np.argsort(n_samples_per_group, kind="stable")[::-1] n_samples_per_group = n_samples_per_group[indices] # Total weight of each fold @@ -1062,7 +1062,7 @@ def _iter_test_indices(self, X, y, groups): # Stable sort to keep shuffled order for groups with the same # class distribution variance sorted_groups_idx = np.argsort( - -np.std(y_counts_per_group, axis=1), kind="mergesort" + -np.std(y_counts_per_group, axis=1), kind="stable" ) for group_idx in sorted_groups_idx: @@ -2364,7 +2364,7 @@ def _iter_indices(self, X, y, groups=None): # Find the sorted list of instances for each class: # (np.unique above performs a sort, so code is O(n logn) already) class_indices = np.split( - np.argsort(y_indices, kind="mergesort"), np.cumsum(class_counts)[:-1] + np.argsort(y_indices, kind="stable"), np.cumsum(class_counts)[:-1] ) rng = check_random_state(self.random_state) From f62c2a29e53ac692ef7c51153ce0167400c41e18 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 6 Apr 2026 08:47:47 -0400 Subject: [PATCH 329/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33696) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/github/pylatest_free_threaded_linux-64_conda.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index f8d859674b47c..7a8c7134f62bd 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -18,7 +18,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18. https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab From 0311cbf8de2a7edfdc534b8da8ed5ca72eee30af Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 6 Apr 2026 08:48:03 -0400 Subject: [PATCH 330/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33697) Co-authored-by: Lock file bot <noreply@github.com> --- .../github/pylatest_pip_scipy_dev_linux-64_conda.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index 86df152ce5556..c711085b975c3 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -17,7 +17,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a3 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -32,7 +32,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa -# pip charset-normalizer @ https://files.pythonhosted.org/packages/76/7e/bc8911719f7084f72fd545f647601ea3532363927f807d296a8c88a62c0d/charset_normalizer-3.4.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=7bda6eebafd42133efdca535b04ccb338ab29467b3f7bf79569883676fc628db +# pip charset-normalizer @ https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e # pip coverage @ https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec @@ -61,7 +61,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl#sha256=85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 -# pip requests @ https://files.pythonhosted.org/packages/56/5d/c814546c2333ceea4ba42262d8c4d55763003e767fa169adc693bd524478/requests-2.33.0-py3-none-any.whl#sha256=3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b +# pip requests @ https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl#sha256=4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a # pip meson-python @ https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl#sha256=67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298 # pip pooch @ https://files.pythonhosted.org/packages/2a/2d/d4bf65e47cea8ff2c794a600c4fd1273a7902f268757c531e0ee9f18aa58/pooch-1.9.0-py3-none-any.whl#sha256=f265597baa9f760d25ceb29d0beb8186c243d6607b0f60b83ecf14078dbc703b # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 From bcd638c759cdfcfa8cd547f162312cd09a8012d4 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 6 Apr 2026 08:48:19 -0400 Subject: [PATCH 331/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33698) Co-authored-by: Lock file bot <noreply@github.com> --- ...test_conda_forge_cuda_array-api_linux-64_conda.lock | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 507e2b98f7e87..d43e43312e5f2 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -60,7 +60,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.con https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -187,7 +187,7 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.0-pyhc364b38_0.conda#a18297fed4097f00f58d64a8191f9881 +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.1-pyhc364b38_0.conda#aff29594e5d127a4b35aeef4b5f330cc https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 @@ -214,7 +214,7 @@ https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda# https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.595.45-pyhd8ed1ab_0.conda#bbb874843e7cc9cfe379d59499155e45 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py313h80991f8_0.conda#2d5ee4938cdde91a8967f3eea686c546 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py313h80991f8_0.conda#7245f1bbf52ed5e3818d742f51b44a7d https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 @@ -276,7 +276,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.co https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py313hcd51b16_0.conda#81412e7d848362a09a30ede0776e657b +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py313hcd51b16_1.conda#aafbb057823020eda1e5db662bc354a9 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 @@ -296,7 +296,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py313h28b6081_0 https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_mkl_hd6d2a1f_303.conda#5b8a8672aca66f3871aab4d0d1a8f796 https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.conda#84cef0ce56c6db53edb3f8b83bdbb364 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py313hbfd7664_0.conda#1c8807728f0333228766dee685394e16 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py313hbfd7664_0.conda#6a036e42f4e47720804f35d1897336a1 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py313h98bfbea_0_cpu.conda#d2b771a9050c52941a61a72f2d161c64 https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 From e1a29f65b5bfc8336ce094593fdd0484126f7c73 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 6 Apr 2026 08:48:47 -0400 Subject: [PATCH 332/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33699) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/circle/doc_linux-64_conda.lock | 16 ++++++++-------- .../doc_min_dependencies_linux-64_conda.lock | 10 +++++----- .../pylatest_conda_forge_mkl_linux-64_conda.lock | 12 ++++++------ ...t_conda_forge_mkl_no_openmp_osx-64_conda.lock | 4 ++-- .../pylatest_conda_forge_osx-arm64_conda.lock | 6 +++--- ...atest_pip_openblas_pandas_linux-64_conda.lock | 10 +++++----- ...ymin_conda_forge_arm_linux-aarch64_conda.lock | 6 +++--- ...openblas_min_dependencies_linux-64_conda.lock | 8 ++++---- ...orge_openblas_ubuntu_2204_linux-64_conda.lock | 10 +++++----- .../pymin_conda_forge_openblas_win-64_conda.lock | 4 ++-- 10 files changed, 43 insertions(+), 43 deletions(-) diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 77af5a55514e0..6e807d21dd65f 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -45,7 +45,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.con https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda#7af961ef4aa2c1136e11dd43ded245ab https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f @@ -140,7 +140,7 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275 https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2#576d629e47797577ab0f1b351297ef4a https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda#49ee13eb9b8f44d63879c69b8a40a74b +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.15-py311hd8ed1ab_0.conda#bf0d09d5c2b61aaf7b11c551c8545cfa @@ -177,7 +177,7 @@ https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda# https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -190,7 +190,7 @@ https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda#23029aae904a2ba587daba708208012f https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda#a61bf9ec79426938ff785eb69dbb1960 -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.1-pyhd8ed1ab_0.conda#d8d30923ccee7525704599efd722aa16 https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda#a24add9a3bababee946f3bc1c829acfe https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h57d2397_2.conda#759edfe34f07c5c4565b6c5ec0c7fb17 https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f @@ -289,9 +289,9 @@ https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.1-p https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py311hf27b23e_0.conda#78202f74ac55b455e0539b6d0253964d +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py311hf27b23e_1.conda#b3fb332c110fee191999153ccf69fad2 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.0-pyhcf101f3_0.conda#bee5ed456361bfe8af502beaf5db82e2 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda#8368d58342d0825f0843dc6acdd0c483 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 @@ -309,7 +309,7 @@ https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311h724c32c_4. https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.0-pyhcf101f3_0.conda#b14079a39ae60ac7ad2ec3d9eab075ca -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.conda#3ac73c673df24589b5b84d43a4afd235 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py311h8032f78_0.conda#138e5d98884407fcc8ccc6088574b1c7 https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 @@ -325,7 +325,7 @@ https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.c https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.1-pyhcf101f3_0.conda#1f90643873d0cc2f7b0bf2752db71016 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 -https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.16.1-pyhd8ed1ab_0.conda#837aaf71ddf3b27acae0e7e9015eebc6 +https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.17.0-pyhcf101f3_0.conda#c09bb5f9960ff1cd334c5573b5ad79c2 https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda#bf22cb9c439572760316ce0748af3713 https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.7.0-pyhd8ed1ab_0.conda#28eddfb8b9ecdd044a6f609f985398a7 https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.20.0-pyhd8ed1ab_0.conda#4cae490c8d142824fb80d9aed672fddd diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index e723e6e2018dd..1a1a8111b39d3 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -48,7 +48,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f @@ -148,7 +148,7 @@ https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda#49ee13eb9b8f44d63879c69b8a40a74b +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -174,7 +174,7 @@ https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#3 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e @@ -183,7 +183,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_ https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2025.3-pyhd8ed1ab_0.conda#7ead57407430ba33f681738905278d03 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.1-pyhd8ed1ab_0.conda#d8d30923ccee7525704599efd722aa16 https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda#3eeeeb9e4827ace8c0c1419c85d590ad https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 @@ -244,7 +244,7 @@ https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h036367 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.0-pyhcf101f3_0.conda#bee5ed456361bfe8af502beaf5db82e2 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock index 475d453143bdb..e858e3c354f92 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -45,7 +45,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.con https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 @@ -143,7 +143,7 @@ https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda#49ee13eb9b8f44d63879c69b8a40a74b +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda#3bb89e4f795e5414addaa531d6b1500a https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -172,7 +172,7 @@ https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#3 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py314h8ec4b1a_0.conda#79678378ae235e24b3aa83cee1b38207 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/linux-64/playwright-1.58.2-h5585027_0.conda#1650804f26dd992fd7418fe603f1c653 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -240,10 +240,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.co https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_0.conda#1bd12dc69c3632f1d7ee9fbfd68c0186 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_1.conda#5abdb958cf8cc0b43cf078d0559f7969 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.0-pyhcf101f3_0.conda#bee5ed456361bfe8af502beaf5db82e2 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 @@ -259,7 +259,7 @@ https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0. https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py314hb4ffadd_0.conda#23fc526360815090f6bfcd7c6c8e4954 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py314hb4ffadd_0.conda#41ee6fe2a848876bc9f524c5a500b85b https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py314h969be7f_0_cpu.conda#97c21b0d5952f4e0f80bb790df1a5c88 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h6018c46_103.conda#a3c40f317db763f9631d078d0fb2759e https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 240a6f58bba96..7e41b0d52d9e0 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -81,7 +81,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.cond https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.3-h694c41f_0.conda#6ab1403cc6cb284d56d0464f19251075 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda#34a9f67498721abcfef00178bcf4b190 -https://conda.anaconda.org/conda-forge/osx-64/pillow-12.1.1-py314hf9dbaa9_0.conda#9a35ec32776ac587bf178233fd2176e4 +https://conda.anaconda.org/conda-forge/osx-64/pillow-12.2.0-py314hc904d5e_0.conda#fb32d458ddac23248e07a0830c6ffc7b https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.13.0-h06b67a2_5.conda#f3e5cd2b56a3c866214b1d2529a54730 @@ -98,7 +98,7 @@ https://conda.anaconda.org/conda-forge/osx-64/liblapacke-3.9.0-20_osx64_mkl.cond https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.3-py314h7b24d9b_0.conda#3d8057ab97e4c8fd1f781356e7be9b40 https://conda.anaconda.org/conda-forge/osx-64/blas-devel-3.9.0-20_osx64_mkl.conda#cc3260179093918b801e373c6e888e02 https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h22a2ed9_4.conda#511f02f632e1fb0555da3cb4261851d9 -https://conda.anaconda.org/conda-forge/osx-64/pandas-3.0.1-py314h99bb933_0.conda#8efb0ea54eaf4aff69a0a16a5e5efb4c +https://conda.anaconda.org/conda-forge/osx-64/pandas-3.0.2-py314h99bb933_0.conda#84a0c511492546f0363360ad1e4e6510 https://conda.anaconda.org/conda-forge/osx-64/scipy-1.17.1-py314h5727af0_0.conda#adbed17bd17ac00193e6dce1f1a37781 https://conda.anaconda.org/conda-forge/osx-64/blas-2.120-mkl.conda#b041a7677a412f3d925d8208936cb1e2 https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.8-py314hd47142c_0.conda#91d76a5937b47f7f0894857ce88feb9f diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock index e75fcbe1569d8..b86d543b12ba8 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock @@ -49,7 +49,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda# https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda#6483b1f59526e05d7d894e466b5b6924 https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda#f8381319127120ce51e081dce4865cf4 https://conda.anaconda.org/conda-forge/osx-arm64/sleef-3.9.0-hb028509_0.conda#68f833178f171cfffdd18854c0e9b7f9 -https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_0.conda#347261d575a245cb6111fb2cb5a79fc7 +https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_1.conda#ddd7d9cd7e3c3f184867e92ed1c7d394 https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda#a9d86bc62f39b94c4661716624eb21b0 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.2-h8088a28_2.conda#f1c0bce276210bed45a04949cfe8dc20 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.3-hed4e4f5_1.conda#d99c2a23a31b0172e90f456f580b695e @@ -111,7 +111,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_h https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_8.conda#445fc95210a8e15e8b5f9f93782e3f80 https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda#26981599908ed2205366e8fc91b37fc6 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef -https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.1.1-py314hab283cf_0.conda#bcb38a8005e93a3b240a0dbcf28df87a +https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.2.0-py314hab283cf_0.conda#adf49537da0e0c34cf735e71fe579506 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -139,7 +139,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.3-py314h1569ea8_0.con https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/osx-arm64/blas-devel-3.11.0-6_h11c0a38_openblas.conda#923a8c7dd5c8ae2d5a3aff4e1e579337 https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.3.3-py314hf8a3a22_4.conda#cddc851000ce131d757678c2f329eaad -https://conda.anaconda.org/conda-forge/osx-arm64/pandas-3.0.1-py314h5e21a50_0.conda#840cec8154769d52f65f0fdaaf4aa4c9 +https://conda.anaconda.org/conda-forge/osx-arm64/pandas-3.0.2-py314he609de1_0.conda#a28d1a3565d7c6d95479c2c6e52c1b16 https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.10.0-cpu_generic_py314_he36690f_3.conda#51da3d684a7d90b35adfd742fb551cc4 https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.1-py314hfc1f868_0.conda#7806ce54b78b0b11517b465a3398e910 https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.306-openblas.conda#4cd635f3755993f4658959c2b3e1f2ef diff --git a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock index c5cac4cedeb9c..e512c064ff773 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -17,7 +17,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a3 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -32,7 +32,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa -# pip charset-normalizer @ https://files.pythonhosted.org/packages/2b/58/a199d245894b12db0b957d627516c78e055adc3a0d978bc7f65ddaf7c399/charset_normalizer-3.4.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=530e8cebeea0d76bdcf93357aa5e41336f48c3dc709ac52da2bb167c5b8271d9 +# pip charset-normalizer @ https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd # pip coverage @ https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3 # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 # pip cython @ https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 @@ -49,7 +49,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip numpy @ https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83 # pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 -# pip pillow @ https://files.pythonhosted.org/packages/71/24/538bff45bde96535d7d998c6fed1a751c75ac7c53c37c90dc2601b243893/pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717 +# pip pillow @ https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl#sha256=81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # pip pyparsing @ https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl#sha256=850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d @@ -70,12 +70,12 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl#sha256=85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 # pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 -# pip requests @ https://files.pythonhosted.org/packages/56/5d/c814546c2333ceea4ba42262d8c4d55763003e767fa169adc693bd524478/requests-2.33.0-py3-none-any.whl#sha256=3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b +# pip requests @ https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl#sha256=4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a # pip scipy @ https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 # pip lightgbm @ https://files.pythonhosted.org/packages/42/86/dabda8fbcb1b00bcfb0003c3776e8ade1aa7b413dff0a2c08f457dace22f/lightgbm-4.6.0-py3-none-manylinux_2_28_x86_64.whl#sha256=cb19b5afea55b5b61cbb2131095f50538bd608a00655f23ad5d25ae3e3bf1c8d # pip matplotlib @ https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486 # pip meson-python @ https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl#sha256=67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298 -# pip pandas @ https://files.pythonhosted.org/packages/f2/85/ab6d04733a7d6ff32bfc8382bf1b07078228f5d6ebec5266b91bfc5c4ff7/pandas-3.0.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=1ff8cf1d2896e34343197685f432450ec99a85ba8d90cce2030c5eee2ef98791 +# pip pandas @ https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e # pip pyamg @ https://files.pythonhosted.org/packages/63/f3/c13ae1422434baeefe4d4f306a1cc77f024fe96d2abab3c212cfa1bf3ff8/pyamg-5.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=5cc223c66a7aca06fba898eb5e8ede6bb7974a9ddf7b8a98f56143c829e63631 # pip pytest-cov @ https://files.pythonhosted.org/packages/80/b4/bb7263e12aade3842b938bc5c6958cae79c5ee18992f9b9349019579da0f/pytest_cov-6.3.0-py3-none-any.whl#sha256=440db28156d2468cafc0415b4f8e50856a0d11faefa38f30906048fe490f1749 # pip pytest-xdist @ https://files.pythonhosted.org/packages/ca/31/d4e37e9e550c2b92a9cbc2e4d0b7420a27224968580b5a447f420847c975/pytest_xdist-3.8.0-py3-none-any.whl#sha256=202ca578cfeb7370784a8c33d6d05bc6e13b4f25b5053c30a152269fd10f0b88 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 1428eb0a8af20..9d8ecb4f0c883 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -36,7 +36,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.con https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.56-h1abf092_0.conda#d5aff85583507906d19696d4961f4738 https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 -https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.41.3-h1022ec0_0.conda#cf2861212053d05f27ec49c3784ff8bb +https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42-h1022ec0_0.conda#a0b5de740d01c390bdbb46d7503c9fab https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda#182afabe009dc78d8b73100255ee6868 https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda#25f5885f11e8b1f075bccf4a2da91c60 @@ -119,7 +119,7 @@ https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h2fb54aa_1.conda#b761e5f1358577a16ca187c6116d9fcc https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.1.1-py311h8e17b9e_0.conda#2f611dceeef334e4d3448944bf714277 +https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.2.0-py311h8e17b9e_0.conda#c2e33eff9ea2d1501b83d938d9d4334d https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 @@ -162,7 +162,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.11.0-pl5321h598d https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.1-py311h399493a_0.conda#be28b3d39c6942f89652b505e85ae3d6 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.306-openblas.conda#cc7cac46a53a5c76f20439cb298d10a2 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 -https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.11.0-py311hb02cd75_0.conda#8a634ae402ca677dd0fc4d6e08226389 +https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.11.0-py311hb02cd75_1.conda#da150e07831537629fb38495fefae7fb https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.8-py311hfecb2dc_0.conda#3920b856b59a909812f1913b96adaad8 diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index fea5857318fc9..536b0aea4e708 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -44,7 +44,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.con https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f @@ -145,7 +145,7 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-1.0.9-h166bdaf_9.conda#46 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.0.9-py311ha362b79_9.conda#ced5340f5dc6cff43a80deac8d0e398f https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda#49ee13eb9b8f44d63879c69b8a40a74b +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 @@ -165,7 +165,7 @@ https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#3 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e @@ -226,7 +226,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h7b9373a_16. https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h0c412b5_8.conda#80e27e7982af989ebc2e0f0d57c75ea7 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.0-pyhcf101f3_0.conda#bee5ed456361bfe8af502beaf5db82e2 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index cb602ebd902d8..5b9e34e990976 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -22,7 +22,7 @@ https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb -https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda#db409b7c1720428638e7c0d509d3e1b5 +https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f @@ -56,7 +56,7 @@ https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1 https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 -https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.6-pyhd8ed1ab_0.conda#49ee13eb9b8f44d63879c69b8a40a74b +https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 @@ -71,7 +71,7 @@ https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_open https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.1.1-py311hf88fc01_0.conda#0415141f4e3d4dad3c39ad4718936352 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac @@ -94,7 +94,7 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_h1ea3ea9_openblas.conda#064f82e2cd0146b28a0bda3ca9b6fb7e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.1-py311h8032f78_0.conda#3ac73c673df24589b5b84d43a4afd235 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py311h8032f78_0.conda#138e5d98884407fcc8ccc6088574b1c7 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 @@ -102,7 +102,7 @@ https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-openblas.conda#81122e5749efe4c34c07471ad866eab1 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.0-pyhcf101f3_0.conda#bee5ed456361bfe8af502beaf5db82e2 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda#16e3f039c0aa6446513e94ab18a8784b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda#910f28a05c178feba832f842155cbfff diff --git a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock index 7031254c0123d..523052fc68233 100644 --- a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock @@ -104,7 +104,7 @@ https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda https://conda.anaconda.org/conda-forge/win-64/fonttools-4.62.0-py311h3f79411_0.conda#5abfb5569386a6a7e8f6f88d4845af10 https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_0.conda#507b36518b5a595edda64066c820a6ef https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/win-64/pillow-12.1.1-py311h17b8079_0.conda#b17fe050184f2f7fd03e094a5fdc56ae +https://conda.anaconda.org/conda-forge/win-64/pillow-12.2.0-py311h17b8079_0.conda#80382ea49ddde54350b5ca5135be2838 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.1-py311h9c22a71_0.conda#24047b0ff1fa264427c456e4c7f68283 @@ -115,5 +115,5 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/win-64/harfbuzz-13.2.1-h5a1b470_0.conda#f6414f2f905326bcf0e7c87a04d175a2 https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.0-pl5321hfcac499_3.conda#b53193a38f677045dae28f7039122035 -https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.0-py311he824864_0.conda#4f0afbd4b6e9d6e5d6c32cd5edcb0eb7 +https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.0-py311he824864_1.conda#19b367dda0ee6f48f67d0d72a3fd1a12 https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py311h1ea47a8_0.conda#64fe28aa2486e41918239d385336e88e From 6b034924aec3a755f6fc5352919986695dce2a14 Mon Sep 17 00:00:00 2001 From: Mohammad Ahmadullah Khan <115063771+MAUK9086@users.noreply.github.com> Date: Mon, 6 Apr 2026 23:54:55 +0530 Subject: [PATCH 333/462] FIX Use check_array in inverse_transform for Power/QuantileTransformer (#33268) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.preprocessing/33268.fix.rst | 5 +++ sklearn/preprocessing/_data.py | 29 +++++++++++++-- sklearn/preprocessing/tests/test_data.py | 36 +++++++++++++++++-- 3 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.preprocessing/33268.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.preprocessing/33268.fix.rst b/doc/whats_new/upcoming_changes/sklearn.preprocessing/33268.fix.rst new file mode 100644 index 0000000000000..1c697b32e18bc --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.preprocessing/33268.fix.rst @@ -0,0 +1,5 @@ +- :class:`~sklearn.preprocessing.PowerTransformer` and + :class:`~sklearn.preprocessing.QuantileTransformer` now don't raise a warning in + :meth:`inverse_transform` related to feature names if :meth:`fit` is called using data with + feature names. + By :user:`Thibault <ThibaultDECO>` and :user:`Mohammad Ahmadullah Khan <MAUK9086>`. diff --git a/sklearn/preprocessing/_data.py b/sklearn/preprocessing/_data.py index f7dd221150323..b4deda955ac1a 100644 --- a/sklearn/preprocessing/_data.py +++ b/sklearn/preprocessing/_data.py @@ -3064,10 +3064,21 @@ def inverse_transform(self, X): The projected data. """ check_is_fitted(self) - X = self._check_inputs( - X, in_fit=False, accept_sparse_negative=True, copy=self.copy + X = check_array( + X, + accept_sparse="csc", + copy=self.copy, + dtype=FLOAT_DTYPES, + force_writeable=True, + ensure_all_finite="allow-nan", ) + if not X.shape[1] == self.n_features_in_: + raise ValueError( + f"X has {X.shape[1]} features, but QuantileTransformer " + f"is expecting {self.n_features_in_} features as input." + ) + return self._transform(X, inverse=True) def __sklearn_tags__(self): @@ -3482,7 +3493,19 @@ def inverse_transform(self, X): The original data. """ check_is_fitted(self) - X = self._check_input(X, in_fit=False, check_shape=True) + X = check_array( + X, + copy=self.copy, + dtype=FLOAT_DTYPES, + force_writeable=True, + ensure_all_finite="allow-nan", + ) + + if not X.shape[1] == self.n_features_in_: + raise ValueError( + f"X has {X.shape[1]} features, but PowerTransformer " + f"is expecting {self.n_features_in_} features as input." + ) if self.standardize: X = self._scaler.inverse_transform(X) diff --git a/sklearn/preprocessing/tests/test_data.py b/sklearn/preprocessing/tests/test_data.py index e4a7f1652510c..de16e4973c1cb 100644 --- a/sklearn/preprocessing/tests/test_data.py +++ b/sklearn/preprocessing/tests/test_data.py @@ -2413,8 +2413,8 @@ def test_power_transformer_shape_exception(method): def test_power_transformer_lambda_zero(): - pt = PowerTransformer(method="box-cox", standardize=False) X = np.abs(X_2d)[:, 0:1] + pt = PowerTransformer(method="box-cox", standardize=False).fit(X) # Test the lambda = 0 case pt.lambdas_ = np.array([0]) @@ -2458,7 +2458,7 @@ def test_optimization_power_transformer(method, lmbda): # Clip the data here to make sure the inequality is valid. X = np.clip(X, -1 / lmbda + 1e-5, None) - pt = PowerTransformer(method=method, standardize=False) + pt = PowerTransformer(method=method, standardize=False).fit(np.abs(X)) pt.lambdas_ = [lmbda] X_inv = pt.inverse_transform(X) @@ -2472,7 +2472,7 @@ def test_optimization_power_transformer(method, lmbda): def test_invserse_box_cox(): # output nan if the input is invalid - pt = PowerTransformer(method="box-cox", standardize=False) + pt = PowerTransformer(method="box-cox", standardize=False).fit([[1.0], [2.0]]) pt.lambdas_ = [0.5] X_inv = pt.inverse_transform([[-2.1]]) assert np.isnan(X_inv) @@ -2837,3 +2837,33 @@ def test_yeojohnson_for_different_scipy_version(): """Check that the results are consistent across different SciPy versions.""" pt = PowerTransformer(method="yeo-johnson").fit(X_1col) pt.lambdas_[0] == pytest.approx(0.99546157, rel=1e-7) + + +@pytest.mark.parametrize("TransformerClass", [PowerTransformer, QuantileTransformer]) +def test_transformer_inverse_transform_feature_names_warning(TransformerClass): + """Check that inverse_transform does not raise a warning about feature + names when fitted on a DataFrame and transforming a NumPy array. + + Non-regression test for issue #31947. + """ + pd = pytest.importorskip("pandas") + + X_df = pd.DataFrame({"a": [1.0, 2.0, 3.0], "b": [4.0, 5.0, 6.0]}) + transformer = TransformerClass() + transformer.fit(X_df) + + with warnings.catch_warnings(): + warnings.simplefilter("error") + transformer.inverse_transform(X_df.to_numpy()) + + +@pytest.mark.parametrize("TransformerClass", [PowerTransformer, QuantileTransformer]) +def test_transformer_inverse_transform_shape_error(TransformerClass): + """Check that an informative error is raised when the input shape is incorrect.""" + X = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]) + transformer = TransformerClass().fit(X) + + X_wrong = np.array([[1.0], [2.0], [3.0]]) + msg = f"X has 1 features, but {TransformerClass.__name__} is expecting 2 features" + with pytest.raises(ValueError, match=msg): + transformer.inverse_transform(X_wrong) From d93d84c22653ea3430fc8bb4b942f37a773581e0 Mon Sep 17 00:00:00 2001 From: Christian Veenhuis <124370897+ChVeen@users.noreply.github.com> Date: Mon, 6 Apr 2026 21:12:21 +0200 Subject: [PATCH 334/462] MNT FIX grammar issue in the `AGENTS.md` file (#33700) --- AGENTS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 79d71164c33ec..76f23d4b35587 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # AGENTS Instruction -This file contains is additional guidance for AI agents and other AI editors. +This file contains additional guidance for AI agents and other AI editors. ## **REQUIRED: AI/Agent Disclosure** From 5a10bb798914191f7d22ffa4e5ed85c28ce4e137 Mon Sep 17 00:00:00 2001 From: Karthik <karthik.06.dulam@gmail.com> Date: Tue, 7 Apr 2026 04:41:19 +0530 Subject: [PATCH 335/462] DOC Fix misleading parameter docs for `n_clusters` in Spectral Clustering (#33563) --- sklearn/cluster/_spectral.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sklearn/cluster/_spectral.py b/sklearn/cluster/_spectral.py index 877c849a10ef7..ac1d10c8b715e 100644 --- a/sklearn/cluster/_spectral.py +++ b/sklearn/cluster/_spectral.py @@ -404,7 +404,7 @@ class SpectralClustering(ClusterMixin, BaseEstimator): Parameters ---------- n_clusters : int, default=8 - The dimension of the projection subspace. + Number of clusters to extract. eigen_solver : {'arpack', 'lobpcg', 'amg'}, default=None The eigenvalue decomposition strategy to use. AMG requires pyamg From d43c433e52ec78dbe5ce1f61077d92c8b0e3dac0 Mon Sep 17 00:00:00 2001 From: Mohammad Ahmadullah Khan <115063771+MAUK9086@users.noreply.github.com> Date: Tue, 7 Apr 2026 04:58:45 +0530 Subject: [PATCH 336/462] PERF Faster FastICA for deflation + logcosh (#33269) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.decomposition/33269.efficiency.rst | 3 +++ sklearn/decomposition/_fastica.py | 13 ++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.decomposition/33269.efficiency.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.decomposition/33269.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.decomposition/33269.efficiency.rst new file mode 100644 index 0000000000000..59affd41b45f7 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.decomposition/33269.efficiency.rst @@ -0,0 +1,3 @@ +- :class:`~sklearn.decomposition.FastICA` with `algorithm='deflation'` and + `fun='logcosh'` is now an order of magnitude faster. + By :user:`Mohammad Ahmadullah Khan <MAUK9086>`. diff --git a/sklearn/decomposition/_fastica.py b/sklearn/decomposition/_fastica.py index ea72a3790631f..59bffc7621d54 100644 --- a/sklearn/decomposition/_fastica.py +++ b/sklearn/decomposition/_fastica.py @@ -140,16 +140,19 @@ def _ica_par(X, tol, g, fun_args, max_iter, w_init): return W, ii + 1 -# Some standard non-linear functions. -# XXX: these should be optimized, as they can be a bottleneck. def _logcosh(x, fun_args=None): - alpha = fun_args.get("alpha", 1.0) # comment it out? + alpha = fun_args.get("alpha", 1.0) x *= alpha gx = np.tanh(x, x) # apply the tanh inplace + + if x.ndim == 1: + return gx, alpha * (1 - gx**2) + + # When the input is 2D, compute in a loop to avoid extra allocation + # of array of shape x.shape g_x = np.empty(x.shape[0], dtype=x.dtype) - # XXX compute in chunks to avoid extra allocation - for i, gx_i in enumerate(gx): # please don't vectorize. + for i, gx_i in enumerate(gx): g_x[i] = (alpha * (1 - gx_i**2)).mean() return gx, g_x From 01901eb0b56b4386b5678c8b7d3ebfa15f4ddb63 Mon Sep 17 00:00:00 2001 From: Wiktor Olszowy <olszowyw@gmail.com> Date: Tue, 7 Apr 2026 02:39:27 +0200 Subject: [PATCH 337/462] DOC Clarify that group-based splitters do not perform class-label stratification (#33037) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- sklearn/model_selection/_split.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sklearn/model_selection/_split.py b/sklearn/model_selection/_split.py index 64517af6a05ad..2dcfe51df71e8 100644 --- a/sklearn/model_selection/_split.py +++ b/sklearn/model_selection/_split.py @@ -210,7 +210,7 @@ class LeaveOneOut(_UnsupportedGroupCVMixin, BaseCrossValidator): See Also -------- LeaveOneGroupOut : For splitting the data according to explicit, - domain-specific stratification of the dataset. + domain-specific grouping of the dataset. GroupKFold : K-fold iterator variant with non-overlapping groups. """ @@ -597,8 +597,8 @@ class GroupKFold(GroupsConsumerMixin, _BaseKFold): See Also -------- - LeaveOneGroupOut : For splitting the data according to explicit - domain-specific stratification of the dataset. + LeaveOneGroupOut : For splitting the data according to explicit, + domain-specific grouping of the dataset. StratifiedKFold : Takes class information into account to avoid building folds with imbalanced class proportions (for binary or multiclass @@ -1324,7 +1324,7 @@ class LeaveOneGroupOut(GroupsConsumerMixin, BaseCrossValidator): Provides train/test indices to split data such that each training set is comprised of all samples except ones belonging to one specific group. - Arbitrary domain specific group information is provided as an array of integers + Arbitrary domain-specific group information is provided as an array of integers that encodes the group of each sample. For instance the groups could be the year of collection of the samples @@ -1441,7 +1441,7 @@ class LeavePGroupsOut(GroupsConsumerMixin, BaseCrossValidator): Provides train/test indices to split data according to a third-party provided group. This group information can be used to encode arbitrary - domain specific stratifications of the samples as integers. + domain-specific groupings of the samples as integers. For instance the groups could be the year of collection of the samples and thus allow for cross-validation against time-based splits. @@ -2081,7 +2081,7 @@ class GroupShuffleSplit(GroupsConsumerMixin, BaseShuffleSplit): Provides randomized train/test indices to split data according to a third-party provided group. This group information can be used to encode - arbitrary domain specific stratifications of the samples as integers. + arbitrary domain-specific groupings of the samples as integers. For instance the groups could be the year of collection of the samples and thus allow for cross-validation against time-based splits. From fa4bbf601b7b553b7defaa6fc09f511aaddc4207 Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre <guillaume@probabl.ai> Date: Wed, 8 Apr 2026 14:59:26 +0200 Subject: [PATCH 338/462] EHN accept metric="l2" with ward linkage in agglomeration clustering (#24681) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.cluster/24681.enhancement.rst | 4 ++ sklearn/cluster/_agglomerative.py | 8 +-- sklearn/cluster/tests/test_hierarchical.py | 50 +++++++++++++++---- 3 files changed, 47 insertions(+), 15 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.cluster/24681.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.cluster/24681.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.cluster/24681.enhancement.rst new file mode 100644 index 0000000000000..5ef1b655f6655 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.cluster/24681.enhancement.rst @@ -0,0 +1,4 @@ +- :class:`cluster.AgglomerativeClustering` and + :class:`cluster.FeatureAgglomeration` now accept `metric="l2"` together with + `linkage="ward"`. `metric="l2"` is equivalent to `metric="euclidean"`. + :pr:`24681` by :user:`Guillaume Lemaitre <glemaitre>`. diff --git a/sklearn/cluster/_agglomerative.py b/sklearn/cluster/_agglomerative.py index 50d1acd37847e..2655ca6c6a4dc 100644 --- a/sklearn/cluster/_agglomerative.py +++ b/sklearn/cluster/_agglomerative.py @@ -796,7 +796,7 @@ class AgglomerativeClustering(ClusterMixin, BaseEstimator): metric : str or callable, default="euclidean" Metric used to compute the linkage. Can be "euclidean", "l1", "l2", "manhattan", "cosine", or "precomputed". If linkage is "ward", only - "euclidean" is accepted. If "precomputed", a distance matrix is needed + "euclidean" and "l2" are accepted. If "precomputed", a distance matrix is needed as input for the fit method. If connectivity is None, linkage is "single" and affinity is not "precomputed" any valid pairwise distance metric can be assigned. @@ -1021,10 +1021,10 @@ def _fit(self, X): "compute_full_tree must be True if distance_threshold is set." ) - if self.linkage == "ward" and self.metric != "euclidean": + if self.linkage == "ward" and self.metric not in ("euclidean", "l2"): raise ValueError( f"{self.metric} was provided as metric. Ward can only " - "work with euclidean distances." + "work with euclidean distances (i.e. 'euclidean' and 'l2')." ) tree_builder = _TREE_BUILDERS[self.linkage] @@ -1142,7 +1142,7 @@ class FeatureAgglomeration( metric : str or callable, default="euclidean" Metric used to compute the linkage. Can be "euclidean", "l1", "l2", "manhattan", "cosine", or "precomputed". If linkage is "ward", only - "euclidean" is accepted. If "precomputed", a distance matrix is needed + "euclidean" and "l2" are accepted. If "precomputed", a distance matrix is needed as input for the fit method. .. versionadded:: 1.2 diff --git a/sklearn/cluster/tests/test_hierarchical.py b/sklearn/cluster/tests/test_hierarchical.py index a4f19abdca9ad..c3261ab6ee747 100644 --- a/sklearn/cluster/tests/test_hierarchical.py +++ b/sklearn/cluster/tests/test_hierarchical.py @@ -227,17 +227,6 @@ def test_agglomerative_clustering(global_random_seed, lil_container): with pytest.raises(ValueError): clustering.fit(X) - # Test that using ward with another metric than euclidean raises an - # exception - clustering = AgglomerativeClustering( - n_clusters=10, - connectivity=connectivity.toarray(), - metric="manhattan", - linkage="ward", - ) - with pytest.raises(ValueError): - clustering.fit(X) - # Test using another metric than euclidean works with linkage complete for metric in PAIRED_DISTANCES.keys(): # Compare our (structured) implementation to scipy @@ -888,3 +877,42 @@ def test_precomputed_connectivity_metric_with_2_connected_components(): assert_array_equal(clusterer.labels_, clusterer_precomputed.labels_) assert_array_equal(clusterer.children_, clusterer_precomputed.children_) + + +@pytest.mark.parametrize("Clustering", [AgglomerativeClustering, FeatureAgglomeration]) +def test_agglomeration_ward_contrained_metric(Clustering): + """Check that we raise an error when 'euclidean' or 'l2' are not passed with + ward linkage.""" + rng = np.random.RandomState(0) + mask = np.ones([10, 10], dtype=bool) + n_samples = 100 + X = rng.randn(n_samples, 50) + connectivity = grid_to_graph(*mask.shape) + + clustering = Clustering( + n_clusters=10, + connectivity=connectivity.toarray(), + metric="manhattan", + linkage="ward", + ) + with pytest.raises(ValueError): + clustering.fit(X) + + +@pytest.mark.parametrize("Clustering", [AgglomerativeClustering, FeatureAgglomeration]) +@pytest.mark.parametrize("metric", ["euclidean", "l2"]) +def test_agglomeration_ward_euclidean(Clustering, metric): + """Check that we can pass 'euclidean' and 'l2' as metric with Ward linkage.""" + rng = np.random.RandomState(0) + mask = np.ones([10, 10], dtype=bool) + n_samples = 100 + X = rng.randn(n_samples, 100) + connectivity = grid_to_graph(*mask.shape) + + clustering = Clustering( + n_clusters=10, + connectivity=connectivity.toarray(), + metric=metric, + linkage="ward", + ) + clustering.fit(X) From 237387b8e71e50d547d9130dd6a147bc83f37596 Mon Sep 17 00:00:00 2001 From: Chani Fainendler <chani20058664@gmail.com> Date: Wed, 8 Apr 2026 16:29:03 +0300 Subject: [PATCH 339/462] FIX: StratifiedGroupKFold errors when n_splits > n_groups (#33176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.model_selection/33176.fix.rst | 3 +++ sklearn/model_selection/_split.py | 8 ++++++++ sklearn/model_selection/tests/test_split.py | 4 ++-- 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.model_selection/33176.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.model_selection/33176.fix.rst b/doc/whats_new/upcoming_changes/sklearn.model_selection/33176.fix.rst new file mode 100644 index 0000000000000..60a181946a4a0 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.model_selection/33176.fix.rst @@ -0,0 +1,3 @@ +- :class:`model_selection.StratifiedGroupKFold` now raises a `ValueError` when + `n_splits` is greater than the number of unique groups, preventing degenerate folds. + By :user:`Chani Fainendler <gitCHANI2005>`. diff --git a/sklearn/model_selection/_split.py b/sklearn/model_selection/_split.py index 2dcfe51df71e8..90055a5a543c1 100644 --- a/sklearn/model_selection/_split.py +++ b/sklearn/model_selection/_split.py @@ -1044,6 +1044,14 @@ def _iter_test_indices(self, X, y, groups): _, groups_inv, groups_cnt = np.unique( groups, return_inverse=True, return_counts=True ) + n_groups = len(groups_cnt) + + if self.n_splits > n_groups: + raise ValueError( + f"Cannot have number of splits n_splits={self.n_splits} greater" + f" than the number of groups: {n_groups}." + ) + y_counts_per_group = np.zeros((len(groups_cnt), n_classes)) for class_idx, group_idx in zip(y_inv, groups_inv): y_counts_per_group[group_idx, class_idx] += 1 diff --git a/sklearn/model_selection/tests/test_split.py b/sklearn/model_selection/tests/test_split.py index 43f6da90a873a..c75c15361fbfc 100644 --- a/sklearn/model_selection/tests/test_split.py +++ b/sklearn/model_selection/tests/test_split.py @@ -217,7 +217,7 @@ def test_2d_y(): StratifiedKFold(), RepeatedKFold(), RepeatedStratifiedKFold(), - StratifiedGroupKFold(), + StratifiedGroupKFold(n_splits=3), ShuffleSplit(), StratifiedShuffleSplit(test_size=0.5), GroupShuffleSplit(), @@ -1783,7 +1783,7 @@ def test_group_kfold(kfold, shuffle, global_random_seed): groups = np.array([1, 1, 1, 2, 2]) X = y = np.ones(len(groups)) with pytest.raises(ValueError, match="Cannot have number of splits.*greater"): - next(GroupKFold(n_splits=3).split(X, y, groups)) + next(kfold(n_splits=3).split(X, y, groups)) def test_time_series_cv(): From fc8225ee5d38794c21d96ec3e79594e6def6ec54 Mon Sep 17 00:00:00 2001 From: Ho Yin Chau <hchau630@berkeley.edu> Date: Thu, 9 Apr 2026 08:38:38 -0400 Subject: [PATCH 340/462] DOC Fix incorrect documented output shape for `predict` method of linear models when `n_targets > 1` (#29026) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- sklearn/linear_model/_base.py | 28 +++++++++++++++--- sklearn/linear_model/_coordinate_descent.py | 12 +++++--- sklearn/linear_model/_least_angle.py | 10 +++++-- sklearn/linear_model/_omp.py | 6 ++-- sklearn/linear_model/_ridge.py | 32 +++++++++++++++++++++ 5 files changed, 74 insertions(+), 14 deletions(-) diff --git a/sklearn/linear_model/_base.py b/sklearn/linear_model/_base.py index 4788b67fde4dc..01b2205b6479b 100644 --- a/sklearn/linear_model/_base.py +++ b/sklearn/linear_model/_base.py @@ -302,13 +302,13 @@ def predict(self, X): Parameters ---------- - X : array-like or sparse matrix, shape (n_samples, n_features) + X : array-like or sparse matrix of shape (n_samples, n_features) Samples. Returns ------- - C : array, shape (n_samples,) - Returns predicted values. + C : ndarray of shape (n_samples,) + Predicted values. """ check_same_namespace(X, self, attribute="coef_", method="predict") return self._decision_function(X) @@ -333,6 +333,26 @@ def _set_intercept(self, X_offset, y_offset, X_scale=None): self.intercept_ = 0.0 +class MultiOutputLinearModel(MultiOutputMixin, LinearModel): + # Provides consistent docstring to `predict` for linear models that support + # multi-output. + def predict(self, X): + """ + Predict using the linear model. + + Parameters + ---------- + X : array-like or sparse matrix of shape (n_samples, n_features) + Samples. + + Returns + ------- + C : ndarray of shape (n_samples,) or (n_samples, n_outputs) + Predicted values. + """ + return super().predict(X) + + # XXX Should this derive from LinearModel? It should be a mixin, not an ABC. # Maybe the n_features checking can be moved to LinearModel. class LinearClassifierMixin(ClassifierMixin): @@ -487,7 +507,7 @@ def sparsify(self): return self -class LinearRegression(MultiOutputMixin, RegressorMixin, LinearModel): +class LinearRegression(RegressorMixin, MultiOutputLinearModel): """ Ordinary least squares Linear Regression. diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index 992510b24d938..378c5df8efc02 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -12,11 +12,15 @@ from joblib import effective_n_jobs from scipy import sparse -from sklearn.base import MultiOutputMixin, RegressorMixin, _fit_context +from sklearn.base import RegressorMixin, _fit_context # mypy error: Module 'sklearn.linear_model' has no attribute '_cd_fast' from sklearn.linear_model import _cd_fast as cd_fast # type: ignore[attr-defined] -from sklearn.linear_model._base import LinearModel, _pre_fit, _preprocess_data +from sklearn.linear_model._base import ( + MultiOutputLinearModel, + _pre_fit, + _preprocess_data, +) from sklearn.model_selection import check_cv from sklearn.utils import Bunch, check_array, check_scalar, metadata_routing from sklearn.utils._metadata_requests import ( @@ -767,7 +771,7 @@ def enet_path( # ElasticNet model -class ElasticNet(MultiOutputMixin, RegressorMixin, LinearModel): +class ElasticNet(RegressorMixin, MultiOutputLinearModel): """Linear regression with combined L1 and L2 priors as regularizer. Minimizes the objective function: @@ -1550,7 +1554,7 @@ def _path_residuals( return this_mse.mean(axis=0) -class LinearModelCV(MultiOutputMixin, LinearModel, ABC): +class LinearModelCV(MultiOutputLinearModel, ABC): """Base class for iterative model fitting along a regularization path.""" _parameter_constraints: dict = { diff --git a/sklearn/linear_model/_least_angle.py b/sklearn/linear_model/_least_angle.py index a1a858c4f9f71..c9c11f2abd543 100644 --- a/sklearn/linear_model/_least_angle.py +++ b/sklearn/linear_model/_least_angle.py @@ -15,9 +15,13 @@ from scipy import interpolate, linalg from scipy.linalg.lapack import get_lapack_funcs -from sklearn.base import MultiOutputMixin, RegressorMixin, _fit_context +from sklearn.base import RegressorMixin, _fit_context from sklearn.exceptions import ConvergenceWarning -from sklearn.linear_model._base import LinearModel, LinearRegression, _preprocess_data +from sklearn.linear_model._base import ( + LinearRegression, + MultiOutputLinearModel, + _preprocess_data, +) from sklearn.model_selection import check_cv # mypy error: Module 'sklearn.utils' has no attribute 'arrayfuncs' @@ -917,7 +921,7 @@ def _lars_path_solver( # Estimator classes -class Lars(MultiOutputMixin, RegressorMixin, LinearModel): +class Lars(RegressorMixin, MultiOutputLinearModel): """Least Angle Regression model aka LAR. Read more in the :ref:`User Guide <least_angle_regression>`. diff --git a/sklearn/linear_model/_omp.py b/sklearn/linear_model/_omp.py index 50014a054d23f..e59fce98316bf 100644 --- a/sklearn/linear_model/_omp.py +++ b/sklearn/linear_model/_omp.py @@ -11,8 +11,8 @@ from scipy import linalg from scipy.linalg.lapack import get_lapack_funcs -from sklearn.base import MultiOutputMixin, RegressorMixin, _fit_context -from sklearn.linear_model._base import LinearModel, _pre_fit +from sklearn.base import RegressorMixin, _fit_context +from sklearn.linear_model._base import LinearModel, MultiOutputLinearModel, _pre_fit from sklearn.model_selection import check_cv from sklearn.utils import Bunch, as_float_array, check_array from sklearn.utils._param_validation import Interval, StrOptions, validate_params @@ -642,7 +642,7 @@ def orthogonal_mp_gram( return np.squeeze(coef) -class OrthogonalMatchingPursuit(MultiOutputMixin, RegressorMixin, LinearModel): +class OrthogonalMatchingPursuit(RegressorMixin, MultiOutputLinearModel): """Orthogonal Matching Pursuit model (OMP). Read more in the :ref:`User Guide <omp>`. diff --git a/sklearn/linear_model/_ridge.py b/sklearn/linear_model/_ridge.py index ee58aa85e2943..5dbdcb5af2404 100644 --- a/sklearn/linear_model/_ridge.py +++ b/sklearn/linear_model/_ridge.py @@ -1271,6 +1271,22 @@ def fit(self, X, y, sample_weight=None): ) return super().fit(X, y, sample_weight=sample_weight) + def predict(self, X): + """ + Predict using the linear model. + + Parameters + ---------- + X : array-like or sparse matrix of shape (n_samples, n_features) + Samples. + + Returns + ------- + C : ndarray of shape (n_samples,) or (n_samples, n_outputs) + Predicted values. + """ + return super().predict(X) + def __sklearn_tags__(self): tags = super().__sklearn_tags__() tags.array_api_support = True @@ -2837,6 +2853,22 @@ def fit(self, X, y, sample_weight=None, **params): super().fit(X, y, sample_weight=sample_weight, **params) return self + def predict(self, X): + """ + Predict using the linear model. + + Parameters + ---------- + X : array-like or sparse matrix of shape (n_samples, n_features) + Samples. + + Returns + ------- + C : ndarray of shape (n_samples,) or (n_samples, n_outputs) + Predicted values. + """ + return super().predict(X) + def _get_scorer_instance(self): """Return a scorer which corresponds to what's defined in RegressorMixin parent class. This is used for routing `sample_weight`. From 7fea2089affd436ff92c48a1a1fa90bbb37b2efe Mon Sep 17 00:00:00 2001 From: "Christine P. Chai" <star1327p@gmail.com> Date: Thu, 9 Apr 2026 06:50:29 -0700 Subject: [PATCH 341/462] DOC: Add Multi-Label Classification article URL to Hamming Loss (#33714) --- sklearn/metrics/_classification.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 3eea92e67fb69..316dcc5711862 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -3291,8 +3291,10 @@ def hamming_loss(y_true, y_pred, *, sample_weight=None): References ---------- - .. [1] Grigorios Tsoumakas, Ioannis Katakis. Multi-Label Classification: - An Overview. International Journal of Data Warehousing & Mining, + .. [1] Grigorios Tsoumakas, Ioannis Katakis. + `Multi-Label Classification: An Overview + <https://people.iee.ihu.gr/~stoug/odep/papers/Multi-Label%20Classification:%20An%20Overview.pdf>`_. + International Journal of Data Warehousing & Mining, 3(3), 1-13, July-September 2007. .. [2] `Wikipedia entry on the Hamming distance From 506ab6e59c722c0d41026e8566898cb279109fc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20du=20Boisberranger?= <jeremie@probabl.ai> Date: Thu, 9 Apr 2026 17:09:05 +0200 Subject: [PATCH 342/462] MNT Simplify hstack logic in ColumnTransformer (#32205) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérôme Dockès <jerome@dockes.org> --- sklearn/compose/_column_transformer.py | 82 +++++-------------- .../compose/tests/test_column_transformer.py | 58 ++++++------- sklearn/utils/_set_output.py | 7 +- 3 files changed, 50 insertions(+), 97 deletions(-) diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index 5de8f78b229ba..83455cd9f62bf 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -597,12 +597,17 @@ def _get_feature_name_out_for_transformer(self, name, trans, feature_names_in): column_indices = self._transformer_to_input_indices[name] names = feature_names_in[column_indices] # An actual transformer - if not hasattr(trans, "get_feature_names_out"): + if hasattr(trans, "get_feature_names_out"): + return trans.get_feature_names_out(names) + elif hasattr(self, "_transformers_feature_names_out"): + # Fallback to feature names returned by transformers that output + # dataframes but don't implement get_feature_names_out. + return self._transformers_feature_names_out[self.output_indices_[name]] + else: raise AttributeError( f"Transformer {name} (type {type(trans).__name__}) does " "not provide get_feature_names_out." ) - return trans.get_feature_names_out(names) def get_feature_names_out(self, input_features=None): """Get output feature names for transformation. @@ -1146,68 +1151,21 @@ def _hstack(self, Xs, *, n_samples): Xs = [f.toarray() if sparse.issparse(f) else f for f in Xs] adapter = _get_container_adapter("transform", self) if adapter and all(adapter.is_supported_container(X) for X in Xs): - # rename before stacking as it avoids to error on temporary duplicated - # columns - transformer_names = [ - t[0] - for t in self._iter( - fitted=True, - column_as_labels=False, - skip_drop=True, - skip_empty_columns=True, + # Store feature names out of transformers in case they don't implement + # get_feature_names_out + self._transformers_feature_names_out = np.hstack( + [_get_feature_names(X) for X in Xs] + ) + + # Rename all columns to avoid duplicated column names. + # The names are not important here as final column names will be + # generated by the set_output wrapper using `get_feature_names_out`. + Xs = [ + adapter.rename_columns( + X, [f"tmp_col_name_{i}_{j}" for j in range(X.shape[1])] ) + for i, X in enumerate(Xs) ] - feature_names_outs = [X.columns for X in Xs if X.shape[1] != 0] - if self.verbose_feature_names_out: - # `_add_prefix_for_feature_names_out` takes care about raising - # an error if there are duplicated columns. - feature_names_outs = self._add_prefix_for_feature_names_out( - list(zip(transformer_names, feature_names_outs)) - ) - else: - # check for duplicated columns and raise if any - feature_names_outs = list(chain.from_iterable(feature_names_outs)) - feature_names_count = Counter(feature_names_outs) - if any(count > 1 for count in feature_names_count.values()): - duplicated_feature_names = sorted( - name - for name, count in feature_names_count.items() - if count > 1 - ) - err_msg = ( - "Duplicated feature names found before concatenating the" - " outputs of the transformers:" - f" {duplicated_feature_names}.\n" - ) - for transformer_name, X in zip(transformer_names, Xs): - if X.shape[1] == 0: - continue - dup_cols_in_transformer = sorted( - set(X.columns).intersection(duplicated_feature_names) - ) - if len(dup_cols_in_transformer): - err_msg += ( - f"Transformer {transformer_name} has conflicting " - f"columns names: {dup_cols_in_transformer}.\n" - ) - raise ValueError( - err_msg - + "Either make sure that the transformers named above " - "do not generate columns with conflicting names or set " - "verbose_feature_names_out=True to automatically " - "prefix to the output feature names with the name " - "of the transformer to prevent any conflicting " - "names." - ) - - names_idx = 0 - for X in Xs: - if X.shape[1] == 0: - continue - names_out = feature_names_outs[names_idx : names_idx + X.shape[1]] - adapter.rename_columns(X, names_out) - names_idx += X.shape[1] - output = adapter.hstack(Xs) output_samples = output.shape[0] if output_samples != n_samples: diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index 9f69a956d7c38..76f70d5c2b51b 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -2614,6 +2614,23 @@ def test_column_transformer_remainder_passthrough_naming_consistency(transform_o assert preprocessor.get_feature_names_out().tolist() == expected_column_names +# DfOutTransformer that does not define get_feature_names_out +class DfOutTransformer(BaseEstimator): + def __init__(self, offset=1.0): + self.offset = offset + + def fit(self, X, y=None): + return self + + def transform(self, X, y=None): + return X - self.offset + + def set_output(self, transform=None): + # This transformer will always output a DataFrame regardless of the + # configuration. + return self + + @pytest.mark.parametrize("dataframe_lib", ["pandas", "polars"]) def test_column_transformer_column_renaming(dataframe_lib): """Check that we properly rename columns when using `ColumnTransformer` and @@ -2631,15 +2648,17 @@ def test_column_transformer_column_renaming(dataframe_lib): ("A", "passthrough", ["x1", "x2", "x3"]), ("B", FunctionTransformer(), ["x1", "x2"]), ("C", StandardScaler(), ["x1", "x3"]), + ("D", DfOutTransformer(), ["x2", "x3"]), # special case of a transformer returning 0-columns, e.g feature selector ( - "D", + "E", FunctionTransformer(lambda x: _safe_indexing(x, [], axis=1)), ["x1", "x2", "x3"], ), ], - verbose_feature_names_out=True, ).set_output(transform=dataframe_lib) + + # by default, verbose_feature_names_out is True df_trans = transformer.fit_transform(df) assert list(df_trans.columns) == [ "A__x1", @@ -2649,39 +2668,12 @@ def test_column_transformer_column_renaming(dataframe_lib): "B__x2", "C__x1", "C__x3", + "D__x2", + "D__x3", ] - -@pytest.mark.parametrize("dataframe_lib", ["pandas", "polars"]) -def test_column_transformer_error_with_duplicated_columns(dataframe_lib): - """Check that we raise an error when using `ColumnTransformer` and - the columns names are duplicated between transformers.""" - lib = pytest.importorskip(dataframe_lib) - - df = lib.DataFrame({"x1": [1, 2, 3], "x2": [10, 20, 30], "x3": [100, 200, 300]}) - - transformer = ColumnTransformer( - transformers=[ - ("A", "passthrough", ["x1", "x2", "x3"]), - ("B", FunctionTransformer(), ["x1", "x2"]), - ("C", StandardScaler(), ["x1", "x3"]), - # special case of a transformer returning 0-columns, e.g feature selector - ( - "D", - FunctionTransformer(lambda x: _safe_indexing(x, [], axis=1)), - ["x1", "x2", "x3"], - ), - ], - verbose_feature_names_out=False, - ).set_output(transform=dataframe_lib) - err_msg = re.escape( - "Duplicated feature names found before concatenating the outputs of the " - "transformers: ['x1', 'x2', 'x3'].\n" - "Transformer A has conflicting columns names: ['x1', 'x2', 'x3'].\n" - "Transformer B has conflicting columns names: ['x1', 'x2'].\n" - "Transformer C has conflicting columns names: ['x1', 'x3'].\n" - ) - with pytest.raises(ValueError, match=err_msg): + transformer.set_params(verbose_feature_names_out=False) + with pytest.raises(ValueError, match=r"Output feature names:.*are not unique"): transformer.fit_transform(df) diff --git a/sklearn/utils/_set_output.py b/sklearn/utils/_set_output.py index 220dc69f3390d..46c3aa07f2524 100644 --- a/sklearn/utils/_set_output.py +++ b/sklearn/utils/_set_output.py @@ -27,8 +27,11 @@ def get_columns(columns): if callable(columns): try: return columns() - except Exception: - return None + except AttributeError as e: + if "does not provide get_feature_names_out" in str(e): + return None + else: + raise return columns From d9a1b74f0d39ed655d7ddfe2a4303f40002ec1f8 Mon Sep 17 00:00:00 2001 From: EdenRochmanSharabi <91745090+EdenRochmanSharabi@users.noreply.github.com> Date: Thu, 9 Apr 2026 17:52:48 +0200 Subject: [PATCH 343/462] FIX reconstruct_from_patches_2d when patch size equals image size (#33643) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.feature_extraction/33643.fix.rst | 4 ++++ sklearn/feature_extraction/image.py | 4 +++- .../feature_extraction/tests/test_image.py | 23 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.feature_extraction/33643.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.feature_extraction/33643.fix.rst b/doc/whats_new/upcoming_changes/sklearn.feature_extraction/33643.fix.rst new file mode 100644 index 0000000000000..e04b8446a8354 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.feature_extraction/33643.fix.rst @@ -0,0 +1,4 @@ +- :func:`feature_extraction.image.reconstruct_from_patches_2d` now produces + correct results when a patch dimension equals the corresponding image + dimension. + By :user:`Eden Rochman <EdenRochmanSharabi>`. diff --git a/sklearn/feature_extraction/image.py b/sklearn/feature_extraction/image.py index 32c2765cd841a..e8f58b5f37e0b 100644 --- a/sklearn/feature_extraction/image.py +++ b/sklearn/feature_extraction/image.py @@ -521,7 +521,9 @@ def reconstruct_from_patches_2d(patches, image_size): for j in range(i_w): # divide by the amount of overlap # XXX: is this the most efficient way? memory-wise yes, cpu wise? - img[i, j] /= float(min(i + 1, p_h, i_h - i) * min(j + 1, p_w, i_w - j)) + img[i, j] /= float( + min(i + 1, p_h, n_h, i_h - i) * min(j + 1, p_w, n_w, i_w - j) + ) return img diff --git a/sklearn/feature_extraction/tests/test_image.py b/sklearn/feature_extraction/tests/test_image.py index cb490fcd576ee..6d393a85f740d 100644 --- a/sklearn/feature_extraction/tests/test_image.py +++ b/sklearn/feature_extraction/tests/test_image.py @@ -14,6 +14,7 @@ img_to_graph, reconstruct_from_patches_2d, ) +from sklearn.utils._testing import assert_allclose def test_img_to_graph(): @@ -223,6 +224,28 @@ def test_reconstruct_patches_perfect_color(orange_face): np.testing.assert_array_almost_equal(face, face_reconstructed) +@pytest.mark.parametrize( + "image_size, patch_size", + [ + ((128, 256), (128, 128)), # patch_h == image_h + ((256, 128), (128, 128)), # patch_w == image_w + ((128, 128), (128, 128)), # patch == image + ((128, 256, 3), (128, 128)), # patch_h == image_h, with channels + ], +) +def test_reconstruct_patches_edge_patch_size(image_size, patch_size): + """Check that reconstruct_from_patches_2d works when a patch dimension + equals the corresponding image dimension. + + Non-regression test for https://github.com/scikit-learn/scikit-learn/issues/10910 + """ + rng = np.random.RandomState(0) + image = rng.rand(*image_size) + patches = extract_patches_2d(image, patch_size) + reconstructed = reconstruct_from_patches_2d(patches, image_size) + assert_allclose(image, reconstructed) + + def test_patch_extractor_fit(downsampled_face_collection, global_random_seed): faces = downsampled_face_collection extr = PatchExtractor( From 6b7366ba21e02401395c4d31c5760cafbe525b0e Mon Sep 17 00:00:00 2001 From: Jake Blitch <43113549+blitchj@users.noreply.github.com> Date: Thu, 9 Apr 2026 11:25:10 -0500 Subject: [PATCH 344/462] FIX RFE use stable sort for the feature importances for deterministic results (#29532) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../upcoming_changes/sklearn.feature_selection/29532.fix.rst | 4 ++++ sklearn/feature_selection/_rfe.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.feature_selection/29532.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.feature_selection/29532.fix.rst b/doc/whats_new/upcoming_changes/sklearn.feature_selection/29532.fix.rst new file mode 100644 index 0000000000000..5b631123a7885 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.feature_selection/29532.fix.rst @@ -0,0 +1,4 @@ +- :class:`feature_selection.RFE` now uses stable sorting when ranking feature + importances. This ensures that the feature selection is deterministic and consistent + across runs when feature importances are tied. + By :user:`blitchj <blitchj>`. diff --git a/sklearn/feature_selection/_rfe.py b/sklearn/feature_selection/_rfe.py index 2b1317d49128f..011dbc7b515f1 100644 --- a/sklearn/feature_selection/_rfe.py +++ b/sklearn/feature_selection/_rfe.py @@ -347,7 +347,7 @@ def _fit(self, X, y, step_score=None, **fit_params): self.importance_getter, transform_func="square", ) - ranks = np.argsort(importances) + ranks = np.argsort(importances, kind="stable") # for sparse case ranks is matrix ranks = np.ravel(ranks) From f3182980c56943664f6b1ff30e8d0c436bd7139e Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Thu, 9 Apr 2026 21:29:47 +0200 Subject: [PATCH 345/462] DOC move Advanced Plotting With Partial Dependence from miscellaneous to inspection (#33625) --- doc/conf.py | 3 +++ .../plot_partial_dependence_visualization_api.py | 0 2 files changed, 3 insertions(+) rename examples/{miscellaneous => inspection}/plot_partial_dependence_visualization_api.py (100%) diff --git a/doc/conf.py b/doc/conf.py index b0bed18209e93..8cfa3ef1f4b4a 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -515,6 +515,9 @@ def add_js_css_files(app, pagename, templatename, context, doctree): "auto_examples/linear_model/plot_sgd_comparison": ( "auto_examples/linear_model/plot_sgd_loss_functions" ), + "auto_examples/miscellaneous/plot_partial_dependence_visualization_api": ( + "auto_examples/inspection/plot_partial_dependence_visualization_api" + ), } html_context["redirects"] = redirects for old_link in redirects: diff --git a/examples/miscellaneous/plot_partial_dependence_visualization_api.py b/examples/inspection/plot_partial_dependence_visualization_api.py similarity index 100% rename from examples/miscellaneous/plot_partial_dependence_visualization_api.py rename to examples/inspection/plot_partial_dependence_visualization_api.py From 362ebd5d5b10a45a8f089b8c454e834d76ec478a Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 13 Apr 2026 04:14:11 -0400 Subject: [PATCH 346/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33732) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/circle/doc_linux-64_conda.lock | 42 ++++----- .../doc_min_dependencies_linux-64_conda.lock | 38 ++++---- build_tools/github/debian_32bit_lock.txt | 2 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 34 ++++---- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 20 ++--- .../pylatest_conda_forge_osx-arm64_conda.lock | 24 +++--- ...st_pip_openblas_pandas_linux-64_conda.lock | 12 +-- ...n_conda_forge_arm_linux-aarch64_conda.lock | 86 +++++++++---------- ...nblas_min_dependencies_linux-64_conda.lock | 28 +++--- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 14 +-- ...min_conda_forge_openblas_win-64_conda.lock | 16 ++-- build_tools/github/ubuntu_atlas_lock.txt | 2 +- 12 files changed, 159 insertions(+), 159 deletions(-) diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 6e807d21dd65f..2464e1438ad97 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -17,7 +17,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda# https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.2-h4922eb0_0.conda#2a60ab96432bc74eedbcda8a528080a1 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.3-h4922eb0_0.conda#f7781cb22afa62ef27fd0b3300c53c86 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -37,18 +37,18 @@ https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a3 https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 -https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 +https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda#7af961ef4aa2c1136e11dd43ded245ab https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.8.1-h1fbca29_0.conda#d83958768626b3c8471ce032e28afcd3 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -99,7 +99,7 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb5 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 @@ -115,7 +115,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.con https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_22.conda#0b6cd616dab5e509c5c368d58a01982d +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_23.conda#b6090b005c6e1947e897c926caac1286 https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 @@ -141,7 +141,7 @@ https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 -https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 +https://conda.anaconda.org/conda-forge/noarch/click-8.3.2-pyhc90fa1f_0.conda#4d18bc3af7cfcea97bd817164672a08c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.15-py311hd8ed1ab_0.conda#bf0d09d5c2b61aaf7b11c551c8545cfa https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -151,8 +151,8 @@ https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/doit-0.37.0-pyhcf101f3_0.conda#37b3d4c558f2bb2b5378c43f4d6f1fb5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h31f076a_22.conda#5e6d687088defd7740e973f604e0a8e2 -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h7ab9642_22.conda#ac8519fa5fe0e5d779b5f6d658c10ed5 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h7499c90_23.conda#3a937700705778ab8f5a6ce4f38eccca +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h91b0f8e_23.conda#12d093c7df954a01b396a748442bd5cb https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -165,23 +165,23 @@ https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b96 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.2-hf7376ad_0.conda#7147b0792a803cd5b9929ce5d48f7818 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.18.1-pyhcf101f3_1.conda#30bec5e8f4c3969e2b1bd407c5e52afb +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.19.0-pyhcf101f3_0.conda#b94cbc2227cdca1e9a65d7ad4ee636c1 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.24.1-pyhd8ed1ab_0.conda#7526d20621b53440b0aae45d4797847e +https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda#a11ab1f31af799dd93c3a39881528884 https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda#7d9daffbb8d8e0af0f769dbbcd173a54 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef @@ -231,16 +231,16 @@ https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0 https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a -https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 +https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.0.0-pyhd8ed1ab_0.conda#724309d702b3a44f59987f9be424c040 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_0.conda#9b47a4cd3aabb73201a2b8ed9f127189 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 @@ -269,7 +269,7 @@ https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.c https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 -https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 +https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.0.0-pyhd8ed1ab_0.conda#62fa494c03634a688a28748902579881 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda#7b8bace4943e0dc345fc45938826f2b8 @@ -278,7 +278,7 @@ https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_2.conda#c6ba2de6b22dedf2f20eba3bde1dbe8e https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b @@ -308,7 +308,7 @@ https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311h724c32c_4.conda#d04e508f5a03162c8bab4586a65d00bf https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 -https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.0-pyhcf101f3_0.conda#b14079a39ae60ac7ad2ec3d9eab075ca +https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda#2bce0d047658a91b99441390b9b27045 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py311h8032f78_0.conda#138e5d98884407fcc8ccc6088574b1c7 https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 1a1a8111b39d3..50a202b313025 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -17,7 +17,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda# https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.2-h4922eb0_0.conda#2a60ab96432bc74eedbcda8a528080a1 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.3-h4922eb0_0.conda#f7781cb22afa62ef27fd0b3300c53c86 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -39,19 +39,19 @@ https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a3 https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 -https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 +https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.8.1-h1fbca29_0.conda#d83958768626b3c8471ce032e28afcd3 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -109,7 +109,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_1 https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 @@ -124,7 +124,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.con https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_22.conda#0b6cd616dab5e509c5c368d58a01982d +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_23.conda#b6090b005c6e1947e897c926caac1286 https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda#b52b769cd13f7adaa6ccdc68ef801709 https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 @@ -149,15 +149,15 @@ https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 -https://conda.anaconda.org/conda-forge/noarch/click-8.3.1-pyh8f84b5b_1.conda#ea8a6c3256897cc31263de9f455e25d9 +https://conda.anaconda.org/conda-forge/noarch/click-8.3.2-pyhc90fa1f_0.conda#4d18bc3af7cfcea97bd817164672a08c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h31f076a_22.conda#5e6d687088defd7740e973f604e0a8e2 -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h7ab9642_22.conda#ac8519fa5fe0e5d779b5f6d658c10ed5 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h7499c90_23.conda#3a937700705778ab8f5a6ce4f38eccca +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h91b0f8e_23.conda#12d093c7df954a01b396a748442bd5cb https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -166,16 +166,16 @@ https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.2-hf7376ad_0.conda#7147b0792a803cd5b9929ce5d48f7818 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f @@ -209,14 +209,14 @@ https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.cond https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a -https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.5.2-pyhd8ed1ab_0.conda#c85c76dc67d75619a92f51dfbce06992 +https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.0.0-pyhd8ed1ab_0.conda#724309d702b3a44f59987f9be424c040 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.3-default_h99862b1_0.conda#4642265acfa1ad8dfe96c89d8d7b38fe +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_0.conda#9b47a4cd3aabb73201a2b8ed9f127189 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda#9f6a8664f1fe752f79473eeb9bf33a60 @@ -230,14 +230,14 @@ https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 -https://conda.anaconda.org/conda-forge/noarch/importlib-resources-6.5.2-pyhd8ed1ab_0.conda#e376ea42e9ae40f3278b0f79c9bf9826 +https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.0.0-pyhd8ed1ab_0.conda#62fa494c03634a688a28748902579881 https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.5-pyhd8ed1ab_0.conda#4c8327180586e7b1cd8b6815fc8827f1 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda#d53ffc0edc8eabf4253508008493c5bc https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 diff --git a/build_tools/github/debian_32bit_lock.txt b/build_tools/github/debian_32bit_lock.txt index 4a7f8993d7019..67aae0f7dd32b 100644 --- a/build_tools/github/debian_32bit_lock.txt +++ b/build_tools/github/debian_32bit_lock.txt @@ -33,7 +33,7 @@ pygments==2.20.0 # via pytest pyproject-metadata==0.11.0 # via meson-python -pytest==9.0.2 +pytest==9.0.3 # via # -r build_tools/github/debian_32bit_requirements.txt # pytest-cov diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock index e858e3c354f92..81c957c22efe4 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -16,7 +16,7 @@ https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.2-h4922eb0_0.conda#2a60ab96432bc74eedbcda8a528080a1 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.3-h4922eb0_0.conda#f7781cb22afa62ef27fd0b3300c53c86 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 @@ -37,19 +37,19 @@ https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a3 https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 -https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 +https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 @@ -93,7 +93,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.cond https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-hc87160b_0.conda#dde6a3e4fe6bb2ecd2a7050dd1e701fb https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 @@ -103,7 +103,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 @@ -129,7 +129,7 @@ https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.14.1-h3d65ac4_0.conda#fa4e76aac348ef9c27e72c79b02833fc https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 @@ -145,13 +145,13 @@ https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda#3bb89e4f795e5414addaa531d6b1500a +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b -https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.3.2-py314h42812f9_0.conda#511748f9debe034ff88eef99bc215fd3 +https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.4.0-py314h42812f9_0.conda#bf19183372b78e064d41f42c1a1846a1 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 @@ -161,7 +161,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.2-hf7376ad_0.conda#7147b0792a803cd5b9929ce5d48f7818 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde @@ -170,11 +170,11 @@ https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d0 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f -https://conda.anaconda.org/conda-forge/linux-64/playwright-1.58.2-h5585027_0.conda#1650804f26dd992fd7418fe603f1c653 +https://conda.anaconda.org/conda-forge/linux-64/playwright-1.59.1-h5585027_0.conda#3ec4a57c54725b9be3cad126ccbad2c0 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 @@ -205,11 +205,11 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_0.conda#9b47a4cd3aabb73201a2b8ed9f127189 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 @@ -217,7 +217,7 @@ https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda# https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.1-pyhd8ed1ab_0.conda#eadf0f76d9121a6297be754e9d7cc099 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.3-h4df99d1_101.conda#235765e4ea0d0301c75965985163b5a1 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda#a4059bc12930bddeb41aef71537ffaed https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 @@ -230,7 +230,7 @@ https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.c https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.58.0-pyhcf101f3_0.conda#3b886c49cf44aa133d0eb07e4d0cac89 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_2.conda#c6ba2de6b22dedf2f20eba3bde1dbe8e https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 7e41b0d52d9e0..66d3067f4654f 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -9,17 +9,17 @@ https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda#4173a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda#627eca44e62e2b665eeec57a984a7f00 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 -https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.2-h19cb2f5_0.conda#ed6f7b7a35f942a0301e581d72616f7d +https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.3-h19cb2f5_0.conda#212ddd7bd52988f751905114325b5c0b https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.5-hcc62823_0.conda#1d6e71b8c73711e28ffe207acdc4e2f8 https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda#66a0dc7464927d0853b590b6f53ba3ea https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda#210a85a1119f97ea7887188d176db135 -https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.2-h8616949_0.conda#48dda187f169f5a8f1e5e07701d5cdd9 -https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda#688a0c3d57fa118b9c97bf7e471ab46c +https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.4.1-ha1e9b39_0.conda#57cc1464d457d01ac78f5860b9ca1714 +https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda#becdfbfe7049fa248e52aa37a9df09e2 https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda#ec88ba8a245855935b871a7324373105 https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda#7bb6608cf1f83578587297a158a6630b https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda#30439ff30578e504ee5e0b390afc8c65 -https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.2-h0d3cbff_0.conda#2f82b78f43520355ae2d297fecde25fd +https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.3-h0d3cbff_0.conda#fbc27eb49069842d5335776d600856ff https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda#ced34dd9929f491ca6dab6a2927aff25 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda#47f1b8b4a76ebd0cd22bd7153e54a4dc @@ -30,24 +30,24 @@ https://conda.anaconda.org/conda-forge/osx-64/lerc-4.1.0-h35c7297_0.conda#d2fe7e https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda#63186ac7a8a24b3528b4b14f21c03f54 https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda#5a088b358e37ccb4f4e5c573ff37a9f9 -https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.56-he930e7c_0.conda#635ddc7697d405386dcb64d777c545b5 -https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.52.0-h77d7759_0.conda#d553eb96758e038b04027b30fe314b2d +https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.57-he930e7c_0.conda#42dab0e4f72a55f9bc3546deec60fe44 +https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.53.0-h8f8c405_0.conda#f2bb6692dfb33a1bbce746aa812a9a5b https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.2-h7a90416_0.conda#0c8bdbfd118f5963ab343846094932a3 https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda#afda563484aa0017278866707807a335 -https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda#30bb8d08b99b9a7600d39efb3559fff0 +https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda#5cf0ece4375c73d7a5765e83565a69c7 https://conda.anaconda.org/conda-forge/osx-64/qhull-2020.2-h3c5361c_5.conda#dd1ea9ff27c93db7c01a7b7656bd4ad4 https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda#eefd65452dfe7cce476a519bece46704 https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda#6e6efb7463f8cef69dbcb4c2205bf60e https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.3-h8bce59a_1.conda#b3ecb6480fd46194e3f7dd0ff4445dff https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf -https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.2-h894318c_0.conda#e77ab67215939f46bb6ec8226a242e6a +https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.3-h894318c_0.conda#070e696856881a647e57267344e6b478 https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.3-h58fbd8d_0.conda#27515b8ab8bf4abd8d3d90cf11212411 https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda#9a5cb96e43f5c2296690186e15b3296f https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.2-hd552753_0.conda#eea3155f3b4a3b75af504c871ec23858 -https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda#030ec23658b941438ac42303aff0db2b +https://conda.anaconda.org/conda-forge/osx-64/python-3.14.4-h7c6738f_100_cp314.conda#d4e8506d0ac094be21451682eed9ce4d https://conda.anaconda.org/conda-forge/osx-64/brotli-1.2.0-hf139dec_1.conda#149d8ee7d6541a02a6117d8814fd9413 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -87,7 +87,7 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.13.0-h06b67a2_5.conda#f3e5cd2b56a3c866214b1d2529a54730 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/osx-64/mkl-2023.2.0-h694c41f_50502.conda#0bdfc939c8542e0bc6041cbd9a900219 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-20_osx64_mkl.conda#160fdc97a51d66d51dc782fb67d35205 https://conda.anaconda.org/conda-forge/osx-64/mkl-devel-2023.2.0-h694c41f_50502.conda#045f993e4434eaa02518d780fdca34ae https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock index b86d543b12ba8..fe0ffe272276e 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock @@ -12,19 +12,19 @@ https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda#62 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda#f1182c91c0de31a7abd40cedf6a5ebef https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa -https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.2-h55c6f16_0.conda#4280e0a7fd613b271e022e60dea0138c +https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.3-h55c6f16_0.conda#acbb3f547c4aae16b19e417db0c6e5ed https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.5-hf6b4638_0.conda#a32123f93e168eaa4080d87b0fb5da8a https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda#43c04d9cb46ef176bb2a4c77e324d599 https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda#4d5a7445f0b25b6a3ddbb56e790f5251 -https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda#f0695fbecf1006f27f4395d64bd0c4b8 -https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda#009f0d956d7bfb00de86901d16e486c7 +https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.4.1-h84a0fba_0.conda#b8a7544c83a67258b0e8592ec6a5d322 +https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda#b1fd823b5ae54fbec272cea0811bd8a9 https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda#57c4be259f5e0b99a5983799a228ae55 https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda#c0d87c3c8e075daf1daf6c31b53e8083 https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda#e5e7d467f80da752be17796b87fe6385 https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda#bc5a5721b6439f2f62a84f2548136082 -https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.2-hc7d1edf_0.conda#9c162044093d8d689836dafe3c27fe06 +https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.3-hc7d1edf_0.conda#086b00b77f5f0f7ef5c2a99855650df4 https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda#068d497125e4bf8a66bf707254fff5ae https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda#415816daf82e0b23a736a069a75e9da7 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda#78b548eed8227a689f93775d5d23ae09 @@ -40,22 +40,22 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.c https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda#58b2c5aee0ad58549bf92baead9baead -https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.56-h132b30e_0.conda#ce25ae471d213f9dd5edb0fe8e0b102a -https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.52.0-h1ae2325_0.conda#f6233a3fddc35a2ec9f617f79d6f3d71 +https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.57-h132b30e_0.conda#1a28041d8d998688fd82e25b45582b21 +https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.0-h1b79a29_0.conda#8423c008105df35485e184066cad4566 https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.2-h5ef1a60_0.conda#b284e2b02d53ef7981613839fb86beee https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda#175809cc57b2c67f27a0f238bd7f069d -https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda#f4f6ad63f98f64191c3e77c5f5f29d76 +https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda#25dcccd4f80f1638428613e0d7c9b4e1 https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda#6483b1f59526e05d7d894e466b5b6924 https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda#f8381319127120ce51e081dce4865cf4 https://conda.anaconda.org/conda-forge/osx-arm64/sleef-3.9.0-hb028509_0.conda#68f833178f171cfffdd18854c0e9b7f9 -https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_1.conda#ddd7d9cd7e3c3f184867e92ed1c7d394 +https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_2.conda#555070ad1e18b72de36e9ee7ed3236b3 https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda#a9d86bc62f39b94c4661716624eb21b0 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.2-h8088a28_2.conda#f1c0bce276210bed45a04949cfe8dc20 https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.3-hed4e4f5_1.conda#d99c2a23a31b0172e90f456f580b695e https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c -https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.2-h414bf82_0.conda#baeca21071729b617b20b019f85beedf +https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.3-h414bf82_0.conda#a641199cf4a5a2a16367acd53dcb8532 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.3-hdfa99f5_0.conda#e98ba7b5f09a5f450eca083d5a1c4649 https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda#92df6107310b1fff92c4cc84f0de247b https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.33.5-h4a5acfd_0.conda#b839e3295b66434f20969c8b940f056a @@ -63,10 +63,10 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.con https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.2-h8d039ee_0.conda#e476ba84e57f2bd2004a27381812ad4e https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.2-h6bc93b0_0.conda#a47a14da2103c9c7a390f7c8bc8d7f9b -https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda#753c8d0447677acb7ddbcc6e03e82661 +https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.4-h4c637c5_100_cp314.conda#e1bc5a3015a4bbeb304706dba5a32b7f https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda#48ece20aa479be6ac9a284772827d00c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_101.conda#3bb89e4f795e5414addaa531d6b1500a +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py314hc6117b3_0.conda#1289de88f884ac89144949cb97ccabe7 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 @@ -122,7 +122,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.32-openmp_he657 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.19.0-py314h6cfcd04_0.conda#0c8942bc23758aaeafed2707902fc48e -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_he8a363d_4.conda#76c651b923e048f3f3e0ecb22c966f70 https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-6_h51639a9_openblas.conda#e551103471911260488a02155cef9c94 diff --git a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock index e512c064ff773..f16567821a235 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -14,20 +14,20 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda# https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 +https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda#05051be49267378d2fcd12931e319ac3 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 @@ -68,7 +68,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip contourpy @ https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl#sha256=85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 -# pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b +# pip pytest @ https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl#sha256=2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9 # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl#sha256=4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a # pip scipy @ https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 9d8ecb4f0c883..fe7fe73aa714c 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -30,16 +30,17 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.con https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda#4feebd0fbf61075a1a9c2e9b3936c257 https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda#574d88ce3348331e962cfa5ed451b247 https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda#5a86bf847b9b926f3a4f203339748d78 -https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.2-he30d5cf_0.conda#5109d7f837a3dfdf5c60f60e311b041f -https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.2-he30d5cf_0.conda#96944e3c92386a12755b94619bae0b35 +https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda#a85ba48648f6868016f2741fd9170250 +https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.conda#76298a9e6d71ee6e832a8d0d7373b261 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.56-h1abf092_0.conda#d5aff85583507906d19696d4961f4738 +https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.57-h1abf092_0.conda#41ba1a3e77b5aeb55bc2b9a206760f6a +https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.0-h022381a_0.conda#86db4036fd08bf34e991bf48a8af405d https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42-h1022ec0_0.conda#a0b5de740d01c390bdbb46d7503c9fab https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda#182afabe009dc78d8b73100255ee6868 -https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.1-h546c87b_1.conda#25f5885f11e8b1f075bccf4a2da91c60 +https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.2-h546c87b_0.conda#3b129669089e4d6a5c6871dbb4669b99 https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda#bb5a90c93e3bac3d5690acf76b4a6386 https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda#7fc6affb9b01e567d2ef1d05b84aa6ed https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libice-1.1.2-h86ecc28_0.conda#c8d8ec3e00cd0fd8a231789b91a7c5b7 @@ -69,14 +70,14 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.25.0-h4f8a99f_0.c https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda#2d1409c50882819cb1af2de82e2b7208 https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda#f731af71c723065d91b4c01bb822641b https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 -https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.2-h185addb_0.conda#728e129e280ddc3b4885fd3bc64a9f58 +https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.3-h185addb_0.conda#90fc92ca3f97be362ecf59413cef7ca2 https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda#d9ca108bd680ea86a963104b6b3e95ca https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda#a229e22d4d8814a07702b0919d8e6701 https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_1.conda#4ac4372fc4d7f20630a91314cdac8afd https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.32-pthreads_h9d3fd7e_0.conda#5d2ce5cf40443d055ec6d33840192265 -https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.52.0-h10b116e_0.conda#77891484f18eca74b8ad83694da9815e https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda#e3ec9079759d35b875097d6a9a69e744 +https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.15-h91f4b29_0_cpython.conda#bb09184ea3313703da05516cd730e8f8 https://conda.anaconda.org/conda-forge/linux-aarch64/qhull-2020.2-h70be974_5.conda#bb138086d938e2b64f5f364945793ebf https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-0.4.1-hca56bd8_2.conda#159ffec8f7fab775669a538f0b29373a https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-keysyms-0.4.1-h5c728e9_0.conda#57ca8564599ddf8b633c4ea6afee6f3a @@ -84,53 +85,59 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-renderutil-0.3.10- https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-wm-0.4.2-h5c728e9_0.conda#f14dcda6894722e421da2b7dcffb0b78 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libx11-1.8.13-h63a1b12_0.conda#22dd10425ef181e80e130db50675d615 https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-1.2.0-hd651790_1.conda#5c933384d588a06cd8dac78ca2864aab +https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-aarch64/cyrus-sasl-2.1.28-h6598af7_1.conda#f4fbf4001970e3e58984281a12c99969 +https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.4-py311hdc11669_0.conda#931a90956062cc7219c6bce6c6ccfe7f https://conda.anaconda.org/conda-forge/linux-aarch64/dbus-1.16.2-h70963c4_1.conda#a4b6b82427d15f0489cef0df2d82f926 +https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_0.conda#0fed1ff55f4938a65907f3ecf62609db https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.3-h8af1aa0_0.conda#f11edf8adf0d119148b97f745548390d +https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 +https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.5.0-py311h229e7f7_0.conda#aeade47300d466d9d6ba01daaca31a86 https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda#bb960f01525b5e001608afef9d47b79c https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-6_haddc8a3_openblas.conda#652bb20bb4618cacd11e17ae070f47ce https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h4f2b762_6.conda#67828c963b17db7dc989fe5d509ef04a https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda#19de96909ee1198e2853acd8aba89f6c +https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b +https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.32-pthreads_h3a8cbd8_0.conda#62e1383bcaf8f5244d2598bbda509e3b https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c -https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.15-h91f4b29_0_cpython.conda#bb09184ea3313703da05516cd730e8f8 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd +https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 +https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f +https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.5-py311hb9158a3_0.conda#8776b78b9f2532ef4f0e2acc8f03f755 +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d +https://conda.anaconda.org/conda-forge/linux-aarch64/unicodedata2-17.0.1-py311h19352d5_0.conda#22df73a2e312d88d56f6986e0a287edb https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-image-0.4.0-h5c728e9_2.conda#b82e5c78dbbfa931980e8bfe83bce913 https://conda.anaconda.org/conda-forge/linux-aarch64/xkeyboard-config-2.47-he30d5cf_0.conda#4ac707a4279972357712af099cd1ae50 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.7-he30d5cf_0.conda#fb42b683034619915863d68dd9df03a3 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5cf_0.conda#e8b4056544341daf1d415eaeae7a040c https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda#ae2c2dd0e2d38d249887727db2af960e https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad -https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-aarch64/cython-3.2.4-py311hdc11669_0.conda#931a90956062cc7219c6bce6c6ccfe7f -https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.5.0-py311h229e7f7_0.conda#aeade47300d466d9d6ba01daaca31a86 +https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.5-py311h2dad8b0_0.conda#d3bcad889948820993ded0b13c2ae906 +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab +https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.62.0-py311h164a683_0.conda#d3ef6350930100e30aaf0ecdf4e4dd3a +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-6_hd72aa62_openblas.conda#939e300b110db241a96a1bed438c315b https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda#0d00176464ebb25af83d40736a2cd3bb https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-6_h88aeb00_openblas.conda#e23a27b52fb320687239e2c5ae4d7540 https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm21-21.1.8-hfd2ba90_0.conda#de59c5148c2a8347c02e437e3ed242a0 -https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.2-hfd2ba90_0.conda#c1911bb134ed245ce090fdf23079a6f8 +https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.3-hfd2ba90_0.conda#c2e1304da2e44348df892c1425bf294d https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b -https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.10-h2fb54aa_1.conda#b761e5f1358577a16ca187c6116d9fcc -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.13-h2fb54aa_0.conda#67eea19865a3463f75ca0d3a1d096350 https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.2.0-py311h8e17b9e_0.conda#c2e33eff9ea2d1501b83d938d9d4334d -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd -https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 -https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 -https://conda.anaconda.org/conda-forge/linux-aarch64/tornado-6.5.5-py311hb9158a3_0.conda#8776b78b9f2532ef4f0e2acc8f03f755 -https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/linux-aarch64/unicodedata2-17.0.1-py311h19352d5_0.conda#22df73a2e312d88d56f6986e0a287edb +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 +https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 +https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-cursor-0.1.6-he30d5cf_0.conda#8b70063c86f7f9a0b045e78d2d9971f7 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcomposite-0.4.7-he30d5cf_0.conda#9c639c1abdbfe6759c5beb2c1db4bc13 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcursor-1.2.3-h86ecc28_0.conda#f2054759c2203d12d0007005e1f1296d @@ -138,31 +145,24 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdamage-1.1.6-h86ec https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda#eeee3bdb31c6acde2b81ad1b8c287087 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda#1f64c613f0b8d67e9fb0e165d898fb6b https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.7-he30d5cf_0.conda#b15ca02584678f38df6e114c32f93959 -https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.5-py311h2dad8b0_0.conda#d3bcad889948820993ded0b13c2ae906 -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.62.0-py311h164a683_0.conda#d3ef6350930100e30aaf0ecdf4e4dd3a -https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-13.2.1-h1134a53_0.conda#05d65a2cf410adc331c9ea61f59f1013 -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 +https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-14.1.0-h1134a53_0.conda#5461f9f6ba3c30ee46e014fc127c8ac0 https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_3.conda#4ba7653ca09e74e8968120c6aea4bfb1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.0-default_h94a09a5_0.conda#4e1023aa62d0919a4014954d57bcb786 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.3-default_h94a09a5_0.conda#7c7dc469f56ce1831736c2827bc52b8c https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-6_hb558247_openblas.conda#12da32239ec4cc63d4f94d83b8425947 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.3-h7d4fc67_0.conda#7eb18b198b1d35da9352062c69c4ee64 https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.341.0-h8b8848b_0.conda#06bb91a87fb97ea09398d2e121e00c39 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py311h669026d_0.conda#23c6d37dec83159283cfeee4fceebf84 -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 -https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-6_h9678261_openblas.conda#64fe76410feeef76a105b2343edc4af7 https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311h04741b4_4.conda#1eeea54b0c520a475db39f8c711de661 -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.11.0-pl5321h598db47_2.conda#811e17440391dbcbb67032931cd2e752 https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.1-py311h399493a_0.conda#be28b3d39c6942f89652b505e85ae3d6 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.306-openblas.conda#cc7cac46a53a5c76f20439cb298d10a2 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.11.0-py311hb02cd75_1.conda#da150e07831537629fb38495fefae7fb -https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.8-py311hfecb2dc_0.conda#3920b856b59a909812f1913b96adaad8 diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 536b0aea4e708..28f5111e2c434 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -12,7 +12,7 @@ https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.2-h4922eb0_0.conda#2a60ab96432bc74eedbcda8a528080a1 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.3-h4922eb0_0.conda#f7781cb22afa62ef27fd0b3300c53c86 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 @@ -33,21 +33,21 @@ https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a3 https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 -https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 +https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb03c661_3.conda#672fad24c7fedff73c684c3e9e9848b3 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 @@ -89,7 +89,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1.conda#f883d61afbc95c50f7b3f62546da4235 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda#d1db1b8be7c3a8983dcbbbfe4f0765de @@ -102,7 +102,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h8fd135c_2.conda#bbf65f7688512872f063810623b755dc https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 @@ -158,15 +158,15 @@ https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.2-hf7376ad_0.conda#7147b0792a803cd5b9929ce5d48f7818 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d -https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.4-pyhcf101f3_0.conda#82c1787f2a65c0155ef9652466ee98d6 +https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 @@ -193,11 +193,11 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.0-default_h99862b1_0.conda#d966a23335e090a5410cc4f0dec8d00a -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.3-default_h99862b1_0.conda#4642265acfa1ad8dfe96c89d8d7b38fe +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_0.conda#9b47a4cd3aabb73201a2b8ed9f127189 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 @@ -212,7 +212,7 @@ https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.con https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda#d53ffc0edc8eabf4253508008493c5bc https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.20.2-h2a5cb19_18.conda#7313674073496cec938f73b71163bc31 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-20_linux64_openblas.conda#9932a1d4e9ecf2d35fb19475446e361e diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 5b9e34e990976..3d319d24ec14b 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -17,15 +17,15 @@ https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 -https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 +https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 @@ -41,10 +41,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.cond https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e @@ -96,7 +96,7 @@ https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_h1ea3ea9_ope https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py311h8032f78_0.conda#138e5d98884407fcc8ccc6088574b1c7 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-openblas.conda#81122e5749efe4c34c07471ad866eab1 diff --git a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock index 523052fc68233..8c5fb4d778d4b 100644 --- a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock @@ -29,15 +29,15 @@ https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.5-hac47afa_0.conda#bf https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda#720b39f5ec0610457b725eb3f396219a https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda#b085746891cca3bd2704a450a7b4b5ce https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#64571d1dd6cdcfa25d0664a5950fdaa2 -https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda#56a686f92ac0273c0f6af58858a3f013 -https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda#ba0bfd4c3cf73f299ffe46ff0eaeb8e3 +https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.4.1-hfd05255_0.conda#25a127bad5470852b30b239f030ec95b +https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda#8f83619ab1588b98dd99c90b0bfc5c6d https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.32-pthreads_h877e47f_0.conda#cb7bb86e848c806cf3f0a182fcdf77da -https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda#8830689d537fda55f990620680934bb1 +https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.0-hf5d6505_0.conda#4152b5a8d2513fd7ae9fb9f221a5595d https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.341.0-h477610d_0.conda#804880b2674119b84277d6c16b01677d https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda#f9bbae5e2537e3b06e0f7310ba76c893 https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda#dbabbd6234dea34040e631f87676292f https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda#7ecb9f2f112c66f959d2bb7dbdb89b67 -https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda#eb585509b815415bc964b2c7e11c7eb3 +https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.2-hf411b9b_0.conda#05c7d624cff49dbd8db1ad5ba537a8a3 https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda#08c8fa3b419df480d985e304f7884d35 https://conda.anaconda.org/conda-forge/win-64/qhull-2020.2-hc790b64_5.conda#854fbdff64b572b5c0b470f334d34c11 https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda#0481bfd9814bf525bd4b3ee4b51494c4 @@ -47,7 +47,7 @@ https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-6_h0adab6e_openblas https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda#450e3ae947fc46b60f1d8f8f318b40d4 https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda#ccd93cfa8e54fd9df4e83dbe55ff6e8c https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda#2cf0cf76cc15d360dfa2f17fd6cf9772 -https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.56-h7351971_0.conda#bedc0fc6a8fb31b8013878ea20c76bae +https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.57-h7351971_0.conda#3e40866d979cf6faba7263de9c2b4b99 https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h3cfd58e_0.conda#f6dd496a1f2b66951110a3a0817f699b https://conda.anaconda.org/conda-forge/win-64/openblas-0.3.32-pthreads_h4a7f399_0.conda#d7b743c101c58cf009ec7a887e49489f https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda#77eaf2336f3ae749e712f63e36b0f0a1 @@ -64,7 +64,7 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.5.0-py311h275cad7_0.conda#e50d15677f2673c114f18d60c88d9196 https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-6_h2a8eebe_openblas.conda#56ab25cf3cbce9e3a809e3e89739b5a8 -https://conda.anaconda.org/conda-forge/win-64/libclang13-22.1.0-default_ha2db4b5_0.conda#7ad437870ea7d487e1b0e663503b6b1d +https://conda.anaconda.org/conda-forge/win-64/libclang13-22.1.3-default_ha2db4b5_0.conda#deb5befa374fcbc9ec2534c8467b0a6b https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_0.conda#f9975a0177ee6cdda10c86d1db1186b0 https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.4-h0c9aed9_1.conda#0329a7e92c8c8b61fcaaf7ad44642a96 https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-6_hd232482_openblas.conda#06d2ad5bf21e9b86c46783833b2e3c42 @@ -106,14 +106,14 @@ https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_0.conda#5 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/win-64/pillow-12.2.0-py311h17b8079_0.conda#80382ea49ddde54350b5ca5135be2838 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.1-py311h9c22a71_0.conda#24047b0ff1fa264427c456e4c7f68283 https://conda.anaconda.org/conda-forge/win-64/blas-2.306-openblas.conda#8fe2bc7bfe72359526e4e94b018853a3 https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda#52ea1beba35b69852d210242dd20f97d https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/win-64/harfbuzz-13.2.1-h5a1b470_0.conda#f6414f2f905326bcf0e7c87a04d175a2 +https://conda.anaconda.org/conda-forge/win-64/harfbuzz-14.1.0-h5a1b470_0.conda#d261a3229a9cdded071fa5049c327944 https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.0-pl5321hfcac499_3.conda#b53193a38f677045dae28f7039122035 https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.0-py311he824864_1.conda#19b367dda0ee6f48f67d0d72a3fd1a12 https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py311h1ea47a8_0.conda#64fe28aa2486e41918239d385336e88e diff --git a/build_tools/github/ubuntu_atlas_lock.txt b/build_tools/github/ubuntu_atlas_lock.txt index dacb78ac3024b..d4d097e2b51fa 100644 --- a/build_tools/github/ubuntu_atlas_lock.txt +++ b/build_tools/github/ubuntu_atlas_lock.txt @@ -29,7 +29,7 @@ pygments==2.20.0 # via pytest pyproject-metadata==0.11.0 # via meson-python -pytest==9.0.2 +pytest==9.0.3 # via # -r build_tools/github/ubuntu_atlas_requirements.txt # pytest-xdist From 026379933d32b9985ffe472e3d3816ead5a2e205 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 13 Apr 2026 04:14:34 -0400 Subject: [PATCH 347/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33730) Co-authored-by: Lock file bot <noreply@github.com> --- .../pylatest_pip_scipy_dev_linux-64_conda.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index c711085b975c3..9f4975fe2f105 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -14,20 +14,20 @@ https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda# https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda#c014ad06e60441661737121d3eae8a60 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 @@ -43,7 +43,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip meson @ https://files.pythonhosted.org/packages/0b/78/7d049e63e624d51d0065191dae101a1e36d5d3a2360633772d9ad8afb2d5/meson-1.10.2-py3-none-any.whl#sha256=5f84ef186e6e788d9154db63620fc61b3ece69f643b94b43c8b9203c43d89b36 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 -# pip platformdirs @ https://files.pythonhosted.org/packages/63/d7/97f7e3a6abb67d8080dd406fd4df842c2be0efaf712d1c899c32a075027c/platformdirs-4.9.4-py3-none-any.whl#sha256=68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868 +# pip platformdirs @ https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl#sha256=e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl#sha256=81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 # pip roman-numerals @ https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl#sha256=647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7 @@ -59,7 +59,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip urllib3 @ https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl#sha256=bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl#sha256=85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 -# pip pytest @ https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl#sha256=711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b +# pip pytest @ https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl#sha256=2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9 # pip python-dateutil @ https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl#sha256=a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 # pip requests @ https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl#sha256=4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a # pip meson-python @ https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl#sha256=67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298 From 3cd7d69ff4b4485e8d0eec10ab2184cef852eff2 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 13 Apr 2026 04:14:59 -0400 Subject: [PATCH 348/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33729) Co-authored-by: Lock file bot <noreply@github.com> --- .../pylatest_free_threaded_linux-64_conda.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index 7a8c7134f62bd..80bef3b3c1bfe 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -15,12 +15,12 @@ https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2f https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a @@ -28,13 +28,13 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-he1279bd_1_cp314t.conda#19b5d632d02f56f9f95ce07dc1e086b5 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-hf9ea5aa_0_cp314t.conda#f9c864fd19f2e57a6624520c63262a16 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.3-py314hd8ed1ab_1.conda#83eaa6b45bd9d99a26d673a4d50138b3 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_0.conda#de1699ede4f26f116d44653d95228453 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.conda#cc2fcbfdf0628b5ad05b319866187bbc https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 @@ -52,8 +52,8 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314hd4f4903_0.conda#ee2b2bb9e96a9cd64d68492842559adf https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 -https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.3-h92d6c8b_1.conda#817a41a5e7c547bda68fd981fb72b1ec +https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.4-h92d6c8b_0.conda#431c21b61666866b1b4cb3252974642c https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314h529d2a9_0.conda#c09dd94be0e88aca25c60fb53d5c8e45 https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.2-pyhd8ed1ab_0.conda#288250b7e539cddf52f39616deae278d From 2d0b9630590a2fd0a89d0a7779aa40b9c01b4c8a Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 13 Apr 2026 04:31:30 -0400 Subject: [PATCH 349/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33731) Co-authored-by: Lock file bot <noreply@github.com> Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> --- .github/workflows/cuda-ci.yml | 2 +- ...a_forge_cuda_array-api_linux-64_conda.lock | 112 +++++++++--------- 2 files changed, 56 insertions(+), 58 deletions(-) diff --git a/.github/workflows/cuda-ci.yml b/.github/workflows/cuda-ci.yml index 4602a67fdf45f..4404015e8e738 100644 --- a/.github/workflows/cuda-ci.yml +++ b/.github/workflows/cuda-ci.yml @@ -20,7 +20,7 @@ jobs: - name: Build wheels uses: pypa/cibuildwheel@298ed2fb2c105540f5ed055e8a6ad78d82dd3a7e # v3.3.1 env: - CIBW_BUILD: cp313-manylinux_x86_64 + CIBW_BUILD: cp314-manylinux_x86_64 CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28 CIBW_BUILD_VERBOSITY: 1 CIBW_ARCHS: x86_64 diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index d43e43312e5f2..b4859a901e859 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -11,7 +11,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.2 https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_10.conda#590b5a14299d67b9669fe5eb1fdd4d3b https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa -https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 +https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/noarch/cuda-cccl_linux-64-12.9.27-ha770c72_0.conda#87ff6381e33b76e5b9b179a2cdd005ec @@ -24,7 +24,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/noarch/libnvptxcompiler-dev_linux-64-12.9.86-ha770c72_2.conda#a66a909acf08924aced622903832a937 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.2-h4922eb0_0.conda#2a60ab96432bc74eedbcda8a528080a1 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.3-h4922eb0_0.conda#f7781cb22afa62ef27fd0b3300c53c86 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_linux-64-12.9.79-h3f2d84a_0.conda#86e40eb67d83f1a58bdafdd44e5a77c6 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -51,20 +51,20 @@ https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a3 https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 -https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda#8397539e3a0bbd1695584fb4f927485a -https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda#c7c83eecbb72d88b940c249af56c8b17 +https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 +https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb9d3cd8_0.conda#db63358239cbe1ff86242406d440e44a https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda#97169784f0775c85683c3d8badcea2c3 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 -https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda#f61eb8cd60ff9057122a3d338b99c00f +https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 @@ -122,7 +122,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.cond https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-hc87160b_0.conda#dde6a3e4fe6bb2ecd2a7050dd1e701fb https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda#49346bc551d07c6940e811a1f93ba373 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_1.conda#55a83761db33f82d92d7d7a4a61662e5 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca @@ -137,8 +137,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 -https://conda.anaconda.org/rapidsai/linux-64/librmm-26.02.00-cuda12_260204_498dafcf.conda#057e94dab29e9c69b4542eb0c61b161e -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda#fd893f6a3002a635b5e50ceb9dd2c0f4 +https://conda.anaconda.org/rapidsai/linux-64/librmm-26.04.00-cuda12_260408_48b36cc6.conda#815e224bae37f1bf6491fe3145adbda2 +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 @@ -168,12 +168,12 @@ https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2.conda#bb6e31a0daa64ede76fe8d3fff01c06f https://conda.anaconda.org/conda-forge/linux-64/libcusparse-dev-12.5.10.65-hecca717_2.conda#db94469fbd554c107acc3afd0af5d8ec https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-26.02.00-cuda12_260204_c212ab9b.conda#702a98df50c3b8be134516647a217fde +https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-26.04.00-cuda12_260408_b01e3028.conda#4c79a5c4309aa770d00749683f941c70 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df -https://conda.anaconda.org/conda-forge/linux-64/python-3.13.12-hc97d973_100_cp313.conda#4c875ed0e78c2d407ec55eadffb8cf3d +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c https://conda.anaconda.org/conda-forge/linux-64/ucx-1.20.0-hbe80e26_1.conda#ffdaec09a7c09710040eb9e613f8c531 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 @@ -186,35 +186,34 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-he9ea9c5_1.con https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.13.12-py313hd8ed1ab_100.conda#9a4b8a37303b933b847c14a310f0557b -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.1-pyhc364b38_0.conda#aff29594e5d127a4b35aeef4b5f330cc +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.2-pyhc364b38_0.conda#63c7ba46fbfc291fab512005c1753041 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py313hc80a56d_0.conda#4a08e7dd57fdc0a13dc699c4c6d76c3a +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py313hc8edb43_0.conda#b81883b9dbf5069821c2fb09a8ba1407 +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-dev-11.7.5.82-h676940d_2.conda#0fe12e558abf507458bcec839e29778d https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.2-hf7376ad_0.conda#7147b0792a803cd5b9929ce5d48f7818 -https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.48.00-cuda12_260204_bb8b93e1.conda#acc1cf020a408d352f562c8e5e719834 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 +https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.49.00-cuda12_260408_8d47a9ff.conda#b8ddfc6e13aa7b755392fe8cb6f9250a https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 -https://conda.anaconda.org/conda-forge/linux-64/llvmlite-0.44.0-py313hfdae721_2.conda#dd0d7947635c0c524608eab7db55dcc9 -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py313h3dea7bd_1.conda#aeb9b9da79fd0258b3db091d1fefcd71 +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.595.45-pyhd8ed1ab_0.conda#bbb874843e7cc9cfe379d59499155e45 -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.10-hbde042b_1.conda#3c40a106eadf7c14c6236ceddb267893 +https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.595.45-pyhd8ed1ab_1.conda#dc8587ae654e96031728802016e8258c +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py313h80991f8_0.conda#7245f1bbf52ed5e3818d742f51b44a7d +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 @@ -226,8 +225,9 @@ https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339 https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py313h07c4f96_0.conda#6c0b0ae017b5bfd9c8d718217efd8f14 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py314h5bd0f2a_0.conda#dc1ff1e915ab35a06b6fa61efae73ab5 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d +https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py314h5bd0f2a_0.conda#494fdf358c152f9fdd0673c128c2f3dd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b @@ -238,25 +238,25 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h6d69fc9_5.conda#4c5c16bf1133dcfe100f33dd4470998e https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py313h3dea7bd_0.conda#acbda45380f5097ade59014704eb0ba0 -https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.6-py313h929d4db_0.conda#602176b8957b10172dfea675a332d0ac +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e +https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.6-py314h7ea930b_0.conda#a8841fd311da95db72916f58eff3f5a6 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py313h3dea7bd_0.conda#e479cfdec38fb69dc81ce8806b5c75f6 -https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py313h86d8783_1.conda#047e3ea395eab013f918b338fecc19a0 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda#14470902326beee192e33719a2e8bb7f +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 +https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.0-default_h746c552_0.conda#140459a7413d8f6884eb68205ce39a0d +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_0.conda#9b47a4cd3aabb73201a2b8ed9f127189 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.13.12-h4df99d1_100.conda#3d92938d5b83c49162ade038aab58a59 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 -https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py313h246eb7c_1.conda#8526afdb4ae2d95db733c4188f092f01 +https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py314h2b49ec1_1.conda#090f5ddba9c3c2e167619c801c212fb6 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f @@ -266,8 +266,8 @@ https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.co https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b -https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py313h7037e92_0.conda#21f1c403983c8a4e067ba6eec6b878ec -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.2-pyhcf101f3_0.conda#2b694bad8a50dc2f712f5368de866480 +https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_2.conda#c6ba2de6b22dedf2f20eba3bde1dbe8e https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf @@ -276,7 +276,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.co https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py313hcd51b16_1.conda#aafbb057823020eda1e5db662bc354a9 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_1.conda#5abdb958cf8cc0b43cf078d0559f7969 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 @@ -287,35 +287,33 @@ https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_9_cpu.conda#2dccf1b6cf9dba8857050740dbc0497e -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.2.6-py313h17eae1a_0.conda#7a2d2f9adecd86ed5c29c2115354f615 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py313hc8edb43_4.conda#33639459bc29437315d4bff9ed5bc7a7 -https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.6.0-cuda12_py313hacc9b55_0.conda#1986c17fb0b8184289ea7d6fc8ba4b34 -https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py313h28b6081_0.conda#fe933a91c19fa88788b4204b6ba67ba2 +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 +https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.7.0-cuda12_py314h6985919_0.conda#ec0ac10cf8ea10e2ca9437a1feebbfc6 +https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py314hf9e62a7_0.conda#4fe7bd0212d2f7788765875755f67684 https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_mkl_hd6d2a1f_303.conda#5b8a8672aca66f3871aab4d0d1a8f796 -https://conda.anaconda.org/conda-forge/linux-64/numba-0.61.2-py313hd8e3f9f_2.conda#84cef0ce56c6db53edb3f8b83bdbb364 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py313hbfd7664_0.conda#6a036e42f4e47720804f35d1897336a1 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py313h98bfbea_0_cpu.conda#d2b771a9050c52941a61a72f2d161c64 -https://conda.anaconda.org/rapidsai/linux-64/rmm-26.02.00-cuda12_py313_260204_498dafcf.conda#4eed5d6fe2014c9a6448195b3a099e3f -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py313h4b8bb8b_2.conda#0be9bd58abfb3e8f97260bd0176d5331 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py314hb4ffadd_0.conda#41ee6fe2a848876bc9f524c5a500b85b +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py314h969be7f_0_cpu.conda#97c21b0d5952f4e0f80bb790df1a5c88 +https://conda.anaconda.org/rapidsai/linux-64/rmm-26.04.00-cuda12_cp311_abi3_260408_48b36cc6.conda#347f02e4a94831af80076fd6157776ac +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py314hf07bd8e_2.conda#ee95e8bb52e35c3267a53d3ee1347cc4 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 -https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py313h7fc6698_0.conda#41368ea5c4c7c607ac98ecab56833535 +https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py314h3d8d815_0.conda#5045e5051a4d781d41d63e4acc264944 https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_9_cpu.conda#9c5282b7aaf2261d3dbe5a61d24d5337 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py313h683a580_0.conda#ffe67570e1a9192d2f4c189b27f75f89 -https://conda.anaconda.org/conda-forge/linux-64/numba-cuda-0.22.2-py313h92f78c6_0.conda#ffb99b9ade039e075e74b92ecd8810f1 -https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py313hfaae9d9_1.conda#6d308eafec3de495f6b06ebe69c990ed -https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_mkl_py313_h623d66f_303.conda#14135d5ee1f06598b4714f2fce2af13c +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f +https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 +https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_mkl_py314_h624cae8_303.conda#fa04d9a4d7fd7a9bd49deabc4b1a8b4f +https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.49.00-cuda12_cp311_abi3_260408_8d47a9ff.conda#4e44176d2cfc7f9941dc3089df22c9dc https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_9_cpu.conda#d5338f154126253750e8ccc539386b92 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py313h78bf25f_0.conda#85bce686dd57910d533807562204e16b +https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.04.00-cuda12_260408_b01e3028.conda#413e57142e096269834e8a95b4905d09 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_mkl_h0d04637_303.conda#1050dc8cf80cd0a9e63f361c12ee0e82 -https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.48.00-cuda12_py313_260204_bb8b93e1.conda#b44f42d5b787c2787a167222313a2709 -https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.02.00-cuda12_260204_c212ab9b.conda#ab3f7484c3822755fed66f8c061dc599 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py313h78bf25f_0.conda#bd299f66ab2d10d1e03d4148397fe263 -https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.02.00-cuda12_260204_a2f5a8b7.conda#3f6fd0e2cfd7aafc18bbd88027c1d3be -https://conda.anaconda.org/rapidsai/linux-64/libraft-26.02.00-cuda12_260204_c212ab9b.conda#29ca3d988da2975aa443a3dcf5602aea -https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.02.00-cuda12_260204_a2f5a8b7.conda#361cae27e77618c6ba9f943807471f9f -https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.02.00-cuda12_py313_260204_c212ab9b.conda#14933b753ec82f9d5a61d7cb4b5e2e71 -https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.02.00-cuda12_py313_260204_a2f5a8b7.conda#c46807878ad576379e7be3acc187d13a +https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.04.00-cuda12_260408_60b19a0f.conda#c3216f4b246d2016b1f1a9d719dc94ad +https://conda.anaconda.org/rapidsai/linux-64/libraft-26.04.00-cuda12_260408_b01e3028.conda#04014b08138ccd053a8352d879f1cb1e +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py314hdafbbf9_0.conda#860f29e99f5b5f15b0d6a21166588bab +https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.04.00-cuda12_260408_60b19a0f.conda#2b9d59fc5a9ee033d42f68ef6cd451aa +https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.04.00-cuda12_cp311_abi3_260408_b01e3028.conda#45e40019a250657411b7b42182c33dfd +https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.04.00-cuda12_cp311_abi3_260408_.conda#a1a9e67d1b2f9134c41cb4a4063c7497 From e37e89f3518f26b05dfa5c05931a788176060fc1 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Mon, 13 Apr 2026 14:07:22 +0200 Subject: [PATCH 350/462] DOC fix link to plot_partial_dependence_visualization_api example (#33736) --- doc/visualizations.rst | 2 +- sklearn/inspection/_plot/partial_dependence.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/visualizations.rst b/doc/visualizations.rst index e9d38f25e1e0d..a7a4d85fd5ac4 100644 --- a/doc/visualizations.rst +++ b/doc/visualizations.rst @@ -111,8 +111,8 @@ values of the curves. .. rubric:: Examples +* :ref:`sphx_glr_auto_examples_inspection_plot_partial_dependence_visualization_api.py` * :ref:`sphx_glr_auto_examples_miscellaneous_plot_roc_curve_visualization_api.py` -* :ref:`sphx_glr_auto_examples_miscellaneous_plot_partial_dependence_visualization_api.py` * :ref:`sphx_glr_auto_examples_miscellaneous_plot_display_object_visualization.py` * :ref:`sphx_glr_auto_examples_calibration_plot_compare_calibration.py` diff --git a/sklearn/inspection/_plot/partial_dependence.py b/sklearn/inspection/_plot/partial_dependence.py index a4104197e6b7a..958f988ff98ac 100644 --- a/sklearn/inspection/_plot/partial_dependence.py +++ b/sklearn/inspection/_plot/partial_dependence.py @@ -33,7 +33,7 @@ class PartialDependenceDisplay: :ref:`Inspection Guide <partial_dependence>`. For an example on how to use this class, see the following example: - :ref:`sphx_glr_auto_examples_miscellaneous_plot_partial_dependence_visualization_api.py`. + :ref:`sphx_glr_auto_examples_inspection_plot_partial_dependence_visualization_api.py`. .. versionadded:: 0.22 From 99e9e9a1e77b98e77a5c46bd1c85790a71f0dc60 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Mon, 13 Apr 2026 16:46:14 +0200 Subject: [PATCH 351/462] MNT add GitHub Action to add and remove no-contribution warning (#33521) Co-authored-by: Tim Head <betatim@gmail.com> --- .../scripts/add_or_remove_no_pr_warning.py | 50 ++++++++++++++++ .../workflows/not-ready-for-pr-warning.yml | 57 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 .github/scripts/add_or_remove_no_pr_warning.py create mode 100644 .github/workflows/not-ready-for-pr-warning.yml diff --git a/.github/scripts/add_or_remove_no_pr_warning.py b/.github/scripts/add_or_remove_no_pr_warning.py new file mode 100644 index 0000000000000..a32a9e551d9b9 --- /dev/null +++ b/.github/scripts/add_or_remove_no_pr_warning.py @@ -0,0 +1,50 @@ +# Used in Github Action .github/workflows/not_ready_for_pr_warning.yml +import argparse +import os + +from github import Auth, Github + +parser = argparse.ArgumentParser( + description="Add or remove no-contribution warning from issue body" +) +parser.add_argument( + "--mode", choices=["add", "remove"], help="Whether to add or remove warning" +) +args = parser.parse_args() + +# env variables are defined in .github/workflows/not_ready_for_pr_warning.yml +g = Github(auth=Auth.Token(os.environ["GITHUB_TOKEN"])) +repo = g.get_repo(os.environ["GITHUB_REPO"]) +issue = repo.get_issue(number=int(os.environ["ISSUE_NUMBER"])) + +body_text = str(issue.body) if issue.body else "" + +message = ( + "> [!WARNING]\n" + "> This issue is not yet ready for a PR. If you are interested in contributing to " + "scikit-learn, please have a look at our [contributing guidelines]" + "(https://scikit-learn.org/dev/developers/contributing.html), and in particular " + "the sections for [new contributors]" + "(https://scikit-learn.org/dev/developers/contributing.html#new-contributors) and " + 'the ["Needs triage"](https://scikit-learn.org/dev/developers/contributing.html#' + "issues-tagged-needs-triage) label." +) + +if args.mode == "add": + if not body_text.startswith(message): + new_body = f"{message}\n\n{body_text}" + issue.edit(body=new_body) + print(f"Added warning to issue: {os.environ['GITHUB_REPO']}#{issue.number}") + +else: + still_needs_something = any( + label.name.startswith("Needs") or label.name == "RFC" for label in issue.labels + ) + if not still_needs_something: + if body_text.startswith(message): + new_body = body_text.removeprefix(f"{message}\n\n") + issue.edit(body=new_body) + print( + "Removed warning from issue: " + f"{os.environ['GITHUB_REPO']}#{issue.number}" + ) diff --git a/.github/workflows/not-ready-for-pr-warning.yml b/.github/workflows/not-ready-for-pr-warning.yml new file mode 100644 index 0000000000000..e8ad48949ee8d --- /dev/null +++ b/.github/workflows/not-ready-for-pr-warning.yml @@ -0,0 +1,57 @@ +# Add a warning to the issue description when the issue is labeled "Needs ..." +# and doesn't have a warning yet, and remove it again when all such labels are removed. +name: "Add or remove not-ready-for-PR warning" + +permissions: + contents: read + issues: write + +on: + issues: + types: [opened, labeled, unlabeled] + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_REPO: ${{ github.repository }} + ISSUE_NUMBER: ${{ github.event.issue.number }} + +jobs: + + add_not_ready_for_PR_warning: + runs-on: ubuntu-latest + if: github.event.action == 'opened' || (github.event.action == 'labeled' && + (startsWith(github.event.label.name, 'Needs') || github.event.label.name == 'RFC')) + steps: + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.13' + - name: Install PyGithub + run: pip install -Uq PyGithub + - name: Checkout workflow script + uses: actions/checkout@v6 + with: + sparse-checkout: .github/scripts/add_or_remove_no_pr_warning.py + sparse-checkout-cone-mode: false # false for files/ true for directories + - name: Add not-ready-for-PR warning + run: python .github/scripts/add_or_remove_no_pr_warning.py --mode="add" + + remove_not_ready_for_PR_warning: + runs-on: ubuntu-latest + if: github.event.action == 'unlabeled' && + (startsWith(github.event.label.name, 'Needs') || + github.event.label.name == 'RFC') + steps: + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.13' + - name: Install PyGithub + run: pip install -Uq PyGithub + - name: Checkout workflow script + uses: actions/checkout@v6 + with: + sparse-checkout: .github/scripts/add_or_remove_no_pr_warning.py + sparse-checkout-cone-mode: false # false for files/ true for directories + - name: Remove not-ready-for-PR warning + run: python .github/scripts/add_or_remove_no_pr_warning.py --mode="remove" From 45bad763f8a99404a99f1c0168b30e07e297a7ad Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Mon, 13 Apr 2026 18:56:22 +0200 Subject: [PATCH 352/462] FIX Add class-specific contour lines in `DecisionBoundaryDisplay` for `predict_proba` and `decision_function` (#33471) --- .../sklearn.inspection/33471.fix.rst | 5 + sklearn/inspection/_plot/decision_boundary.py | 95 ++++++++++++------- .../tests/test_boundary_decision_display.py | 93 ++++++++++++++++-- 3 files changed, 153 insertions(+), 40 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.inspection/33471.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/33471.fix.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/33471.fix.rst new file mode 100644 index 0000000000000..585a4ee4e4197 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.inspection/33471.fix.rst @@ -0,0 +1,5 @@ +- For multiclass data, :class:`inspection.DecisionBoundaryDisplay` with + ``plot_method="contour"`` now also displays class-specific contours for + ``response_method="predict_proba"`` and ``response_method="decision_function"``. + Multiclass class boundary contour lines are now displayed in black by default for all + response methods to avoid confusion. By :user:`Anne Beyer <AnneBeyer>`. diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index bcbf72a16dd35..20adb4d16332a 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -181,12 +181,20 @@ class DecisionBoundaryDisplay: the list or colors taken from the colormap, and passed to the `cmap` parameter of the `plot_method`. - For :term:`binary` problems, this is ignored and `cmap` or `colors` can be - passed as kwargs instead, otherwise, the default colormap ('viridis') is used. + When `response_method='predict'` and `plot_method='contour'`, + `multiclass_colors` is ignored and the class boundaries are plotted in black + instead as the boundary lines may overlap and the colors don't necessarily + correspond to the classes. + + For :term:`binary` problems, `multiclass_colors` is also ignored and `cmap` or + `colors` can be passed as kwargs instead, otherwise, the default colormap + ('viridis') is used. .. versionadded:: 1.7 .. versionchanged:: 1.9 - `multiclass_colors` is now also used when `response_method="predict"` + `multiclass_colors` is now also used when `response_method="predict"`, + except for when `plot_method='contour'`, where it is ignored and "black" is + used instead. xlabel : str, default=None Default label to place on x axis. @@ -294,7 +302,10 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar **kwargs : dict Additional keyword arguments to be passed to the `plot_method`. For :term:`binary` problems, `cmap` or `colors` can be set here to specify the - colormap or colors, otherwise the default colormap ('viridis') is used. + colormap or colors, otherwise the default colormap ('viridis') is used. If + not specified by the user, `zorder` is set to -1 to ensure that the decision + boundary is plotted in the background (in case a scatter plot is added on + top). Returns ------- @@ -330,33 +341,13 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar mpl, self.multiclass_colors, self.n_classes ) - if self.response.ndim == 2: # predict - # Set `levels` to ensure all classes are displayed in different colors - if "levels" not in kwargs: - if plot_method == "contour": - kwargs["levels"] = np.arange(self.n_classes) - elif plot_method == "contourf": - kwargs["levels"] = np.arange(self.n_classes + 1) - 0.5 - # `pcolormesh` requires cmap, for the others it makes no difference - cmap = mpl.colors.ListedColormap(self.multiclass_colors_) - self.surface_ = plot_func( - self.xx0, self.xx1, self.response, cmap=cmap, **kwargs - ) + # If not set by the user, set default values for `zorder` to ensure that the + # decision boundary is plotted in the background (in case a scatter plot is + # added on top) + if "zorder" not in kwargs: + kwargs["zorder"] = -1 - # predict_proba and decision_function differ for plotting methods - elif plot_method == "contour": - # Set `levels` to ensure all classes are displayed in different colors - if "levels" not in kwargs: - kwargs["levels"] = np.arange(self.n_classes) - # Plot only integer class values - self.surface_ = plot_func( - self.xx0, - self.xx1, - self.response.argmax(axis=2), - colors=self.multiclass_colors_, - **kwargs, - ) - else: + if self.response.ndim == 3: # predict_proba and decision_function multiclass_cmaps = [ mpl.colors.LinearSegmentedColormap.from_list( f"colormap_{class_idx}", @@ -374,6 +365,39 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar plot_func(self.xx0, self.xx1, response, cmap=cmap, **kwargs) ) + if plot_method == "contour": + # Additionally plot the decision boundaries between classes. + self.surface_.append( + plot_func( + self.xx0, + self.xx1, + self.response.argmax(axis=2), + colors="black", + zorder=-1, + # set levels to ensure all boundaries are plotted correctly + levels=np.arange(self.n_classes), + ) + ) + + elif self.response.ndim == 2: # predict + # Set `levels` to ensure all class boundaries are displayed. + if "levels" not in kwargs: + if plot_method == "contour": + kwargs["levels"] = np.arange(self.n_classes) + elif plot_method == "contourf": + kwargs["levels"] = np.arange(self.n_classes + 1) - 0.5 + + if plot_method == "contour": + self.surface_ = plot_func( + self.xx0, self.xx1, self.response, colors="black", **kwargs + ) + else: + # `pcolormesh` requires cmap, for `contourf` it makes no difference + cmap = mpl.colors.ListedColormap(self.multiclass_colors_) + self.surface_ = plot_func( + self.xx0, self.xx1, self.response, cmap=cmap, **kwargs + ) + if xlabel is not None or not ax.get_xlabel(): xlabel = self.xlabel if xlabel is None else xlabel ax.set_xlabel(xlabel) @@ -469,9 +493,14 @@ def from_estimator( in the list or colors taken from the colormap, and passed to the `cmap` parameter of the `plot_method`. - For :term:`binary` problems, this is ignored and `cmap` or `colors` can be - passed as kwargs instead, otherwise, the default colormap ('viridis') is - used. + When `response_method='predict'` and `plot_method='contour'`, + `multiclass_colors` is ignored and the class boundaries are plotted in black + instead as the boundary lines may overlap and the colors don't necessarily + correspond to the classes. + + For :term:`binary` problems, `multiclass_colors` is also ignored and `cmap` + or `colors` can be passed as kwargs instead, otherwise, the default colormap + ('viridis') is used. .. versionadded:: 1.7 .. versionchanged:: 1.9 diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index 1039d5eca1cdd..ac127106a2625 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -688,9 +688,17 @@ def test_multiclass_colors_cmap( assert disp.n_classes == len(np.unique(colors, axis=0)) if response_method == "predict": - cmap = mpl.colors.ListedColormap(colors) - assert disp.surface_.cmap == cmap - elif plot_method != "contour": + if plot_method == "contour": + assert disp.surface_.colors == "black" + else: + cmap = mpl.colors.ListedColormap(colors) + assert disp.surface_.cmap == cmap + + else: + if plot_method == "contour": + # the last display additionally contains the class boundary contours + assert disp.surface_[-1].colors == "black" + del disp.surface_[-1] cmaps = [ mpl.colors.LinearSegmentedColormap.from_list( f"colormap_{class_idx}", [(1.0, 1.0, 1.0, 1.0), (r, g, b, 1.0)] @@ -702,8 +710,6 @@ def test_multiclass_colors_cmap( for idx, quad in enumerate(disp.surface_): assert quad.cmap == cmaps[idx] - else: - assert_allclose(disp.surface_.colors, colors) def test_multiclass_not_enough_colors_error(pyplot): @@ -748,8 +754,12 @@ def test_multiclass_not_enough_colors_error(pyplot): ], ) def test_multiclass_levels(pyplot, y, response_method, plot_method): - # non-regression test for issue #32866 + """ + Test that `levels` are set such that all classes and class boundaries are displayed. + This is only relevant for "contour" and "predict" with "contourf". + Non-regression test for issue #32866. + """ X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1], [2, 2], [3, 2]]) clf = LogisticRegression().fit(X, y) @@ -759,6 +769,7 @@ def test_multiclass_levels(pyplot, y, response_method, plot_method): X, response_method=response_method, plot_method=plot_method, + multiclass_colors="gist_rainbow", ) if plot_method == "contour": @@ -766,7 +777,75 @@ def test_multiclass_levels(pyplot, y, response_method, plot_method): else: expected_levels = np.arange(7) - 0.5 - assert_allclose(disp.surface_.levels, expected_levels) + if isinstance(disp.surface_, list): + # This is the case for "decision_function" and "predict_proba" with "contour", + # which have a separate surface for each class contour and contain the decision + # boundary contour (which requires the correct levels) on the last surface. + levels = disp.surface_[-1].levels + else: + levels = disp.surface_.levels + + assert_allclose(levels, expected_levels) + + # Check that all expected colors are visible for contourf: + if plot_method == "contourf": + expected_colors = pyplot.get_cmap("gist_rainbow")(np.linspace(0, 1, 6)) + # TODO: Remove version check and the else branch once 3.10 is the minimal + # supported matplotlib version. + import matplotlib as mpl + + # disp.surface_ is QuadContourSet. In matplotlib 3.10.0, the API for + # QuadContourSet was changed to produce only one collection per plot and + # `.collections` was deprecated, whereas before, a collection was created for + # each level separately. + if parse_version(mpl.__version__) >= parse_version("3.10.0"): + surface_colors = disp.surface_.get_facecolor() + else: + surface_colors = [ + collection.get_facecolor()[0] + for collection in disp.surface_.collections + ] + assert_allclose(expected_colors, surface_colors) + + +@pytest.mark.parametrize( + "response_method", ["decision_function", "predict_proba", "predict"] +) +@pytest.mark.parametrize("plot_method", ["contourf", "contour", "pcolormesh"]) +def test_zorder(pyplot, response_method, plot_method): + """Check that decision boundaries are plotted in the background.""" + X = np.array([[-1, -1], [-2, -1], [1, 1], [2, 1], [2, 2], [3, 2]]) + y = np.arange(6) + clf = LogisticRegression().fit(X, y) + disp = DecisionBoundaryDisplay.from_estimator( + clf, X, response_method=response_method, plot_method=plot_method + ) + # TODO: Remove version check and the else branch once 3.10 is the minimal + # supported matplotlib version. + import matplotlib as mpl + + # disp.surface_ is QuadContourSet or QuadMesh (for "pcolormesh"). In matplotlib + # 3.10.0, the API for QuadContourSet was changed to produce only one collection + # per plot (as it was and is the case for QuadMesh) and `.collections` was + # deprecated, whereas before, a collection was created for each level + # separately. + if ( + parse_version(mpl.__version__) >= parse_version("3.10.0") + or plot_method == "pcolormesh" + ): + if isinstance(disp.surface_, list): + for surface in disp.surface_: + assert surface.get_zorder() == -1 + else: + assert disp.surface_.get_zorder() == -1 + else: + if isinstance(disp.surface_, list): + for surface in disp.surface_: + for collection in surface.collections: + assert collection.get_zorder() == -1 + else: + for collection in disp.surface_.collections: + assert collection.get_zorder() == -1 # estimator classes for non-regression test cases for issue #33194 From b674d83af6280151e3d2e0674cc6b1cce6075dc2 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Tue, 14 Apr 2026 10:08:18 +0200 Subject: [PATCH 353/462] ENH add sparse and sample_weight support to MultiTaskElasticNet (#33440) --- .../sklearn.linear_model/33440.feature.rst | 5 + sklearn/linear_model/_cd_fast.pyx | 363 +++++++++++++++--- sklearn/linear_model/_coordinate_descent.py | 273 ++++++------- .../tests/test_coordinate_descent.py | 297 +++++++------- 4 files changed, 593 insertions(+), 345 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33440.feature.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33440.feature.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33440.feature.rst new file mode 100644 index 0000000000000..c39e018db60b6 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33440.feature.rst @@ -0,0 +1,5 @@ +- :class:`linear_model.MultiTaskElasticNet`, + :class:`linear_model.MultiTaskElasticNetCV`, + :class:`linear_model.MultiTaskLasso`, and :class:`linear_model.MultiTaskLassoCV` now + support fitting on sparse `X` as well as fitting with `sample_weight`. + By :user:`Christian Lorentzen <lorentzenchr>`. diff --git a/sklearn/linear_model/_cd_fast.pyx b/sklearn/linear_model/_cd_fast.pyx index 3eb260eb7e279..4a5bb1e62ece7 100644 --- a/sklearn/linear_model/_cd_fast.pyx +++ b/sklearn/linear_model/_cd_fast.pyx @@ -12,7 +12,7 @@ from sklearn.utils._cython_blas cimport ( _axpy, _dot, _asum, _gemv, _nrm2, _copy, _scal ) from sklearn.utils._cython_blas cimport ColMajor, Trans, NoTrans -from sklearn.utils._typedefs cimport uint8_t, uint32_t +from sklearn.utils._typedefs cimport int32_t, uint8_t, uint32_t from sklearn.utils._random cimport our_rand_r @@ -83,6 +83,43 @@ cdef inline floating diff_abs_max(int n, const floating* a, floating* b) noexcep return m +cdef inline floating sparse_dot( + int32_t j, + const floating[::1] X_data, # in + const int32_t[::1] X_indices, # in + const int32_t[::1] X_indptr, # in + const floating[::1] y, +) noexcept nogil: + """BLAS X[:, j] @ y for sparse CSC X.""" + cdef int32_t i, i_ind + cdef int32_t startptr = X_indptr[j] + cdef int32_t endptr = X_indptr[j + 1] + cdef floating result = 0 + + for i_ind in range(startptr, endptr): + i = X_indices[i_ind] + result += X_data[i_ind] * y[i] + return result + + +cdef inline floating sparse_axpy( + int32_t j, + floating a, + const floating[::1] X_data, # in + const int32_t[::1] X_indices, # in + const int32_t[::1] X_indptr, # in + floating[::1] y, # out +) noexcept nogil: + """BLAS y += a * X[:, j] for sparse CSC X.""" + cdef int32_t i, i_ind + cdef int32_t startptr = X_indptr[j] + cdef int32_t endptr = X_indptr[j + 1] + + for i_ind in range(startptr, endptr): + i = X_indices[i_ind] + y[i] += a * X_data[i_ind] + + message_conv = ( "Objective did not converge. You might want to increase " "the number of iterations, check the scale of the " @@ -473,8 +510,8 @@ cdef inline void R_plus_wj_Xj( unsigned int n_samples, floating[::1] R, # out const floating[::1] X_data, - const int[::1] X_indices, - const int[::1] X_indptr, + const int32_t[::1] X_indices, + const int32_t[::1] X_indptr, const floating[::1] X_mean, bint center, const floating[::1] sample_weight, @@ -483,20 +520,23 @@ cdef inline void R_plus_wj_Xj( unsigned int j, ) noexcept nogil: """R += w_j * X[:,j]""" - cdef unsigned int startptr = X_indptr[j] - cdef unsigned int endptr = X_indptr[j + 1] + cdef int32_t i, i_ind + cdef int32_t startptr = X_indptr[j] + cdef int32_t endptr = X_indptr[j + 1] cdef floating sw cdef floating X_mean_j = X_mean[j] if no_sample_weights: - for i in range(startptr, endptr): - R[X_indices[i]] += X_data[i] * w_j + for i_ind in range(startptr, endptr): + i = X_indices[i_ind] + R[i] += X_data[i_ind] * w_j if center: for i in range(n_samples): R[i] -= X_mean_j * w_j else: - for i in range(startptr, endptr): - sw = sample_weight[X_indices[i]] - R[X_indices[i]] += sw * X_data[i] * w_j + for i_ind in range(startptr, endptr): + i = X_indices[i_ind] + sw = sample_weight[i] + R[i] += sw * X_data[i_ind] * w_j if center: for i in range(n_samples): R[i] -= sample_weight[i] * X_mean_j * w_j @@ -509,8 +549,8 @@ cdef (floating, floating) gap_enet_sparse( floating alpha, # L1 penalty floating beta, # L2 penalty const floating[::1] X_data, - const int[::1] X_indices, - const int[::1] X_indptr, + const int32_t[::1] X_indices, + const int32_t[::1] X_indptr, const floating[::1] y, const floating[::1] sample_weight, bint no_sample_weights, @@ -533,7 +573,7 @@ cdef (floating, floating) gap_enet_sparse( cdef floating Ry cdef floating w_l1_norm cdef floating w_l2_norm2 = 0.0 - cdef unsigned int i, j + cdef int32_t i, i_ind, j # w_l2_norm2 = w @ w if beta > 0: @@ -557,8 +597,9 @@ cdef (floating, floating) gap_enet_sparse( # XtA = X.T @ R for j in range(n_features): XtA[j] = 0.0 - for i in range(X_indptr[j], X_indptr[j + 1]): - XtA[j] += X_data[i] * R[X_indices[i]] + for i_ind in range(X_indptr[j], X_indptr[j + 1]): + i = X_indices[i_ind] + XtA[j] += X_data[i_ind] * R[i] if center: XtA[j] -= X_mean[j] * R_sum @@ -580,8 +621,9 @@ cdef (floating, floating) gap_enet_sparse( # sparse X.T @ dense R for j in range(n_features): XtA[j] = 0.0 - for i in range(X_indptr[j], X_indptr[j + 1]): - XtA[j] += X_data[i] * R[X_indices[i]] + for i_ind in range(X_indptr[j], X_indptr[j + 1]): + i = X_indices[i_ind] + XtA[j] += X_data[i_ind] * R[i] if center: XtA[j] -= X_mean[j] * R_sum @@ -613,8 +655,8 @@ def sparse_enet_coordinate_descent( floating alpha, floating beta, const floating[::1] X_data, - const int[::1] X_indices, - const int[::1] X_indptr, + const int32_t[::1] X_indices, + const int32_t[::1] X_indptr, const floating[::1] y, const floating[::1] sample_weight, const floating[::1] X_mean, @@ -697,12 +739,12 @@ def sparse_enet_coordinate_descent( cdef uint32_t[::1] active_set # TODO: use binset insteaf of array of bools cdef uint8_t[::1] excluded_set - cdef unsigned int i + cdef int32_t i, i_ind cdef unsigned int j cdef unsigned int n_iter = 0 cdef unsigned int f_iter - cdef unsigned int startptr = X_indptr[0] - cdef unsigned int endptr + cdef int32_t startptr = X_indptr[0] + cdef int32_t endptr cdef uint32_t rand_r_state_seed = rng.randint(0, RAND_R_MAX) cdef uint32_t* rand_r_state = &rand_r_state_seed cdef bint center = False @@ -738,23 +780,25 @@ def sparse_enet_coordinate_descent( w_j = w[j] if no_sample_weights: - for i in range(startptr, endptr): - normalize_sum += (X_data[i] - X_mean_j) ** 2 - R[X_indices[i]] -= X_data[i] * w_j - norm2_cols_X[j] = normalize_sum + \ - (n_samples - endptr + startptr) * X_mean_j ** 2 + for i_ind in range(startptr, endptr): + i = X_indices[i_ind] + normalize_sum += (X_data[i_ind] - X_mean_j) ** 2 + R[i] -= X_data[i_ind] * w_j + norm2_cols_X[j] = normalize_sum if center: + norm2_cols_X[j] += (n_samples - endptr + startptr) * X_mean_j ** 2 for i in range(n_samples): R[i] += X_mean_j * w_j R_sum += R[i] else: # R = sw * (y - np.dot(X, w)) - for i in range(startptr, endptr): - tmp = sample_weight[X_indices[i]] + for i_ind in range(startptr, endptr): + i = X_indices[i_ind] + tmp = sample_weight[i] # second term will be subtracted by loop over range(n_samples) - normalize_sum += (tmp * (X_data[i] - X_mean_j) ** 2 + normalize_sum += (tmp * (X_data[i_ind] - X_mean_j) ** 2 - tmp * X_mean_j ** 2) - R[X_indices[i]] -= tmp * X_data[i] * w_j + R[i] -= tmp * X_data[i_ind] * w_j if center: for i in range(n_samples): normalize_sum += sample_weight[i] * X_mean_j ** 2 @@ -851,8 +895,9 @@ def sparse_enet_coordinate_descent( # tmp = X[:,j] @ (R + w_j * X[:,j]) tmp = 0.0 - for i in range(startptr, endptr): - tmp += R[X_indices[i]] * X_data[i] + for i_ind in range(startptr, endptr): + i = X_indices[i_ind] + tmp += R[i] * X_data[i_ind] tmp += w_j * norm2_cols_X[j] if center: @@ -1250,12 +1295,21 @@ cdef (floating, floating) gap_enet_multi_task( int n_samples, int n_features, int n_tasks, - const floating[::1, :] W, # in + const floating[::1, :] W, floating alpha, floating beta, - const floating[::1, :] X, # in - const floating[::1, :] Y, # in - const floating[::1, :] R, # in + const floating[::1, :] X, + bint X_is_sparse, + const floating[::1] X_data, + const int32_t[::1] X_indices, + const int32_t[::1] X_indptr, + const floating[::1, :] Y, + const floating[::1] sample_weight, + bint no_sample_weights, + const floating[::1] X_mean, + bint center, + const floating[::1, :] R, # current residuals = y - X @ w + const floating[::1] R_sum, floating[:, ::1] XtA, # out floating[::1] XtA_row_norms, # out ) noexcept nogil: @@ -1280,21 +1334,37 @@ cdef (floating, floating) gap_enet_multi_task( cdef floating w_l21_norm cdef floating w_l2_norm2 = 0.0 cdef unsigned int t, j + cdef int32_t i # w_l2_norm2 = linalg.norm(W, ord="fro") ** 2 if beta > 0: w_l2_norm2 = _dot(n_features * n_tasks, &W[0, 0], 1, &W[0, 0], 1) # R_norm2 = linalg.norm(R, ord="fro") ** 2 - R_norm2 = _dot(n_samples * n_tasks, &R[0, 0], 1, &R[0, 0], 1) + if not X_is_sparse or no_sample_weights: + R_norm2 = _dot(n_samples * n_tasks, &R[0, 0], 1, &R[0, 0], 1) + else: # sparse X and sample_weights + R_norm2 = 0.0 + for t in range(n_tasks): + for i in range(n_samples): + # R is already multiplied by sample_weight + if sample_weight[i] != 0: + R_norm2 += (R[i, t] ** 2) / sample_weight[i] # Ry = np.sum(R * Y) if not (alpha == 0 and beta == 0): + # Note that with sample_weight, R equals R*sw and y is just y, such that + # Ry = (sw * R) @ y, as it should be. Ry = _dot(n_samples * n_tasks, &R[0, 0], 1, &Y[0, 0], 1) if alpha == 0: # XtA = X.T @ R for j in range(n_features): for t in range(n_tasks): - XtA[j, t] = _dot(n_samples, &X[0, j], 1, &R[0, t], 1) + if not X_is_sparse: + XtA[j, t] = _dot(n_samples, &X[0, j], 1, &R[0, t], 1) + else: + XtA[j, t] = sparse_dot(j, X_data, X_indices, X_indptr, R[:, t]) + if center: + XtA[j, t] -= X_mean[j] * R_sum[t] # ||X'R||_2^2 dual_norm_XtA = _dot(n_features * n_tasks, &XtA[0, 0], 1, &XtA[0, 0], 1) if beta == 0: @@ -1312,7 +1382,13 @@ cdef (floating, floating) gap_enet_multi_task( # XtA = X.T @ R - beta * W.T for j in range(n_features): for t in range(n_tasks): - XtA[j, t] = _dot(n_samples, &X[0, j], 1, &R[0, t], 1) - beta * W[t, j] + if not X_is_sparse: + XtA[j, t] = _dot(n_samples, &X[0, j], 1, &R[0, t], 1) - beta * W[t, j] + else: + XtA[j, t] = sparse_dot(j, X_data, X_indices, X_indptr, R[:, t]) + if center: + XtA[j, t] -= X_mean[j] * R_sum[t] + XtA[j, t] -= beta * W[t, j] # dual_norm_XtA = np.max(np.sqrt(np.sum(XtA ** 2, axis=1))) dual_norm_XtA = 0.0 @@ -1344,7 +1420,13 @@ def enet_coordinate_descent_multi_task( floating alpha, floating beta, const floating[::1, :] X, + bint X_is_sparse, + const floating[::1] X_data, + const int32_t[::1] X_indices, + const int32_t[::1] X_indptr, const floating[::1, :] Y, + const floating[::1] sample_weight, + const floating[::1] X_mean, unsigned int max_iter, floating tol, object rng, @@ -1375,6 +1457,15 @@ def enet_coordinate_descent_multi_task( n_iter : int Number of coordinate descent iterations. """ + # Notes for sample_weight: + # For dense X, one centers X and y and then rescales them by sqrt(sample_weight). + # For sparse X, we get the sample_weight averaged center X_mean. We take care + # that every calculation results as if we had rescaled y and X (and therefore also + # X_mean) by sqrt(sample_weight) without actually calculating the square root. + # We work with: + # yw = sample_weight * y + # R = sample_weight * residual + # norm2_cols_X = np.sum(sample_weight * (X - X_mean)**2, axis=0) if floating is float: dtype = np.float32 @@ -1382,20 +1473,19 @@ def enet_coordinate_descent_multi_task( dtype = np.float64 # get the data information into easy vars - cdef unsigned int n_samples = X.shape[0] - cdef unsigned int n_features = X.shape[1] + cdef unsigned int n_samples = Y.shape[0] + cdef unsigned int n_features = W.shape[1] cdef unsigned int n_tasks = Y.shape[1] # compute squared norms of the columns of X - # same as norm2_cols_X = np.square(X).sum(axis=0) - cdef floating[::1] norm2_cols_X = np.einsum( - "ij,ij->j", X, X, dtype=dtype, order="C" - ) + norm2_cols_X_array = np.empty(shape=n_features, dtype=dtype) + cdef floating[::1] norm2_cols_X = norm2_cols_X_array # initial value of the residuals - cdef floating[::1, :] R = np.empty((n_samples, n_tasks), dtype=dtype, order='F') + cdef floating[::1, :] R # shape (n_samples, n_tasks) cdef floating[:, ::1] XtA = np.empty((n_features, n_tasks), dtype=dtype) cdef floating[::1] XtA_row_norms = np.empty(n_features, dtype=dtype) + cdef const floating[::1, :] Yw cdef floating d_j cdef floating Xj_theta @@ -1409,16 +1499,20 @@ def enet_coordinate_descent_multi_task( cdef floating gap = tol + 1.0 cdef floating d_w_tol = tol cdef floating dual_norm_XtA + cdef floating[::1] R_sum cdef unsigned int n_active = n_features cdef uint32_t[::1] active_set # TODO: use binset instead of array of bools cdef uint8_t[::1] excluded_set cdef unsigned int j cdef unsigned int t + cdef int32_t i, i_ind, startptr, endptr cdef unsigned int n_iter = 0 cdef unsigned int f_iter cdef uint32_t rand_r_state_seed = rng.randint(0, RAND_R_MAX) cdef uint32_t* rand_r_state = &rand_r_state_seed + cdef bint center = False + cdef bint no_sample_weights = sample_weight is None if alpha == 0: # No screeing without L1-penalty. @@ -1428,20 +1522,106 @@ def enet_coordinate_descent_multi_task( active_set = np.empty(n_features, dtype=np.uint32) # map [:n_active] -> j excluded_set = np.empty(n_features, dtype=np.uint8) + if no_sample_weights or not X_is_sparse: + Yw = Y + R = np.copy(Y, order="F") + else: + Yw = np.multiply(sample_weight[:, None], Y) + R = np.copy(Yw, order="F") + + if X_is_sparse: + R_sum = np.zeros(n_tasks, dtype=dtype) + # center = (X_mean != 0).any() + for j in range(n_features): + if X_mean[j]: + center = True + break + + # compute squared norms of the columns of X + # same as norm2_cols_X = np.square(X).sum(axis=0) + if not X_is_sparse: + np.einsum("ij,ij->j", X, X, dtype=dtype, out=norm2_cols_X_array) + else: + for j in range(n_features): + norm2_cols_X[j] = 0 + startptr = X_indptr[j] + endptr = X_indptr[j + 1] + if no_sample_weights: + for i_ind in range(startptr, endptr): + norm2_cols_X[j] += (X_data[i_ind] - X_mean[j]) ** 2 + if center: + norm2_cols_X[j] += (n_samples - endptr + startptr) * X_mean[j] ** 2 + else: + for i_ind in range(startptr, endptr): + i = X_indices[i_ind] + norm2_cols_X[j] += sample_weight[i] * ( + (X_data[i_ind] - X_mean[j]) ** 2 - X_mean[j] ** 2 + ) + if center: + for i in range(n_samples): + norm2_cols_X[j] += sample_weight[i] * X_mean[j] ** 2 + with nogil: # R = Y - X @ W.T - _copy(n_samples * n_tasks, &Y[0, 0], 1, &R[0, 0], 1) + # R = Y was already set above. for j in range(n_features): for t in range(n_tasks): if W[t, j] != 0: - _axpy(n_samples, -W[t, j], &X[0, j], 1, &R[0, t], 1) + if not X_is_sparse: + _axpy(n_samples, -W[t, j], &X[0, j], 1, &R[0, t], 1) + else: + if no_sample_weights: + sparse_axpy(j, -W[t, j], X_data, X_indices, X_indptr, R[:, t]) + else: + startptr = X_indptr[j] + endptr = X_indptr[j + 1] + for i_ind in range(startptr, endptr): + i = X_indices[i_ind] + R[i, t] -= sample_weight[i] * X_data[i_ind] * W[t, j] + + if X_is_sparse and center: + # R = Y - (X - X_mean) @ W.T + if no_sample_weights: + for i in range(n_samples): + for t in range(n_tasks): + R[i, t] += X_mean[j] * W[t, j] + R_sum[t] += R[i, t] + else: + for i in range(n_samples): + for t in range(n_tasks): + R[i, t] += sample_weight[i] * X_mean[j] * W[t, j] + R_sum[t] += R[i, t] + + # Note: No need to update R_sum from here on because the update terms cancel + # each other: w_j[t] * np.sum(X[:,j] - X_mean[j]) = 0. R_sum is only ever + # needed and calculated if X_mean is provided. # tol = tol * linalg.norm(Y, ord='fro') ** 2 - tol = tol * _nrm2(n_samples * n_tasks, &Y[0, 0], 1) ** 2 + # with sample weights: tol *= y @ (sw * y) + tol *= _dot(n_samples * n_tasks, &Y[0, 0], 1, &Yw[0, 0], 1) # Check convergence before entering the main loop. gap, dual_norm_XtA = gap_enet_multi_task( - n_samples, n_features, n_tasks, W, alpha, beta, X, Y, R, XtA, XtA_row_norms + n_samples=n_samples, + n_features=n_features, + n_tasks=n_tasks, + W=W, + alpha=alpha, + beta=beta, + X=X, + X_is_sparse=X_is_sparse, + X_data=X_data, + X_indices=X_indices, + X_indptr=X_indptr, + Y=Y, + sample_weight=sample_weight, + no_sample_weights=no_sample_weights, + X_mean=X_mean, + center=center, + R=R, + R_sum=R_sum, + XtA=XtA, + XtA_row_norms=XtA_row_norms, ) if gap <= tol: with gil: @@ -1466,10 +1646,25 @@ def enet_coordinate_descent_multi_task( excluded_set[j] = 0 n_active += 1 else: - # R += W[:, 1] * X[:, 1][:, None] + # R += W[:, j] * X[:, 1][:, None] for t in range(n_tasks): if W[t, j] != 0: - _axpy(n_samples, W[t, j], &X[0, j], 1, &R[0, t], 1) + if not X_is_sparse: + _axpy(n_samples, W[t, j], &X[0, j], 1, &R[0, t], 1) + else: + R_plus_wj_Xj( + n_samples=n_samples, + R=R[:, t], + X_data=X_data, + X_indices=X_indices, + X_indptr=X_indptr, + X_mean=X_mean, + center=center, + sample_weight=sample_weight, + no_sample_weights=no_sample_weights, + w_j=W[t, j], + j=j, + ) W[t, j] = 0 excluded_set[j] = 1 @@ -1501,7 +1696,10 @@ def enet_coordinate_descent_multi_task( # _axpy(n_tasks, norm2_cols[j], &w_j[0], 1, &tmp[0], 1) # Using BLAS Level 1 (faster for small vectors like here): for t in range(n_tasks): - tmp[t] = _dot(n_samples, &X[0, j], 1, &R[0, t], 1) + if not X_is_sparse: + tmp[t] = _dot(n_samples, &X[0, j], 1, &R[0, t], 1) + else: + tmp[t] = sparse_dot(j, X_data, X_indices, X_indptr, R[:, t]) # As we have the loop already, we use it to replace the second BLAS # Level 1, i.e., _axpy, too. tmp[t] += w_j[t] * norm2_cols_X[j] @@ -1525,7 +1723,22 @@ def enet_coordinate_descent_multi_task( # Using BLAS Level 1 (faster for small vectors like here): for t in range(n_tasks): if W[t, j] != w_j[t]: - _axpy(n_samples, w_j[t] - W[t, j], &X[0, j], 1, &R[0, t], 1) + if not X_is_sparse: + _axpy(n_samples, w_j[t] - W[t, j], &X[0, j], 1, &R[0, t], 1) + else: + R_plus_wj_Xj( + n_samples=n_samples, + R=R[:, t], + X_data=X_data, + X_indices=X_indices, + X_indptr=X_indptr, + X_mean=X_mean, + center=center, + sample_weight=sample_weight, + no_sample_weights=no_sample_weights, + w_j=w_j[t] - W[t, j], + j=j, + ) # update the maximum absolute coefficient update d_w_j = diff_abs_max(n_tasks, &W[0, j], &w_j[0]) @@ -1542,7 +1755,26 @@ def enet_coordinate_descent_multi_task( # the tolerance: check the duality gap as ultimate stopping # criterion gap, dual_norm_XtA = gap_enet_multi_task( - n_samples, n_features, n_tasks, W, alpha, beta, X, Y, R, XtA, XtA_row_norms + n_samples=n_samples, + n_features=n_features, + n_tasks=n_tasks, + W=W, + alpha=alpha, + beta=beta, + X=X, + X_is_sparse=X_is_sparse, + X_data=X_data, + X_indices=X_indices, + X_indptr=X_indptr, + Y=Y, + sample_weight=sample_weight, + no_sample_weights=no_sample_weights, + X_mean=X_mean, + center=center, + R=R, + R_sum=R_sum, + XtA=XtA, + XtA_row_norms=XtA_row_norms, ) if gap <= tol: # return if we reached desired tolerance @@ -1564,10 +1796,25 @@ def enet_coordinate_descent_multi_task( excluded_set[j] = 0 n_active += 1 else: - # R += W[:, 1] * X[:, 1][:, None] + # R += W[:, j] * X[:, 1][:, None] for t in range(n_tasks): if W[t, j] != 0: - _axpy(n_samples, W[t, j], &X[0, j], 1, &R[0, t], 1) + if not X_is_sparse: + _axpy(n_samples, W[t, j], &X[0, j], 1, &R[0, t], 1) + else: + R_plus_wj_Xj( + n_samples=n_samples, + R=R[:, t], + X_data=X_data, + X_indices=X_indices, + X_indptr=X_indptr, + X_mean=X_mean, + center=center, + sample_weight=sample_weight, + no_sample_weights=no_sample_weights, + w_j=W[t, j], + j=j, + ) W[t, j] = 0 excluded_set[j] = 1 diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index 378c5df8efc02..d66ee2063af3b 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -19,7 +19,6 @@ from sklearn.linear_model._base import ( MultiOutputLinearModel, _pre_fit, - _preprocess_data, ) from sklearn.model_selection import check_cv from sklearn.utils import Bunch, check_array, check_scalar, metadata_routing @@ -27,7 +26,6 @@ MetadataRouter, MethodMapping, _raise_for_params, - get_routing_for_object, ) from sklearn.utils._param_validation import ( Hidden, @@ -46,7 +44,6 @@ check_is_fitted, check_random_state, column_or_1d, - has_fit_parameter, validate_data, ) @@ -626,8 +623,8 @@ def enet_path( if multi_output and positive: raise ValueError("positive=True is not allowed for multi-output (y.ndim != 1)") - # MultiTaskElasticNet does not support sparse matrices - if not multi_output and sparse.issparse(X): + X_is_sparse = sparse.issparse(X) + if X_is_sparse: if X_offset_param is not None: # As sparse matrices are not actually centered we need this to be passed to # the CD solver. @@ -635,6 +632,8 @@ def enet_path( X_sparse_scaling = np.asarray(X_sparse_scaling, dtype=X.dtype) else: X_sparse_scaling = np.zeros(n_features, dtype=X.dtype) + else: + X_sparse_scaling = None # X should have been passed through _pre_fit already if function is called # from ElasticNet.fit @@ -683,18 +682,27 @@ def enet_path( else: coef_ = np.asfortranarray(coef_init, dtype=X.dtype) + if X_is_sparse: + X_data = X.data + X_indices = X.indices + X_indptr = X.indptr + else: + X_data = None + X_indices = None + X_indptr = None + for i, alpha in enumerate(alphas): # account for n_samples scaling in objectives between here and cd_fast l1_reg = alpha * l1_ratio * n_samples l2_reg = alpha * (1.0 - l1_ratio) * n_samples - if not multi_output and sparse.issparse(X): + if not multi_output and X_is_sparse: model = cd_fast.sparse_enet_coordinate_descent( w=coef_, alpha=l1_reg, beta=l2_reg, - X_data=X.data, - X_indices=X.indices, - X_indptr=X.indptr, + X_data=X_data, + X_indices=X_indices, + X_indptr=X_indptr, y=y, sample_weight=sample_weight, X_mean=X_sparse_scaling, @@ -707,7 +715,22 @@ def enet_path( ) elif multi_output: model = cd_fast.enet_coordinate_descent_multi_task( - coef_, l1_reg, l2_reg, X, y, max_iter, tol, rng, random, do_screening + W=coef_, + alpha=l1_reg, + beta=l2_reg, + X=None if X_is_sparse else X, + X_is_sparse=X_is_sparse, + X_data=X_data, + X_indices=X_indices, + X_indptr=X_indptr, + Y=y, + sample_weight=sample_weight, + X_mean=X_sparse_scaling, + max_iter=max_iter, + tol=tol, + rng=rng, + random=random, + do_screening=do_screening, ) elif isinstance(precompute, np.ndarray): # We expect precompute to be already Fortran ordered when bypassing @@ -989,7 +1012,7 @@ def fit(self, X, y, sample_weight=None, check_input=True): Parameters ---------- - X : {ndarray, sparse matrix, sparse array} of (n_samples, n_features) + X : {ndarray, sparse matrix, sparse array} of shape (n_samples, n_features) Data. Note that large sparse matrices and arrays requiring `int64` @@ -1056,7 +1079,6 @@ def fit(self, X, y, sample_weight=None, check_input=True): ) n_samples, n_features = X.shape - alpha = self.alpha if isinstance(sample_weight, numbers.Number): sample_weight = None @@ -1142,7 +1164,7 @@ def fit(self, X, y, sample_weight=None, check_input=True): l1_ratio=self.l1_ratio, eps=None, n_alphas=None, - alphas=[alpha], + alphas=[self.alpha], precompute=precompute, Xy=this_Xy, copy_X=True, @@ -1631,7 +1653,7 @@ def path(X, y, **kwargs): @_fit_context(prefer_skip_nested_validation=True) def fit(self, X, y, sample_weight=None, **params): - """Fit linear model with coordinate descent. + """Fit model with internal cross-validation and with coordinate descent. Fit is on grid of alphas and best alpha estimated by cross-validation. @@ -1771,9 +1793,7 @@ def fit(self, X, y, sample_weight=None, **params): ) y = column_or_1d(y, warn=True) else: - if sparse.issparse(X): - raise TypeError("X should be dense but a sparse matrix was passed.") - elif y.ndim == 1: + if y.ndim == 1: raise ValueError( "For mono-task outputs, use %sCV" % self.__class__.__name__[9:] ) @@ -1847,29 +1867,12 @@ def fit(self, X, y, sample_weight=None, **params): cv = check_cv(self.cv) if _routing_enabled(): - splitter_supports_sample_weight = get_routing_for_object(cv).consumes( - method="split", params=["sample_weight"] + routed_params = process_routing( + self, + "fit", + sample_weight=sample_weight, + **params, ) - if ( - sample_weight is not None - and not splitter_supports_sample_weight - and not has_fit_parameter(self, "sample_weight") - ): - raise ValueError( - "The CV splitter and underlying estimator do not support" - " sample weights." - ) - - if splitter_supports_sample_weight: - params["sample_weight"] = sample_weight - - routed_params = process_routing(self, "fit", **params) - - if sample_weight is not None and not has_fit_parameter( - self, "sample_weight" - ): - # MultiTaskElasticNetCV does not (yet) support sample_weight - sample_weight = None else: routed_params = Bunch() routed_params.splitter = Bunch(split=Bunch()) @@ -1980,7 +1983,8 @@ def get_metadata_routing(self): def __sklearn_tags__(self): tags = super().__sklearn_tags__() multitask = self._is_multitask() - tags.input_tags.sparse = not multitask + tags.input_tags.sparse = True + tags.target_tags.single_output = not multitask tags.target_tags.multi_output = multitask return tags @@ -2547,7 +2551,7 @@ def fit(self, X, y, sample_weight=None, **params): # Multi Task ElasticNet and Lasso models (with joint feature selection) -class MultiTaskElasticNet(Lasso): +class MultiTaskElasticNet(ElasticNet): """Multi-task ElasticNet model trained with L1/L2 mixed-norm as regularizer. The optimization objective for MultiTaskElasticNet is:: @@ -2671,9 +2675,7 @@ class MultiTaskElasticNet(Lasso): [0.0872422 0.0872422] """ - _parameter_constraints: dict = { - **ElasticNet._parameter_constraints, - } + _parameter_constraints: dict = {**ElasticNet._parameter_constraints} for param in ("precompute", "positive"): _parameter_constraints.pop(param) @@ -2690,8 +2692,8 @@ def __init__( random_state=None, selection="cyclic", ): - self.l1_ratio = l1_ratio self.alpha = alpha + self.l1_ratio = l1_ratio self.fit_intercept = fit_intercept self.max_iter = max_iter self.copy_X = copy_X @@ -2701,16 +2703,27 @@ def __init__( self.selection = selection @_fit_context(prefer_skip_nested_validation=True) - def fit(self, X, y): + def fit(self, X, y, sample_weight=None): """Fit MultiTaskElasticNet model with coordinate descent. Parameters ---------- - X : ndarray of shape (n_samples, n_features) - Data. + X : {ndarray, sparse matrix, sparse array} of shape (n_samples, n_features) + Data. Pass directly as Fortran-contiguous data to avoid unnecessary memory + duplication. + + Note that large sparse matrices and arrays requiring `int64` + indices are not accepted. + y : ndarray of shape (n_samples, n_targets) Target. Will be cast to X's dtype if necessary. + sample_weight : float or array-like of shape (n_samples,), default=None + Sample weights. Internally, the `sample_weight` vector will be + rescaled to sum to `n_samples`. + + .. versionadded:: 1.9 + Returns ------- self : object @@ -2725,62 +2738,103 @@ def fit(self, X, y): To avoid memory re-allocation it is advised to allocate the initial data in memory directly using that format. """ + # Remember if X is copied + X_copied = self.copy_X and self.fit_intercept # Need to validate separately here. # We can't pass multi_output=True because that would allow y to be csr. check_X_params = dict( + accept_sparse="csc", dtype=[np.float64, np.float32], order="F", force_writeable=True, - copy=self.copy_X and self.fit_intercept, + accept_large_sparse=False, + copy=X_copied, + ) + check_y_params = dict( + copy=False, dtype=[np.float64, np.float32], ensure_2d=False, order="F" ) - check_y_params = dict(ensure_2d=False, order="F") X, y = validate_data( self, X, y, validate_separately=(check_X_params, check_y_params) ) check_consistent_length(X, y) - y = y.astype(X.dtype) - if hasattr(self, "l1_ratio"): - model_str = "ElasticNet" - else: - model_str = "Lasso" if y.ndim == 1: + if hasattr(self, "l1_ratio"): + model_str = "ElasticNet" + else: + model_str = "Lasso" raise ValueError("For mono-task outputs, use %s" % model_str) n_samples, n_features = X.shape n_targets = y.shape[1] - X, y, X_offset, y_offset, X_scale, _ = _preprocess_data( - X, y, fit_intercept=self.fit_intercept, copy=False + if isinstance(sample_weight, numbers.Number): + sample_weight = None + if sample_weight is not None: + sample_weight = _check_sample_weight(sample_weight, X, dtype=X.dtype) + # TLDR: Rescale sw to sum up to n_samples. + # Long: See comment in ElasticNet. + sample_weight = sample_weight * (n_samples / np.sum(sample_weight)) + + X, y, X_offset, y_offset, X_scale, _, _ = _pre_fit( + X=X, + y=y, + Xy=None, + precompute=False, + fit_intercept=self.fit_intercept, + copy=False, # TODO: improve + sample_weight=sample_weight, ) + # coordinate descent needs F-ordered arrays and _pre_fit might have + # called _rescale_data + if sample_weight is not None: + X, y = _set_order(X, y, order="F") if not self.warm_start or not hasattr(self, "coef_"): - self.coef_ = np.zeros( - (n_targets, n_features), dtype=X.dtype.type, order="F" - ) + self.coef_ = np.zeros((n_targets, n_features), dtype=X.dtype, order="F") + else: + self.coef_ = np.asfortranarray(self.coef_) # coef F-contiguous in memory + X_is_sparse = sparse.issparse(X) + if X_is_sparse: + X_data = X.data + X_indices = X.indices + X_indptr = X.indptr + # As sparse matrices are not actually centered we need this to be passed to + # the CD solver. + X_mean = np.asarray(X_offset / X_scale, dtype=X.dtype) + X = None + else: + X_data = None + X_indices = None + X_indptr = None + X_mean = None + + # account for n_samples scaling in objectives between here and cd_fast l1_reg = self.alpha * self.l1_ratio * n_samples l2_reg = self.alpha * (1.0 - self.l1_ratio) * n_samples - self.coef_ = np.asfortranarray(self.coef_) # coef contiguous in memory - - random = self.selection == "random" - ( self.coef_, self.dual_gap_, self.eps_, self.n_iter_, ) = cd_fast.enet_coordinate_descent_multi_task( - self.coef_, - l1_reg, - l2_reg, - X, - y, - self.max_iter, - self.tol, - check_random_state(self.random_state), - random, + W=self.coef_, + alpha=l1_reg, + beta=l2_reg, + X=X, + X_is_sparse=X_is_sparse, + X_data=X_data, + X_indices=X_indices, + X_indptr=X_indptr, + Y=y, + sample_weight=sample_weight, + X_mean=X_mean, + max_iter=self.max_iter, + tol=self.tol, + rng=check_random_state(self.random_state), + random=self.selection == "random", do_screening=True, ) @@ -2794,7 +2848,6 @@ def fit(self, X, y): def __sklearn_tags__(self): tags = super().__sklearn_tags__() - tags.input_tags.sparse = False tags.target_tags.multi_output = True tags.target_tags.single_output = False return tags @@ -3174,42 +3227,6 @@ def _get_estimator(self): def _is_multitask(self): return True - def __sklearn_tags__(self): - tags = super().__sklearn_tags__() - tags.target_tags.single_output = False - return tags - - # This is necessary as LinearModelCV now supports sample_weight while - # MultiTaskElasticNetCV does not (yet). - def fit(self, X, y, **params): - """Fit MultiTaskElasticNet model with coordinate descent. - - Fit is on grid of alphas and best alpha estimated by cross-validation. - - Parameters - ---------- - X : ndarray of shape (n_samples, n_features) - Training data. - y : ndarray of shape (n_samples, n_targets) - Training target variable. Will be cast to X's dtype if necessary. - - **params : dict, default=None - Parameters to be passed to the CV splitter. - - .. versionadded:: 1.4 - Only available if `enable_metadata_routing=True`, - which can be set by using - ``sklearn.set_config(enable_metadata_routing=True)``. - See :ref:`Metadata Routing User Guide <metadata_routing>` for - more details. - - Returns - ------- - self : object - Returns MultiTaskElasticNet instance. - """ - return super().fit(X, y, **params) - class MultiTaskLassoCV(RegressorMixin, LinearModelCV): """Multi-task Lasso model trained with L1/L2 mixed-norm as regularizer. @@ -3425,39 +3442,3 @@ def _get_estimator(self): def _is_multitask(self): return True - - def __sklearn_tags__(self): - tags = super().__sklearn_tags__() - tags.target_tags.single_output = False - return tags - - # This is necessary as LinearModelCV now supports sample_weight while - # MultiTaskLassoCV does not (yet). - def fit(self, X, y, **params): - """Fit MultiTaskLasso model with coordinate descent. - - Fit is on grid of alphas and best alpha estimated by cross-validation. - - Parameters - ---------- - X : ndarray of shape (n_samples, n_features) - Data. - y : ndarray of shape (n_samples, n_targets) - Target. Will be cast to X's dtype if necessary. - - **params : dict, default=None - Parameters to be passed to the CV splitter. - - .. versionadded:: 1.4 - Only available if `enable_metadata_routing=True`, - which can be set by using - ``sklearn.set_config(enable_metadata_routing=True)``. - See :ref:`Metadata Routing User Guide <metadata_routing>` for - more details. - - Returns - ------- - self : object - Returns an instance of fitted model. - """ - return super().fit(X, y, **params) diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index fbb9d5db1d492..3bdc991887ecc 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -9,7 +9,7 @@ import pytest from scipy import interpolate, sparse -from sklearn.base import clone, config_context +from sklearn.base import clone from sklearn.datasets import load_diabetes, make_regression from sklearn.exceptions import ConvergenceWarning from sklearn.linear_model import ( @@ -31,11 +31,9 @@ from sklearn.linear_model import _cd_fast as cd_fast # type: ignore[attr-defined] from sklearn.linear_model._coordinate_descent import _set_order from sklearn.model_selection import ( - BaseCrossValidator, GridSearchCV, LeaveOneGroupOut, ) -from sklearn.model_selection._split import GroupsConsumerMixin from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler from sklearn.utils import check_array @@ -758,22 +756,22 @@ def test_1d_multioutput_lasso_and_multitask_lasso_cv(): assert_almost_equal(clf.intercept_, clf1.intercept_[0]) +@pytest.mark.parametrize( + "estimator", [ElasticNetCV, LassoCV, MultiTaskElasticNetCV, MultiTaskLassoCV] +) @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) -def test_sparse_input_dtype_enet_and_lassocv(csr_container): - X, y, _, _ = build_dataset(n_features=10) - clf = ElasticNetCV(alphas=5) - clf.fit(csr_container(X), y) - clf1 = ElasticNetCV(alphas=5) - clf1.fit(csr_container(X, dtype=np.float32), y) - assert_almost_equal(clf.alpha_, clf1.alpha_, decimal=6) - assert_almost_equal(clf.coef_, clf1.coef_, decimal=6) - - clf = LassoCV(alphas=5) - clf.fit(csr_container(X), y) - clf1 = LassoCV(alphas=5) - clf1.fit(csr_container(X, dtype=np.float32), y) - assert_almost_equal(clf.alpha_, clf1.alpha_, decimal=6) - assert_almost_equal(clf.coef_, clf1.coef_, decimal=6) +def test_sparse_input_dtype_enet_and_lassocv(estimator, csr_container): + if issubclass(estimator, (MultiTaskElasticNetCV, MultiTaskLassoCV)): + n_targets = 2 + else: + n_targets = 1 + X, y, _, _ = build_dataset(n_targets=n_targets, n_features=10) + reg = estimator(alphas=5) + reg.fit(csr_container(X), y) + reg1 = estimator(alphas=5) + reg1.fit(csr_container(X, dtype=np.float32), y) + assert_allclose(reg.alpha_, reg1.alpha_, rtol=1e-5) + assert_allclose(reg.coef_, reg1.coef_, rtol=1e-5) def test_elasticnet_precompute_incorrect_gram(): @@ -894,66 +892,66 @@ def test_random_descent(csr_container): # This uses the coordinate descent algo using the gram trick. X, y, _, _ = build_dataset(n_samples=50, n_features=20) - clf_cyclic = ElasticNet(selection="cyclic", tol=1e-8) + clf_cyclic = ElasticNet(selection="cyclic", tol=1e-9) clf_cyclic.fit(X, y) - clf_random = ElasticNet(selection="random", tol=1e-8, random_state=42) + clf_random = ElasticNet(selection="random", tol=1e-9, random_state=42) clf_random.fit(X, y) - assert_array_almost_equal(clf_cyclic.coef_, clf_random.coef_) - assert_almost_equal(clf_cyclic.intercept_, clf_random.intercept_) + assert_allclose(clf_cyclic.coef_, clf_random.coef_) + assert_allclose(clf_cyclic.intercept_, clf_random.intercept_) # This uses the descent algo without the gram trick - clf_cyclic = ElasticNet(selection="cyclic", tol=1e-8) + clf_cyclic = ElasticNet(selection="cyclic", tol=1e-9) clf_cyclic.fit(X.T, y[:20]) - clf_random = ElasticNet(selection="random", tol=1e-8, random_state=42) + clf_random = ElasticNet(selection="random", tol=1e-9, random_state=42) clf_random.fit(X.T, y[:20]) - assert_array_almost_equal(clf_cyclic.coef_, clf_random.coef_) - assert_almost_equal(clf_cyclic.intercept_, clf_random.intercept_) + assert_allclose(clf_cyclic.coef_, clf_random.coef_) + assert_allclose(clf_cyclic.intercept_, clf_random.intercept_) # Sparse Case - clf_cyclic = ElasticNet(selection="cyclic", tol=1e-8) + clf_cyclic = ElasticNet(selection="cyclic", tol=1e-9) clf_cyclic.fit(csr_container(X), y) - clf_random = ElasticNet(selection="random", tol=1e-8, random_state=42) + clf_random = ElasticNet(selection="random", tol=1e-9, random_state=42) clf_random.fit(csr_container(X), y) - assert_array_almost_equal(clf_cyclic.coef_, clf_random.coef_) - assert_almost_equal(clf_cyclic.intercept_, clf_random.intercept_) + assert_allclose(clf_cyclic.coef_, clf_random.coef_) + assert_allclose(clf_cyclic.intercept_, clf_random.intercept_) # Multioutput case. new_y = np.hstack((y[:, np.newaxis], y[:, np.newaxis])) - clf_cyclic = MultiTaskElasticNet(selection="cyclic", tol=1e-8) - clf_cyclic.fit(X, new_y) - clf_random = MultiTaskElasticNet(selection="random", tol=1e-8, random_state=42) - clf_random.fit(X, new_y) - assert_array_almost_equal(clf_cyclic.coef_, clf_random.coef_) - assert_almost_equal(clf_cyclic.intercept_, clf_random.intercept_) + clf_cyclic = MultiTaskElasticNet(selection="cyclic", tol=1e-9) + clf_cyclic.fit(csr_container(X), new_y) + clf_random = MultiTaskElasticNet(selection="random", tol=1e-9, random_state=42) + clf_random.fit(csr_container(X), new_y) + assert_allclose(clf_cyclic.coef_, clf_random.coef_) + assert_allclose(clf_cyclic.intercept_, clf_random.intercept_) + + +@pytest.mark.parametrize("path", [enet_path, lasso_path]) +@pytest.mark.parametrize("n_targets", [1, 2]) +@pytest.mark.parametrize("csr_container", CSR_CONTAINERS) +def test_sparse_dense_descent_paths(path, n_targets, csr_container): + # Test that dense and sparse input give the same result for descent paths. + X, y, _, _ = build_dataset(n_targets=n_targets, n_samples=50, n_features=20) + csr = csr_container(X) + _, coefs, _ = path(X, y, tol=1e-10) + _, sparse_coefs, _ = path(csr, y, tol=1e-10) + assert_allclose(coefs, sparse_coefs) -def test_enet_path_positive(): +@pytest.mark.parametrize("path", [enet_path, lasso_path]) +def test_enet_path_positive(path): # Test positive parameter X, Y, _, _ = build_dataset(n_samples=50, n_features=50, n_targets=2) # For mono output # Test that the coefs returned by positive=True in enet_path are positive - for path in [enet_path, lasso_path]: - pos_path_coef = path(X, Y[:, 0], positive=True)[1] - assert np.all(pos_path_coef >= 0) + pos_path_coef = path(X, Y[:, 0], positive=True)[1] + assert np.all(pos_path_coef >= 0) # For multi output, positive parameter is not allowed # Test that an error is raised - for path in [enet_path, lasso_path]: - with pytest.raises(ValueError): - path(X, Y, positive=True) - - -@pytest.mark.parametrize("csr_container", CSR_CONTAINERS) -def test_sparse_dense_descent_paths(csr_container): - # Test that dense and sparse input give the same input for descent paths. - X, y, _, _ = build_dataset(n_samples=50, n_features=20) - csr = csr_container(X) - for path in [enet_path, lasso_path]: - _, coefs, _ = path(X, y, tol=1e-10) - _, sparse_coefs, _ = path(csr, y, tol=1e-10) - assert_allclose(coefs, sparse_coefs) + with pytest.raises(ValueError): + path(X, Y, positive=True) @pytest.mark.parametrize("path_func", [enet_path, lasso_path]) @@ -1151,15 +1149,15 @@ def test_warm_start_multitask_lasso(): @pytest.mark.parametrize( - "klass, n_classes, kwargs", + "est, kwargs", [ - (Lasso, 1, dict(precompute=True)), - (Lasso, 1, dict(precompute=False)), + (Lasso, dict(precompute=True)), + (Lasso, dict(precompute=False)), ], ) -def test_enet_coordinate_descent_raises_convergence(klass, n_classes, kwargs): +def test_enet_coordinate_descent_raises_convergence(est, kwargs): """Test that a warning is issued if model does not converge""" - clf = klass( + reg = est( alpha=1e-10, fit_intercept=False, warm_start=True, @@ -1168,7 +1166,7 @@ def test_enet_coordinate_descent_raises_convergence(klass, n_classes, kwargs): **kwargs, ) # Set initial coefficients to very bad values. - clf.coef_ = np.array([1, 1, 1, 1000]) + reg.coef_ = np.array([1, 1, 1, 1000]) X = np.array([[-1, -1, 1, 1], [1, 1, -1, -1]]) y = np.array([-1, 1]) warning_message = ( @@ -1176,7 +1174,7 @@ def test_enet_coordinate_descent_raises_convergence(klass, n_classes, kwargs): " increase the number of iterations." ) with pytest.warns(ConvergenceWarning, match=warning_message): - clf.fit(X, y) + reg.fit(X, y) def test_convergence_warnings(): @@ -1190,17 +1188,24 @@ def test_convergence_warnings(): MultiTaskElasticNet().fit(X, y) +@pytest.mark.parametrize( + "estimator", [ElasticNetCV, LassoCV, MultiTaskElasticNetCV, MultiTaskLassoCV] +) @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) -def test_sparse_input_convergence_warning(csr_container): - X, y, _, _ = build_dataset(n_samples=1000, n_features=500) +def test_sparse_input_convergence_warning(estimator, csr_container): + if issubclass(estimator, (MultiTaskElasticNetCV, MultiTaskLassoCV)): + n_targets = 2 + else: + n_targets = 1 + X, y, _, _ = build_dataset(n_targets=n_targets, n_samples=50, n_features=25) with pytest.warns(ConvergenceWarning): - ElasticNet(max_iter=1, tol=0).fit(csr_container(X, dtype=np.float32), y) + estimator(max_iter=1, tol=0).fit(csr_container(X, dtype=np.float32), y) # check that the model converges w/o convergence warnings with warnings.catch_warnings(): warnings.simplefilter("error", ConvergenceWarning) - Lasso().fit(csr_container(X, dtype=np.float32), y) + estimator().fit(csr_container(X, dtype=np.float32), y) @pytest.mark.parametrize( @@ -1238,12 +1243,13 @@ def test_multi_task_lasso_cv_dtype(): assert_array_almost_equal(est.coef_, [[1, 0, 0]] * 2, decimal=3) +@pytest.mark.parametrize("estimator", [ElasticNet, MultiTaskElasticNet]) @pytest.mark.parametrize("fit_intercept", [True, False]) @pytest.mark.parametrize("alpha", [0.01]) @pytest.mark.parametrize("precompute", [False, True]) @pytest.mark.parametrize("sparse_container", [None] + CSR_CONTAINERS) def test_enet_sample_weight_consistency( - fit_intercept, alpha, precompute, sparse_container, global_random_seed + estimator, fit_intercept, alpha, precompute, sparse_container, global_random_seed ): """Test that the impact of sample_weight is consistent. @@ -1252,26 +1258,36 @@ def test_enet_sample_weight_consistency( """ rng = np.random.RandomState(global_random_seed) n_samples, n_features = 10, 5 - X = rng.rand(n_samples, n_features) y = rng.rand(n_samples) - if sparse_container is not None: - X = sparse_container(X) + params = dict( alpha=alpha, fit_intercept=fit_intercept, - precompute=precompute, tol=1e-6, l1_ratio=0.5, ) - reg = ElasticNet(**params).fit(X, y) + if issubclass(estimator, MultiTaskElasticNet): + n_tasks = 3 + y = np.tile(y[:, None], reps=(1, n_tasks)) + if precompute: + return + else: + n_tasks = 1 + params["precompute"] = precompute + + if sparse_container is not None: + X = sparse_container(X) + + reg = estimator(**params).fit(X, y) coef = reg.coef_.copy() if fit_intercept: intercept = reg.intercept_ + assert np.sum(coef != 0) > 1 # 1) sample_weight=np.ones(..) should be equivalent to sample_weight=None - sample_weight = np.ones_like(y) + sample_weight = np.ones_like(y, shape=y.shape[0]) reg.fit(X, y, sample_weight=sample_weight) assert_allclose(reg.coef_, coef, rtol=1e-6) if fit_intercept: @@ -1315,22 +1331,23 @@ def test_enet_sample_weight_consistency( X2 = sparse.vstack([X, X[: n_samples // 2]], format="csc") else: X2 = np.concatenate([X, X[: n_samples // 2]], axis=0) - y2 = np.concatenate([y, y[: n_samples // 2]]) + y2 = np.concatenate([y, y[: n_samples // 2]], axis=0) sample_weight_1 = sample_weight.copy() sample_weight_1[: n_samples // 2] *= 2 sample_weight_2 = np.concatenate( [sample_weight, sample_weight[: n_samples // 2]], axis=0 ) - reg1 = ElasticNet(**params).fit(X, y, sample_weight=sample_weight_1) - reg2 = ElasticNet(**params).fit(X2, y2, sample_weight=sample_weight_2) + reg1 = estimator(**params).fit(X, y, sample_weight=sample_weight_1) + reg2 = estimator(**params).fit(X2, y2, sample_weight=sample_weight_2) assert_allclose(reg1.coef_, reg2.coef_, rtol=1e-6) +@pytest.mark.parametrize("estimator", [ElasticNetCV, MultiTaskElasticNetCV]) @pytest.mark.parametrize("fit_intercept", [True, False]) @pytest.mark.parametrize("sparse_container", [None] + CSC_CONTAINERS) def test_enet_cv_sample_weight_correctness( - fit_intercept, sparse_container, global_random_seed + estimator, fit_intercept, sparse_container, global_random_seed ): """Test that ElasticNetCV with sample weights gives correct results. @@ -1346,9 +1363,12 @@ def test_enet_cv_sample_weight_correctness( rng = np.random.RandomState(global_random_seed) n_splits, n_samples_per_cv, n_features = 3, 10, 5 X_with_weights = rng.rand(n_splits * n_samples_per_cv, n_features) - beta = rng.rand(n_features) + beta = 10 * rng.rand(n_features) beta[0:2] = 0 y_with_weights = X_with_weights @ beta + rng.rand(n_splits * n_samples_per_cv) + if issubclass(estimator, MultiTaskElasticNetCV): + n_tasks = 3 + y_with_weights = np.tile(y_with_weights[:, None], reps=(1, n_tasks)) if sparse_container is not None: X_with_weights = sparse_container(X_with_weights) @@ -1358,7 +1378,7 @@ def test_enet_cv_sample_weight_correctness( # The samples in the other cross-validation groups are left with unit # weights. - sw = np.ones_like(y_with_weights) + sw = np.ones(y_with_weights.shape[0]) sw[:n_samples_per_cv] = rng.randint(0, 5, size=n_samples_per_cv) groups_with_weights = np.concatenate( [ @@ -1370,11 +1390,12 @@ def test_enet_cv_sample_weight_correctness( splits_with_weights = list( LeaveOneGroupOut().split(X_with_weights, groups=groups_with_weights) ) - reg_with_weights = ElasticNetCV( + reg_with_weights = estimator( cv=splits_with_weights, fit_intercept=fit_intercept, **params ) reg_with_weights.fit(X_with_weights, y_with_weights, sample_weight=sw) + assert np.sum(reg_with_weights.coef_ != 0) > 1 if sparse_container is not None: X_with_weights = X_with_weights.toarray() @@ -1388,7 +1409,7 @@ def test_enet_cv_sample_weight_correctness( splits_with_repetitions = list( LeaveOneGroupOut().split(X_with_repetitions, groups=groups_with_repetitions) ) - reg_with_repetitions = ElasticNetCV( + reg_with_repetitions = estimator( cv=splits_with_repetitions, fit_intercept=fit_intercept, **params ) reg_with_repetitions.fit(X_with_repetitions, y_with_repetitions) @@ -1403,12 +1424,22 @@ def test_enet_cv_sample_weight_correctness( assert reg_with_weights.intercept_ == pytest.approx(reg_with_repetitions.intercept_) +@pytest.mark.parametrize( + ["estimatorCV", "estimator"], + [(ElasticNetCV, ElasticNet), (MultiTaskElasticNetCV, MultiTaskElasticNet)], +) @pytest.mark.parametrize("sample_weight", [False, True]) -def test_enet_cv_grid_search(sample_weight): +def test_enet_cv_grid_search(estimatorCV, estimator, sample_weight): """Test that ElasticNetCV gives same result as GridSearchCV.""" n_samples, n_features = 200, 10 + if issubclass(estimatorCV, MultiTaskElasticNetCV): + n_targets = 3 + else: + n_targets = 1 + cv = 5 X, y = make_regression( + n_targets=n_targets, n_samples=n_samples, n_features=n_features, effective_rank=10, @@ -1423,12 +1454,12 @@ def test_enet_cv_grid_search(sample_weight): alphas = np.logspace(np.log10(1e-5), np.log10(1), num=10) l1_ratios = [0.1, 0.5, 0.9] - reg = ElasticNetCV(cv=cv, alphas=alphas, l1_ratio=l1_ratios) + reg = estimatorCV(cv=cv, alphas=alphas, l1_ratio=l1_ratios) reg.fit(X, y, sample_weight=sample_weight) param = {"alpha": alphas, "l1_ratio": l1_ratios} gs = GridSearchCV( - estimator=ElasticNet(), + estimator=estimator(), param_grid=param, cv=cv, scoring="neg_mean_squared_error", @@ -1438,12 +1469,22 @@ def test_enet_cv_grid_search(sample_weight): assert reg.alpha_ == pytest.approx(gs.best_params_["alpha"]) +@pytest.mark.parametrize( + ["estimator", "l1_ratio"], + [ + (LassoCV, 0), + (ElasticNetCV, 0.5), + (ElasticNetCV, 1), + (MultiTaskLassoCV, 0), + (MultiTaskElasticNetCV, 0.5), + (MultiTaskElasticNetCV, 1), + ], +) @pytest.mark.parametrize("fit_intercept", [True, False]) -@pytest.mark.parametrize("l1_ratio", [0, 0.5, 1]) @pytest.mark.parametrize("precompute", [False, True]) @pytest.mark.parametrize("sparse_container", [None] + CSC_CONTAINERS) def test_enet_cv_sample_weight_consistency( - fit_intercept, l1_ratio, precompute, sparse_container + estimator, l1_ratio, fit_intercept, precompute, sparse_container ): """Test that the impact of sample_weight is consistent.""" rng = np.random.RandomState(0) @@ -1452,26 +1493,28 @@ def test_enet_cv_sample_weight_consistency( X = rng.rand(n_samples, n_features) y = X.sum(axis=1) + rng.rand(n_samples) params = dict( - l1_ratio=l1_ratio, fit_intercept=fit_intercept, precompute=precompute, tol=1e-6, cv=3, ) + if l1_ratio > 0: + params["l1_ratio"] = l1_ratio + if issubclass(estimator, (MultiTaskElasticNetCV, MultiTaskLassoCV)): + n_tasks = 3 + y = np.tile(y[:, None], reps=(1, n_tasks)) + params.pop("precompute") if sparse_container is not None: X = sparse_container(X) - if l1_ratio == 0: - params.pop("l1_ratio", None) - reg = LassoCV(**params).fit(X, y) - else: - reg = ElasticNetCV(**params).fit(X, y) + reg = estimator(**params).fit(X, y) coef = reg.coef_.copy() if fit_intercept: intercept = reg.intercept_ + assert np.sum(coef != 0) > 1 # sample_weight=np.ones(..) should be equivalent to sample_weight=None - sample_weight = np.ones_like(y) + sample_weight = np.ones(n_samples) reg.fit(X, y, sample_weight=sample_weight) assert_allclose(reg.coef_, coef, rtol=1e-6) if fit_intercept: @@ -1485,32 +1528,47 @@ def test_enet_cv_sample_weight_consistency( assert_allclose(reg.intercept_, intercept) # scaling of sample_weight should have no effect, cf. np.average() - sample_weight = 2 * np.ones_like(y) + sample_weight = 2 * np.ones(n_samples) reg.fit(X, y, sample_weight=sample_weight) assert_allclose(reg.coef_, coef, rtol=1e-6) if fit_intercept: assert_allclose(reg.intercept_, intercept) +@pytest.mark.parametrize( + ["estimatorCV", "estimator"], + [ + (ElasticNetCV, ElasticNet), + (MultiTaskElasticNetCV, MultiTaskElasticNet), + ], +) @pytest.mark.parametrize("X_is_sparse", [False, sparse.csc_array, sparse.csc_matrix]) @pytest.mark.parametrize("fit_intercept", [False, True]) @pytest.mark.parametrize("positive", [False, True]) @pytest.mark.parametrize("sample_weight", [np.array([1, 10, 1, 10]), None]) -def test_enet_alpha_max(X_is_sparse, fit_intercept, positive, sample_weight): +def test_enet_alpha_max( + estimatorCV, estimator, X_is_sparse, fit_intercept, positive, sample_weight +): X = np.array([[3.0, -1.0], [2.0, -5.0], [5.0, -3.0], [1.0, -4.0]]) beta = np.array([1, -2]) y = X @ beta params = dict(fit_intercept=fit_intercept, positive=positive) + if issubclass(estimator, MultiTaskElasticNet): + n_tasks = 3 + y = np.tile(y[:, None], reps=(1, n_tasks)) + params.pop("positive") + if positive: + return if X_is_sparse: X = X_is_sparse(X) # Test alpha_max makes coefs zero. - reg = ElasticNetCV(alphas=1, cv=2, eps=1, **params) + reg = estimatorCV(alphas=1, cv=2, eps=1, **params) reg.fit(X, y, sample_weight=sample_weight) assert_allclose(reg.coef_, 0, atol=1e-5) alpha_max = reg.alpha_ # Test smaller alpha makes coefs nonzero. - reg = ElasticNet(alpha=0.99 * alpha_max, tol=1e-8, **params) + reg = estimator(alpha=0.99 * alpha_max, tol=1e-8, **params) reg.fit(X, y, sample_weight=sample_weight) assert_array_less(1e-3, np.max(np.abs(reg.coef_))) @@ -1518,7 +1576,7 @@ def test_enet_alpha_max(X_is_sparse, fit_intercept, positive, sample_weight): # Make sure that the positive constraint changes alpha_max, # i.e. test the meaningfulness of the test data. not_positive_alpha_max = ( - ElasticNetCV(alphas=1, cv=2, eps=1, **{**params, "positive": not positive}) + estimatorCV(alphas=1, cv=2, eps=1, **{**params, "positive": not positive}) .fit(X, y, sample_weight=sample_weight) .alpha_ ) @@ -1542,6 +1600,7 @@ def test_linear_models_cv_fit_with_loky(estimator): estimator(n_jobs=2, cv=3).fit(X, y) +# TODO: @pytest.mark.parametrize("check_input", [True, False]) def test_enet_sample_weight_does_not_overwrite_sample_weight(check_input): """Check that ElasticNet does not overwrite sample_weights.""" @@ -1708,50 +1767,6 @@ def test_cv_estimators_reject_params_with_no_routing_enabled(EstimatorCV): estimator.fit(X, y, groups=groups) -@pytest.mark.parametrize( - "MultiTaskEstimatorCV", - [MultiTaskElasticNetCV, MultiTaskLassoCV], -) -@config_context(enable_metadata_routing=True) -def test_multitask_cv_estimators_with_sample_weight(MultiTaskEstimatorCV): - """Check that for :class:`MultiTaskElasticNetCV` and - class:`MultiTaskLassoCV` if `sample_weight` is passed and the - CV splitter does not support `sample_weight` an error is raised. - On the other hand if the splitter does support `sample_weight` - while `sample_weight` is passed there is no error and process - completes smoothly as before. - """ - - class CVSplitter(GroupsConsumerMixin, BaseCrossValidator): - def get_n_splits(self, X=None, y=None, groups=None, metadata=None): - pass # pragma: nocover - - class CVSplitterSampleWeight(CVSplitter): - def split(self, X, y=None, groups=None, sample_weight=None): - split_index = len(X) // 2 - train_indices = list(range(0, split_index)) - test_indices = list(range(split_index, len(X))) - yield test_indices, train_indices - yield train_indices, test_indices - - X, y = make_regression(random_state=42, n_targets=2) - sample_weight = np.ones(X.shape[0]) - - # If CV splitter does not support sample_weight an error is raised - splitter = CVSplitter().set_split_request(groups=True) - estimator = MultiTaskEstimatorCV(cv=splitter) - msg = "do not support sample weights" - with pytest.raises(ValueError, match=msg): - estimator.fit(X, y, sample_weight=sample_weight) - - # If CV splitter does support sample_weight no error is raised - splitter = CVSplitterSampleWeight().set_split_request( - groups=True, sample_weight=True - ) - estimator = MultiTaskEstimatorCV(cv=splitter) - estimator.fit(X, y, sample_weight=sample_weight) - - # TODO(1.9): remove @pytest.mark.parametrize( "Estimator", [LassoCV, ElasticNetCV, MultiTaskLassoCV, MultiTaskElasticNetCV] From b3f6eebd213147f44c483b9008633951eedf0fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Tue, 14 Apr 2026 16:08:40 +0200 Subject: [PATCH 354/462] MNT Clean-up deprecations for 1.9: force_int_remainder_cols in ColumnTransformer (#33751) --- sklearn/compose/_column_transformer.py | 48 ------------------- .../compose/tests/test_column_transformer.py | 21 -------- 2 files changed, 69 deletions(-) diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index 83455cd9f62bf..b676738768f8c 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -7,7 +7,6 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause -import warnings from collections import Counter from functools import partial from itertools import chain @@ -165,23 +164,6 @@ class ColumnTransformer(TransformerMixin, _BaseComposition): .. versionchanged:: 1.6 `verbose_feature_names_out` can be a callable or a string to be formatted. - force_int_remainder_cols : bool, default=False - This parameter has no effect. - - .. note:: - If you do not access the list of columns for the remainder columns - in the `transformers_` fitted attribute, you do not need to set - this parameter. - - .. versionadded:: 1.5 - - .. versionchanged:: 1.7 - The default value for `force_int_remainder_cols` will change from - `True` to `False` in version 1.7. - - .. deprecated:: 1.7 - `force_int_remainder_cols` is deprecated and will be removed in 1.9. - Attributes ---------- transformers_ : list @@ -300,7 +282,6 @@ class ColumnTransformer(TransformerMixin, _BaseComposition): "transformer_weights": [dict, None], "verbose": ["verbose"], "verbose_feature_names_out": ["boolean", str, callable], - "force_int_remainder_cols": ["boolean", Hidden(StrOptions({"deprecated"}))], } def __init__( @@ -313,7 +294,6 @@ def __init__( transformer_weights=None, verbose=False, verbose_feature_names_out=True, - force_int_remainder_cols="deprecated", ): self.transformers = transformers self.remainder = remainder @@ -322,7 +302,6 @@ def __init__( self.transformer_weights = transformer_weights self.verbose = verbose self.verbose_feature_names_out = verbose_feature_names_out - self.force_int_remainder_cols = force_int_remainder_cols @property def _transformers(self): @@ -980,14 +959,6 @@ def fit_transform(self, X, y=None, **params): """ _raise_for_params(params, self, "fit_transform") - if self.force_int_remainder_cols != "deprecated": - warnings.warn( - "The parameter `force_int_remainder_cols` is deprecated and will be " - "removed in 1.9. It has no effect. Leave it to its default value to " - "avoid this warning.", - FutureWarning, - ) - validate_data(self, X=X, skip_check_array=True) X = _check_X(X) # set n_features_in_ attribute @@ -1360,7 +1331,6 @@ def make_column_transformer( n_jobs=None, verbose=False, verbose_feature_names_out=True, - force_int_remainder_cols="deprecated", ): """Construct a ColumnTransformer from the given transformers. @@ -1433,23 +1403,6 @@ def make_column_transformer( .. versionadded:: 1.0 - force_int_remainder_cols : bool, default=True - This parameter has no effect. - - .. note:: - If you do not access the list of columns for the remainder columns - in the :attr:`ColumnTransformer.transformers_` fitted attribute, - you do not need to set this parameter. - - .. versionadded:: 1.5 - - .. versionchanged:: 1.7 - The default value for `force_int_remainder_cols` will change from - `True` to `False` in version 1.7. - - .. deprecated:: 1.7 - `force_int_remainder_cols` is deprecated and will be removed in version 1.9. - Returns ------- ct : ColumnTransformer @@ -1483,7 +1436,6 @@ def make_column_transformer( sparse_threshold=sparse_threshold, verbose=verbose, verbose_feature_names_out=verbose_feature_names_out, - force_int_remainder_cols=force_int_remainder_cols, ) diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index 76f70d5c2b51b..d633d6f890bdd 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -814,7 +814,6 @@ def test_column_transformer_get_set_params(): "transformer_weights": None, "verbose_feature_names_out": True, "verbose": False, - "force_int_remainder_cols": "deprecated", } assert ct.get_params() == exp @@ -836,7 +835,6 @@ def test_column_transformer_get_set_params(): "transformer_weights": None, "verbose_feature_names_out": True, "verbose": False, - "force_int_remainder_cols": "deprecated", } assert ct.get_params() == exp @@ -996,23 +994,6 @@ def test_column_transformer_remainder_dtypes(cols1, cols2, expected_remainder_co assert ct.transformers_[-1][-1] == expected_remainder_cols -# TODO(1.9): remove this test -@pytest.mark.parametrize("force_int_remainder_cols", [True, False]) -def test_force_int_remainder_cols_deprecation(force_int_remainder_cols): - """Check that ColumnTransformer raises a FutureWarning when - force_int_remainder_cols is set. - """ - X = np.ones((1, 3)) - ct = ColumnTransformer( - [("T1", Trans(), [0]), ("T2", Trans(), [1])], - remainder="passthrough", - force_int_remainder_cols=force_int_remainder_cols, - ) - - with pytest.warns(FutureWarning, match="`force_int_remainder_cols` is deprecated"): - ct.fit(X) - - @pytest.mark.parametrize( "key, expected_cols", [ @@ -1196,7 +1177,6 @@ def test_column_transformer_get_set_params_with_remainder(): "transformer_weights": None, "verbose_feature_names_out": True, "verbose": False, - "force_int_remainder_cols": "deprecated", } assert ct.get_params() == exp @@ -1217,7 +1197,6 @@ def test_column_transformer_get_set_params_with_remainder(): "transformer_weights": None, "verbose_feature_names_out": True, "verbose": False, - "force_int_remainder_cols": "deprecated", } assert ct.get_params() == exp From 64817509bae5149b912cbc0170a053721258ce45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Tue, 14 Apr 2026 16:17:53 +0200 Subject: [PATCH 355/462] MNT Clean up deprecations for 1.9: base_estimator arg in _BaseChain and ClassifierChain (#33750) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- sklearn/multioutput.py | 74 +++++-------------------------- sklearn/tests/test_multioutput.py | 16 ------- 2 files changed, 12 insertions(+), 78 deletions(-) diff --git a/sklearn/multioutput.py b/sklearn/multioutput.py index 6ab030c5ae02c..18b2ddcc3e1a7 100644 --- a/sklearn/multioutput.py +++ b/sklearn/multioutput.py @@ -8,7 +8,6 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause -import warnings from abc import ABCMeta, abstractmethod from numbers import Integral @@ -26,7 +25,7 @@ ) from sklearn.model_selection import cross_val_predict from sklearn.utils import Bunch, check_random_state, get_tags -from sklearn.utils._param_validation import HasMethods, Hidden, StrOptions +from sklearn.utils._param_validation import HasMethods, StrOptions from sklearn.utils._response import _get_response_values from sklearn.utils._sparse import _align_api_if_sparse from sklearn.utils._user_interface import _print_elapsed_time @@ -623,13 +622,13 @@ def __sklearn_tags__(self): def _available_if_base_estimator_has(attr): - """Return a function to check if `base_estimator` or `estimators_` has `attr`. + """Return a function to check if `estimator` or `estimators_` has `attr`. Helper for Chain implementations. """ def _check(self): - return hasattr(self._get_estimator(), attr) or all( + return hasattr(self.estimator, attr) or all( hasattr(est, attr) for est in self.estimators_ ) @@ -638,60 +637,28 @@ def _check(self): class _BaseChain(BaseEstimator, metaclass=ABCMeta): _parameter_constraints: dict = { - "base_estimator": [ - HasMethods(["fit", "predict"]), - StrOptions({"deprecated"}), - ], - "estimator": [ - HasMethods(["fit", "predict"]), - Hidden(None), - ], + "estimator": [HasMethods(["fit", "predict"])], "order": ["array-like", StrOptions({"random"}), None], "cv": ["cv_object", StrOptions({"prefit"})], "random_state": ["random_state"], "verbose": ["boolean"], } - # TODO(1.9): Remove base_estimator def __init__( self, - estimator=None, + estimator, *, order=None, cv=None, random_state=None, verbose=False, - base_estimator="deprecated", ): self.estimator = estimator - self.base_estimator = base_estimator self.order = order self.cv = cv self.random_state = random_state self.verbose = verbose - # TODO(1.9): This is a temporary getter method to validate input wrt deprecation. - # It was only included to avoid relying on the presence of self.estimator_ - def _get_estimator(self): - """Get and validate estimator.""" - - if self.estimator is not None and (self.base_estimator != "deprecated"): - raise ValueError( - "Both `estimator` and `base_estimator` are provided. You should only" - " pass `estimator`. `base_estimator` as a parameter is deprecated in" - " version 1.7, and will be removed in version 1.9." - ) - - if self.base_estimator != "deprecated": - warning_msg = ( - "`base_estimator` as an argument was deprecated in 1.7 and will be" - " removed in 1.9. Use `estimator` instead." - ) - warnings.warn(warning_msg, FutureWarning) - return self.base_estimator - else: - return self.estimator - def _log_message(self, *, estimator_idx, n_estimators, processing_msg): if not self.verbose: return None @@ -774,7 +741,7 @@ def fit(self, X, Y, **fit_params): elif sorted(self.order_) != list(range(Y.shape[1])): raise ValueError("invalid order") - self.estimators_ = [clone(self._get_estimator()) for _ in range(Y.shape[1])] + self.estimators_ = [clone(self.estimator) for _ in range(Y.shape[1])] if self.cv is None: Y_pred_chain = Y[:, self.order_] @@ -813,7 +780,7 @@ def fit(self, X, Y, **fit_params): if hasattr(self, "chain_method"): chain_method = _check_response_method( - self._get_estimator(), + self.estimator, self.chain_method, ).__name__ self.chain_method_ = chain_method @@ -838,7 +805,7 @@ def fit(self, X, Y, **fit_params): if self.cv is not None and chain_idx < len(self.estimators_) - 1: col_idx = X.shape[1] + chain_idx cv_result = cross_val_predict( - self._get_estimator(), + self.estimator, X_aug[:, :col_idx], y=y, cv=self.cv, @@ -871,7 +838,7 @@ def predict(self, X): def __sklearn_tags__(self): tags = super().__sklearn_tags__() - tags.input_tags.sparse = get_tags(self._get_estimator()).input_tags.sparse + tags.input_tags.sparse = get_tags(self.estimator).input_tags.sparse return tags @@ -950,13 +917,6 @@ class ClassifierChain(MetaEstimatorMixin, ClassifierMixin, _BaseChain): .. versionadded:: 1.2 - base_estimator : estimator, default="deprecated" - Use `estimator` instead. - - .. deprecated:: 1.7 - `base_estimator` is deprecated and will be removed in 1.9. - Use `estimator` instead. - Attributes ---------- classes_ : list @@ -1031,17 +991,15 @@ class labels for each estimator in the chain. ], } - # TODO(1.9): Remove base_estimator from __init__ def __init__( self, - estimator=None, + estimator, *, order=None, cv=None, chain_method="predict", random_state=None, verbose=False, - base_estimator="deprecated", ): super().__init__( estimator, @@ -1049,7 +1007,6 @@ def __init__( cv=cv, random_state=random_state, verbose=verbose, - base_estimator=base_estimator, ) self.chain_method = chain_method @@ -1151,7 +1108,7 @@ def get_metadata_routing(self): """ router = MetadataRouter(owner=self).add( - estimator=self._get_estimator(), + estimator=self.estimator, method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) return router @@ -1222,13 +1179,6 @@ class RegressorChain(MetaEstimatorMixin, RegressorMixin, _BaseChain): .. versionadded:: 1.2 - base_estimator : estimator, default="deprecated" - Use `estimator` instead. - - .. deprecated:: 1.7 - `base_estimator` is deprecated and will be removed in 1.9. - Use `estimator` instead. - Attributes ---------- estimators_ : list @@ -1313,7 +1263,7 @@ def get_metadata_routing(self): """ router = MetadataRouter(owner=self).add( - estimator=self._get_estimator(), + estimator=self.estimator, method_mapping=MethodMapping().add(caller="fit", callee="fit"), ) return router diff --git a/sklearn/tests/test_multioutput.py b/sklearn/tests/test_multioutput.py index 83c35bb3a626b..a6d9ceb33df89 100644 --- a/sklearn/tests/test_multioutput.py +++ b/sklearn/tests/test_multioutput.py @@ -865,19 +865,3 @@ def test_multioutput_regressor_has_partial_fit(): msg = "This 'MultiOutputRegressor' has no attribute 'partial_fit'" with pytest.raises(AttributeError, match=msg): getattr(est, "partial_fit") - - -# TODO(1.9): remove when deprecated `base_estimator` is removed -@pytest.mark.parametrize("Estimator", [ClassifierChain, RegressorChain]) -def test_base_estimator_deprecation(Estimator): - """Check that we warn about the deprecation of `base_estimator`.""" - X = np.array([[1, 2], [3, 4]]) - y = np.array([[1, 0], [0, 1]]) - - estimator = LogisticRegression() - - with pytest.warns(FutureWarning): - Estimator(base_estimator=estimator).fit(X, y) - - with pytest.raises(ValueError): - Estimator(base_estimator=estimator, estimator=estimator).fit(X, y) From e0a0a23e304374d0bbfd658fd5e0519cc8f75168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Tue, 14 Apr 2026 16:26:18 +0200 Subject: [PATCH 356/462] MNT Clean-up deprecations for 1.9: n_aplhas in LinearModelCV (#33753) --- sklearn/linear_model/_coordinate_descent.py | 122 ++--------------- .../tests/test_coordinate_descent.py | 127 ------------------ 2 files changed, 13 insertions(+), 236 deletions(-) diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index d66ee2063af3b..f704f6af052cc 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -28,7 +28,6 @@ _raise_for_params, ) from sklearn.utils._param_validation import ( - Hidden, Interval, StrOptions, validate_params, @@ -1581,16 +1580,9 @@ class LinearModelCV(MultiOutputLinearModel, ABC): _parameter_constraints: dict = { "eps": [Interval(Real, 0, None, closed="neither")], - "n_alphas": [ - Interval(Integral, 1, None, closed="left"), - Hidden(StrOptions({"deprecated"})), - ], - # TODO(1.9): remove "warn" and None options. "alphas": [ Interval(Integral, 1, None, closed="left"), "array-like", - None, - Hidden(StrOptions({"warn"})), ], "fit_intercept": ["boolean"], "precompute": [StrOptions({"auto"}), "array-like", "boolean"], @@ -1609,8 +1601,7 @@ class LinearModelCV(MultiOutputLinearModel, ABC): def __init__( self, eps=1e-3, - n_alphas="deprecated", - alphas="warn", + alphas=100, fit_intercept=True, precompute="auto", max_iter=1000, @@ -1624,7 +1615,6 @@ def __init__( selection="cyclic", ): self.eps = eps - self.n_alphas = n_alphas self.alphas = alphas self.fit_intercept = fit_intercept self.precompute = precompute @@ -1692,40 +1682,6 @@ def fit(self, X, y, sample_weight=None, **params): """ _raise_for_params(params, self, "fit") - # TODO(1.9): remove n_alphas and alphas={"warn", None}; set alphas=100 by - # default. Remove these deprecations messages and use self.alphas directly - # instead of self._alphas. - if self.n_alphas == "deprecated": - self._alphas = 100 - else: - warnings.warn( - "'n_alphas' was deprecated in 1.7 and will be removed in 1.9. " - "'alphas' now accepts an integer value which removes the need to pass " - "'n_alphas'. The default value of 'alphas' will change from None to " - "100 in 1.9. Pass an explicit value to 'alphas' and leave 'n_alphas' " - "to its default value to silence this warning.", - FutureWarning, - ) - self._alphas = self.n_alphas - - if isinstance(self.alphas, str) and self.alphas == "warn": - # - If self.n_alphas == "deprecated", both are left to their default values - # so we don't warn since the future default behavior will be the same as - # the current default behavior. - # - If self.n_alphas != "deprecated", then we already warned about it - # and the warning message mentions the future self.alphas default, so - # no need to warn a second time. - pass - elif self.alphas is None: - warnings.warn( - "'alphas=None' is deprecated and will be removed in 1.9, at which " - "point the default value will be set to 100. Set 'alphas=100' " - "to silence this warning.", - FutureWarning, - ) - else: - self._alphas = self.alphas - # This makes sure that there is no duplication in memory. # Dealing right with copy_X is important in the following: # Multiple functions touch X and subsamples of X and can induce a @@ -1831,7 +1787,7 @@ def fit(self, X, y, sample_weight=None, **params): include_boundaries="left", ) - if isinstance(self._alphas, Integral): + if isinstance(self.alphas, Integral): alphas = [ _alpha_grid( X, @@ -1841,17 +1797,17 @@ def fit(self, X, y, sample_weight=None, **params): # Note: MultiTaskElasticNetCV has no attribute 'positive' positive=getattr(self, "positive", False), eps=self.eps, - n_alphas=self._alphas, + n_alphas=self.alphas, sample_weight=sample_weight, ) for l1_ratio in l1_ratios ] else: # Making sure alphas entries are scalars. - for index, alpha in enumerate(self._alphas): + for index, alpha in enumerate(self.alphas): check_scalar_alpha(alpha, f"alphas[{index}]") # Making sure alphas is properly ordered. - alphas = np.tile(np.sort(self._alphas)[::-1], (n_l1_ratio, 1)) + alphas = np.tile(np.sort(self.alphas)[::-1], (n_l1_ratio, 1)) # We want n_alphas to be the number of alphas used for each l1_ratio. n_alphas = len(alphas[0]) @@ -1920,7 +1876,7 @@ def fit(self, X, y, sample_weight=None, **params): self.l1_ratio_ = best_l1_ratio self.alpha_ = best_alpha - if isinstance(self._alphas, Integral): + if isinstance(self.alphas, Integral): self.alphas_ = np.asarray(alphas) if n_l1_ratio == 1: self.alphas_ = self.alphas_[0] @@ -2008,14 +1964,7 @@ class LassoCV(RegressorMixin, LinearModelCV): Length of the path. ``eps=1e-3`` means that ``alpha_min / alpha_max = 1e-3``. - n_alphas : int, default=100 - Number of alphas along the regularization path. - - .. deprecated:: 1.7 - `n_alphas` was deprecated in 1.7 and will be removed in 1.9. Use `alphas` - instead. - - alphas : array-like or int, default=None + alphas : array-like or int, default=100 Values of alphas to test along the regularization path. If int, `alphas` values are generated automatically. If array-like, list of alpha values to use. @@ -2024,10 +1973,6 @@ class LassoCV(RegressorMixin, LinearModelCV): `alphas` accepts an integer value which removes the need to pass `n_alphas`. - .. deprecated:: 1.7 - `alphas=None` was deprecated in 1.7 and will be removed in 1.9, at which - point the default value will be set to 100. - fit_intercept : bool, default=True Whether to calculate the intercept for this model. If set to false, no intercept will be used in calculations @@ -2178,8 +2123,7 @@ def __init__( self, *, eps=1e-3, - n_alphas="deprecated", - alphas="warn", + alphas=100, fit_intercept=True, precompute="auto", max_iter=1000, @@ -2194,7 +2138,6 @@ def __init__( ): super().__init__( eps=eps, - n_alphas=n_alphas, alphas=alphas, fit_intercept=fit_intercept, precompute=precompute, @@ -2281,14 +2224,7 @@ class ElasticNetCV(RegressorMixin, LinearModelCV): Length of the path. ``eps=1e-3`` means that ``alpha_min / alpha_max = 1e-3``. - n_alphas : int, default=100 - Number of alphas along the regularization path, used for each l1_ratio. - - .. deprecated:: 1.7 - `n_alphas` was deprecated in 1.7 and will be removed in 1.9. Use `alphas` - instead. - - alphas : array-like or int, default=None + alphas : array-like or int, default=100 Values of alphas to test along the regularization path, used for each l1_ratio. If int, `alphas` values are generated automatically. If array-like, list of alpha values to use. @@ -2297,10 +2233,6 @@ class ElasticNetCV(RegressorMixin, LinearModelCV): `alphas` accepts an integer value which removes the need to pass `n_alphas`. - .. deprecated:: 1.7 - `alphas=None` was deprecated in 1.7 and will be removed in 1.9, at which - point the default value will be set to 100. - fit_intercept : bool, default=True Whether to calculate the intercept for this model. If set to false, no intercept will be used in calculations @@ -2470,8 +2402,7 @@ def __init__( *, l1_ratio=0.5, eps=1e-3, - n_alphas="deprecated", - alphas="warn", + alphas=100, fit_intercept=True, precompute="auto", max_iter=1000, @@ -2486,7 +2417,6 @@ def __init__( ): self.l1_ratio = l1_ratio self.eps = eps - self.n_alphas = n_alphas self.alphas = alphas self.fit_intercept = fit_intercept self.precompute = precompute @@ -3034,14 +2964,7 @@ class MultiTaskElasticNetCV(RegressorMixin, LinearModelCV): Length of the path. ``eps=1e-3`` means that ``alpha_min / alpha_max = 1e-3``. - n_alphas : int, default=100 - Number of alphas along the regularization path. - - .. deprecated:: 1.7 - `n_alphas` was deprecated in 1.7 and will be removed in 1.9. Use `alphas` - instead. - - alphas : array-like or int, default=None + alphas : array-like or int, default=100 Values of alphas to test along the regularization path, used for each l1_ratio. If int, `alphas` values are generated automatically. If array-like, list of alpha values to use. @@ -3050,10 +2973,6 @@ class MultiTaskElasticNetCV(RegressorMixin, LinearModelCV): `alphas` accepts an integer value which removes the need to pass `n_alphas`. - .. deprecated:: 1.7 - `alphas=None` was deprecated in 1.7 and will be removed in 1.9, at which - point the default value will be set to 100. - fit_intercept : bool, default=True Whether to calculate the intercept for this model. If set to false, no intercept will be used in calculations @@ -3195,8 +3114,7 @@ def __init__( *, l1_ratio=0.5, eps=1e-3, - n_alphas="deprecated", - alphas="warn", + alphas=100, fit_intercept=True, max_iter=1000, tol=1e-4, @@ -3209,7 +3127,6 @@ def __init__( ): self.l1_ratio = l1_ratio self.eps = eps - self.n_alphas = n_alphas self.alphas = alphas self.fit_intercept = fit_intercept self.max_iter = max_iter @@ -3253,13 +3170,6 @@ class MultiTaskLassoCV(RegressorMixin, LinearModelCV): Length of the path. ``eps=1e-3`` means that ``alpha_min / alpha_max = 1e-3``. - n_alphas : int, default=100 - Number of alphas along the regularization path. - - .. deprecated:: 1.7 - `n_alphas` was deprecated in 1.7 and will be removed in 1.9. Use `alphas` - instead. - alphas : array-like or int, default=None Values of alphas to test along the regularization path. If int, `alphas` values are generated automatically. @@ -3269,10 +3179,6 @@ class MultiTaskLassoCV(RegressorMixin, LinearModelCV): `alphas` accepts an integer value which removes the need to pass `n_alphas`. - .. deprecated:: 1.7 - `alphas=None` was deprecated in 1.7 and will be removed in 1.9, at which - point the default value will be set to 100. - fit_intercept : bool, default=True Whether to calculate the intercept for this model. If set to false, no intercept will be used in calculations @@ -3410,8 +3316,7 @@ def __init__( self, *, eps=1e-3, - n_alphas="deprecated", - alphas="warn", + alphas=100, fit_intercept=True, max_iter=1000, tol=1e-4, @@ -3424,7 +3329,6 @@ def __init__( ): super().__init__( eps=eps, - n_alphas=n_alphas, alphas=alphas, fit_intercept=fit_intercept, max_iter=max_iter, diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index 3bdc991887ecc..4c23e72cbfb58 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -1767,133 +1767,6 @@ def test_cv_estimators_reject_params_with_no_routing_enabled(EstimatorCV): estimator.fit(X, y, groups=groups) -# TODO(1.9): remove -@pytest.mark.parametrize( - "Estimator", [LassoCV, ElasticNetCV, MultiTaskLassoCV, MultiTaskElasticNetCV] -) -def test_linear_model_cv_deprecated_n_alphas(Estimator): - """Check the deprecation of n_alphas in favor of alphas.""" - X, y = make_regression(n_targets=2, random_state=42) - - # Asses warning message raised by LinearModelCV when n_alphas is used - with pytest.warns( - FutureWarning, - match="'n_alphas' was deprecated in 1.7 and will be removed in 1.9", - ): - clf = Estimator(n_alphas=5) - if clf._is_multitask(): - clf = clf.fit(X, y) - else: - clf = clf.fit(X, y[:, 0]) - - # Asses no warning message raised when n_alphas is not used - with warnings.catch_warnings(): - warnings.simplefilter("error") - clf = Estimator(alphas=5) - if clf._is_multitask(): - clf = clf.fit(X, y) - else: - clf = clf.fit(X, y[:, 0]) - - -# TODO(1.9): remove -@pytest.mark.parametrize( - "Estimator", [ElasticNetCV, LassoCV, MultiTaskLassoCV, MultiTaskElasticNetCV] -) -def test_linear_model_cv_deprecated_alphas_none(Estimator): - """Check the deprecation of alphas=None.""" - X, y = make_regression(n_targets=2, random_state=42) - - with pytest.warns( - FutureWarning, match="'alphas=None' is deprecated and will be removed in 1.9" - ): - clf = Estimator(alphas=None) - if clf._is_multitask(): - clf.fit(X, y) - else: - clf.fit(X, y[:, 0]) - - -# TODO(1.9): remove -@pytest.mark.filterwarnings("ignore:.*with no regularization.*:UserWarning") -@pytest.mark.parametrize( - "Estimator", [ElasticNetCV, LassoCV, MultiTaskLassoCV, MultiTaskElasticNetCV] -) -def test_linear_model_cv_alphas_n_alphas_unset(Estimator): - """Check that no warning is raised when both n_alphas and alphas are unset.""" - X, y = make_regression(n_targets=2, random_state=42) - - # Asses no warning message raised when n_alphas is not used - with warnings.catch_warnings(): - warnings.simplefilter("error") - clf = Estimator() - if clf._is_multitask(): - clf = clf.fit(X, y) - else: - clf = clf.fit(X, y[:, 0]) - - -# TODO(1.9): remove -@pytest.mark.filterwarnings("ignore:'n_alphas' was deprecated in 1.7") -@pytest.mark.filterwarnings( - "ignore:With alpha=0, this algorithm does not converge well.*:UserWarning" -) -@pytest.mark.parametrize( - "Estimator", [ElasticNetCV, LassoCV, MultiTaskLassoCV, MultiTaskElasticNetCV] -) -def test_linear_model_cv_alphas(Estimator): - """Check that the behavior of alphas is consistent with n_alphas.""" - X, y = make_regression(n_targets=2, random_state=42) - - # n_alphas is set, alphas is not => n_alphas is used - clf = Estimator(n_alphas=5) - if clf._is_multitask(): - clf.fit(X, y) - else: - clf.fit(X, y[:, 0]) - assert len(clf.alphas_) == 5 - - # n_alphas is set, alphas is set => alphas has priority - clf = Estimator(n_alphas=5, alphas=10) - if clf._is_multitask(): - clf.fit(X, y) - else: - clf.fit(X, y[:, 0]) - assert len(clf.alphas_) == 10 - - # same with alphas array-like - clf = Estimator(n_alphas=5, alphas=np.arange(10)) - if clf._is_multitask(): - clf.fit(X, y) - else: - clf.fit(X, y[:, 0]) - assert len(clf.alphas_) == 10 - - # n_alphas is not set, alphas is set => alphas is used - clf = Estimator(alphas=10) - if clf._is_multitask(): - clf.fit(X, y) - else: - clf.fit(X, y[:, 0]) - assert len(clf.alphas_) == 10 - - # same with alphas array-like - clf = Estimator(alphas=np.arange(10)) - if clf._is_multitask(): - clf.fit(X, y) - else: - clf.fit(X, y[:, 0]) - assert len(clf.alphas_) == 10 - - # both are not set => default = 100 - clf = Estimator() - if clf._is_multitask(): - clf.fit(X, y) - else: - clf.fit(X, y[:, 0]) - assert len(clf.alphas_) == 100 - - @pytest.mark.parametrize("precompute", ["auto", True, False]) def test_enet_path_check_input_false(precompute): """Test enet_path works with check_input=False and various precompute settings.""" From e56d43fdeaa5af7f8c707de15dc2e4a8f1b50867 Mon Sep 17 00:00:00 2001 From: antoinebaker <antoinebaker@users.noreply.github.com> Date: Wed, 15 Apr 2026 12:50:12 +0200 Subject: [PATCH 357/462] FIX Expose `cond` of lstsq solver as `tol` in `LinearRegression` (#33565) Co-authored-by: Christian Lorentzen <lorentzen.ch@gmail.com> --- .../sklearn.linear_model/33565.fix.rst | 6 +++++ sklearn/linear_model/_base.py | 16 ++++++------ sklearn/linear_model/tests/test_base.py | 25 +++++++++++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33565.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33565.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33565.fix.rst new file mode 100644 index 0000000000000..73d3b0b61bbf5 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33565.fix.rst @@ -0,0 +1,6 @@ +- The `tol` parameter in :class:`linear_model.LinearRegression` is now set as + the `cond` parameter of the :func:`scipy.linalg.lstsq` solver when fitting on + dense data. Some tests involving `LinearRegression` were brittle with the + default `cond` values from `scipy` or `numpy`. Here at least the user has + control over the `cond` value and can change it if necessary. + By :user:`Antoine Baker <antoinebaker>` diff --git a/sklearn/linear_model/_base.py b/sklearn/linear_model/_base.py index 01b2205b6479b..2c5fa660df74e 100644 --- a/sklearn/linear_model/_base.py +++ b/sklearn/linear_model/_base.py @@ -527,12 +527,14 @@ class LinearRegression(RegressorMixin, MultiOutputLinearModel): tol : float, default=1e-6 The precision of the solution (`coef_`) is determined by `tol` which - specifies a different convergence criterion for the `lsqr` solver. - `tol` is set as `atol` and `btol` of :func:`scipy.sparse.linalg.lsqr` when - fitting on sparse training data. This parameter has no effect when fitting - on dense data. + specifies the convergence criterion of the underlying solver. `tol` is + set as `atol` and `btol` of :func:`scipy.sparse.linalg.lsqr` when + fitting on sparse training data. `tol` is set as `cond` of + :func:`scipy.linalg.lstsq` when fitting on dense training data. .. versionadded:: 1.7 + .. versionchanged:: 1.9 + Now supported on dense data, interpreted as the `cond` parameter. n_jobs : int, default=None The number of jobs to use for the computation. This will only provide @@ -738,9 +740,9 @@ def rmatvec(b): ) self.coef_ = np.vstack([out[0] for out in outs]) else: - # cut-off ratio for small singular values - cond = max(X.shape) * np.finfo(X.dtype).eps - self.coef_, _, self.rank_, self.singular_ = linalg.lstsq(X, y, cond=cond) + self.coef_, _, self.rank_, self.singular_ = linalg.lstsq( + X, y, cond=self.tol + ) self.coef_ = self.coef_.T if y.ndim == 1: diff --git a/sklearn/linear_model/tests/test_base.py b/sklearn/linear_model/tests/test_base.py index a82171228ac1e..737df13fc2cf9 100644 --- a/sklearn/linear_model/tests/test_base.py +++ b/sklearn/linear_model/tests/test_base.py @@ -60,6 +60,31 @@ def test_linear_regression(): assert_array_almost_equal(reg.predict(X), [0]) +@pytest.mark.parametrize("dtype", [np.float64, np.float32]) +def test_linear_regression_vs_lstsq(dtype): + """ + Check that LinearRegression is as good as `scipy.linalg.lstsq`. + Non regression test for issue #33032. + """ + rng = np.random.RandomState(1137) + n_samples = 500_000 + + x1 = rng.rand(n_samples) + x2 = 0.3 * x1 + 0.1 * rng.rand(n_samples) + X = np.column_stack([x1, x2]) + y = X @ [0.5, 2.0] + 0.1 * rng.rand(n_samples) + + X = X.astype(dtype) + y = y.astype(dtype) + + coef_scipy = linalg.lstsq(X, y)[0] + coef_sklearn = LinearRegression(fit_intercept=False).fit(X, y).coef_ + + rmse_scipy = np.linalg.norm(y - X @ coef_scipy) + rmse_sklearn = np.linalg.norm(y - X @ coef_sklearn) + assert rmse_sklearn == pytest.approx(rmse_scipy, rel=1e-6) + + @pytest.mark.parametrize("sparse_container", [None] + CSR_CONTAINERS) @pytest.mark.parametrize("fit_intercept", [True, False]) def test_linear_regression_sample_weights( From 304cc637d4ae93332375101d95dd2b1bc0b22195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Wed, 15 Apr 2026 14:54:45 +0200 Subject: [PATCH 358/462] MNT Clean-up deprecations for 1.9: raise_warning in class_likelihood_ratios (#33756) --- sklearn/metrics/_classification.py | 70 ++++++-------------- sklearn/metrics/tests/test_classification.py | 13 ---- 2 files changed, 20 insertions(+), 63 deletions(-) diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 316dcc5711862..899d1afaaadea 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -47,7 +47,6 @@ xpx, ) from sklearn.utils._param_validation import ( - Hidden, Interval, Options, StrOptions, @@ -2230,7 +2229,6 @@ def precision_recall_fscore_support( "y_pred": ["array-like", "sparse matrix"], "labels": ["array-like", None], "sample_weight": ["array-like", None], - "raise_warning": ["boolean", Hidden(StrOptions({"deprecated"}))], "replace_undefined_by": [ Options(Real, {1.0, np.nan}), dict, @@ -2244,7 +2242,6 @@ def class_likelihood_ratios( *, labels=None, sample_weight=None, - raise_warning="deprecated", replace_undefined_by=np.nan, ): """Compute binary classification positive and negative likelihood ratios. @@ -2302,15 +2299,6 @@ class after being classified as negative. This is the case when the sample_weight : array-like of shape (n_samples,), default=None Sample weights. - raise_warning : bool, default=True - Whether or not a case-specific warning message is raised when there is division - by zero. - - .. deprecated:: 1.7 - `raise_warning` was deprecated in version 1.7 and will be removed in 1.9, - when an :class:`~sklearn.exceptions.UndefinedMetricWarning` will always - raise in case of a division by zero. - replace_undefined_by : np.nan, 1.0, or dict, default=np.nan Sets the return values for LR+ and LR- when there is a division by zero. Can take the following values: @@ -2340,10 +2328,8 @@ class after being classified as negative. This is the case when the Raises :class:`~sklearn.exceptions.UndefinedMetricWarning` when `y_true` and `y_pred` lead to the following conditions: - - The number of false positives is 0 and `raise_warning` is set to `True` - (default): positive likelihood ratio is undefined. - - The number of true negatives is 0 and `raise_warning` is set to `True` - (default): negative likelihood ratio is undefined. + - The number of false positives is 0: positive likelihood ratio is undefined. + - The number of true negatives is 0: negative likelihood ratio is undefined. - The sum of true positives and false negatives is 0 (no samples of the positive class are present in `y_true`): both likelihood ratios are undefined. @@ -2378,10 +2364,6 @@ class are present in `y_true`): both likelihood ratios are undefined. >>> class_likelihood_ratios(y_true, y_pred, labels=["non-cat", "cat"]) (1.5, 0.75) """ - # TODO(1.9): When `raise_warning` is removed, the following changes need to be made: - # The checks for `raise_warning==True` need to be removed and we will always warn, - # remove `FutureWarning`, and the Warns section in the docstring should not mention - # `raise_warning` anymore. y_true, y_pred = attach_unique(y_true, y_pred) y_type, y_true, y_pred, sample_weight = _check_targets( y_true, y_pred, sample_weight @@ -2392,16 +2374,6 @@ class are present in `y_true`): both likelihood ratios are undefined. f"problems, got targets of type: {y_type}" ) - msg_deprecated_param = ( - "`raise_warning` was deprecated in version 1.7 and will be removed in 1.9. An " - "`UndefinedMetricWarning` will always be raised in case of a division by zero " - "and the value set with the `replace_undefined_by` param will be returned." - ) - if raise_warning != "deprecated": - warnings.warn(msg_deprecated_param, FutureWarning) - else: - raise_warning = True - if replace_undefined_by == 1.0: replace_undefined_by = {"LR+": 1.0, "LR-": 1.0} @@ -2466,18 +2438,17 @@ class are present in `y_true`): both likelihood ratios are undefined. # if `fp == 0`a division by zero will occur if fp == 0: - if raise_warning: - if tp == 0: - msg_beginning = ( - "No samples were predicted for the positive class and " - "`positive_likelihood_ratio` is " - ) - else: - msg_beginning = "`positive_likelihood_ratio` is ill-defined and " - msg_end = "set to `np.nan`. Use the `replace_undefined_by` param to " - "control this behavior. To suppress this warning or turn it into an error, " - "see Python's `warnings` module and `warnings.catch_warnings()`." - warnings.warn(msg_beginning + msg_end, UndefinedMetricWarning, stacklevel=2) + if tp == 0: + msg_beginning = ( + "No samples were predicted for the positive class and " + "`positive_likelihood_ratio` is " + ) + else: + msg_beginning = "`positive_likelihood_ratio` is ill-defined and " + msg_end = "set to `np.nan`. Use the `replace_undefined_by` param to " + "control this behavior. To suppress this warning or turn it into an error, " + "see Python's `warnings` module and `warnings.catch_warnings()`." + warnings.warn(msg_beginning + msg_end, UndefinedMetricWarning, stacklevel=2) if isinstance(replace_undefined_by, float) and np.isnan(replace_undefined_by): positive_likelihood_ratio = replace_undefined_by else: @@ -2490,14 +2461,13 @@ class are present in `y_true`): both likelihood ratios are undefined. # if `tn == 0`a division by zero will occur if tn == 0: - if raise_warning: - msg = ( - "`negative_likelihood_ratio` is ill-defined and set to `np.nan`. " - "Use the `replace_undefined_by` param to control this behavior. To " - "suppress this warning or turn it into an error, see Python's " - "`warnings` module and `warnings.catch_warnings()`." - ) - warnings.warn(msg, UndefinedMetricWarning, stacklevel=2) + msg = ( + "`negative_likelihood_ratio` is ill-defined and set to `np.nan`. " + "Use the `replace_undefined_by` param to control this behavior. To " + "suppress this warning or turn it into an error, see Python's " + "`warnings` module and `warnings.catch_warnings()`." + ) + warnings.warn(msg, UndefinedMetricWarning, stacklevel=2) if isinstance(replace_undefined_by, float) and np.isnan(replace_undefined_by): negative_likelihood_ratio = replace_undefined_by else: diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index 850dc3da2dd60..c561470f8bda5 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -749,19 +749,6 @@ def test_likelihood_ratios(): assert_allclose(neg, 12 / 27) -# TODO(1.9): remove test -@pytest.mark.parametrize("raise_warning", [True, False]) -def test_likelihood_ratios_raise_warning_deprecation(raise_warning): - """Test that class_likelihood_ratios raises a `FutureWarning` when `raise_warning` - param is set.""" - y_true = np.array([1, 0]) - y_pred = np.array([1, 0]) - - msg = "`raise_warning` was deprecated in version 1.7 and will be removed in 1.9." - with pytest.warns(FutureWarning, match=msg): - class_likelihood_ratios(y_true, y_pred, raise_warning=raise_warning) - - def test_likelihood_ratios_replace_undefined_by_worst(): """Test that class_likelihood_ratios returns the worst scores `1.0` for both LR+ and LR- when `replace_undefined_by=1` is set.""" From 54a64238550fc44f36f0566be7eeb379796e8968 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Wed, 15 Apr 2026 15:00:02 +0200 Subject: [PATCH 359/462] ENH DecisionBoundaryDisplay: change default colors and sampling (#33709) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.inspection/33709.enhancement.rst | 4 + sklearn/inspection/_plot/decision_boundary.py | 74 +++++++++++-------- .../tests/test_boundary_decision_display.py | 13 ++-- sklearn/utils/fixes.py | 18 ++++- 4 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.inspection/33709.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.inspection/33709.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.inspection/33709.enhancement.rst new file mode 100644 index 0000000000000..3de50488d0db0 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.inspection/33709.enhancement.rst @@ -0,0 +1,4 @@ +- In :class:`inspection.DecisionBoundaryDisplay`, `multiclass_colors` now defaults to + the more accessible [Petroff color sequence](https://arxiv.org/abs/2107.02270) for + multiclass problems with up to 10 classes. + By :user:`Anne Beyer <AnneBeyer>`. diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index 20adb4d16332a..3c0ca7468dd9f 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -12,6 +12,7 @@ from sklearn.utils._optional_dependencies import check_matplotlib_support from sklearn.utils._response import _get_response_values from sklearn.utils._set_output import _get_adapter_from_container +from sklearn.utils.fixes import PETROFF_COLORS from sklearn.utils.multiclass import type_of_target from sklearn.utils.validation import ( _is_arraylike_not_scalar, @@ -62,26 +63,36 @@ def _select_colors(mpl, multiclass_colors, n_classes): mpl : module Imported `matplotlib` module. - multiclass_colors : list of color-like, str, or None - Color specification for multiclass plots. + multiclass_colors : str or list of matplotlib colors, default=None + The colormap or colors to select. - - If `None`, defaults to `"tab10"` when `n_classes <= 10`, otherwise - `"gist_rainbow"`. - - If `str`, interpreted as a Matplotlib colormap name. - - If `list`, each entry must be a valid Matplotlib color-like value. + Possible inputs are: + + * None: defaults to list of accessible `Petroff colors + <https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352>`_ + if `n_classes <= 10`, otherwise 'gist_rainbow' colormap + * str: name of :class:`matplotlib.colors.Colormap` + * list: list of length `n_classes` of `matplotlib colors + <https://matplotlib.org/stable/users/explain/colors/colors.html#colors-def>`_ n_classes : int Number of colors to select. Returns ------- - colors : list or ndarray of shape (n_classes, 4) + colors : ndarray of shape (n_classes, 4) RGBA colors, one per class. """ if multiclass_colors is None: - multiclass_colors = "tab10" if n_classes <= 10 else "gist_rainbow" + # select accessible colors according to Matthew A. Petroff, see + # https://arxiv.org/abs/2107.02270 and + # https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352 + if n_classes <= 10: + multiclass_colors = PETROFF_COLORS[:n_classes] + else: + multiclass_colors = "gist_rainbow" if isinstance(multiclass_colors, str): if multiclass_colors not in mpl.pyplot.colormaps(): @@ -97,13 +108,7 @@ def _select_colors(mpl, multiclass_colors, n_classes): "different colormap or provide a list of colors via " "'multiclass_colors'." ) - if cmap.N < 256: - # Special case for the qualitative colormaps that encode a - # discrete set of colors that are easily distinguishable, contrary to other - # colormaps that are continuous (for which `cmap.N` >= 256). - return mpl.colors.to_rgba_array(cmap.colors[:n_classes]) - else: - return cmap(np.linspace(0, 1, n_classes)) + return cmap(np.linspace(0, 1, n_classes)) elif isinstance(multiclass_colors, list): if len(multiclass_colors) != n_classes: @@ -164,18 +169,18 @@ class DecisionBoundaryDisplay: (grid_resolution, grid_resolution, n_classes) Values of the response function. - multiclass_colors : list of str or str, default=None + multiclass_colors : str or list of matplotlib colors, default=None Specifies how to color each class when plotting all classes of :term:`multiclass` problems. Possible inputs are: - * list: list of Matplotlib - `color <https://matplotlib.org/stable/users/explain/colors/colors.html#colors-def>`_ - strings, of length `n_classes` + * None: defaults to list of accessible `Petroff colors + <https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352>`_ + if `n_classes <= 10`, otherwise 'gist_rainbow' colormap * str: name of :class:`matplotlib.colors.Colormap` - * None: 'tab10' colormap is used to sample colors if the number of - classes is less than or equal to 10, otherwise 'gist_rainbow' colormap. + * list: list of length `n_classes` of `matplotlib colors + <https://matplotlib.org/stable/users/explain/colors/colors.html#colors-def>`_ Single color (fading to white) colormaps will be generated from the colors in the list or colors taken from the colormap, and passed to the `cmap` parameter @@ -192,9 +197,11 @@ class DecisionBoundaryDisplay: .. versionadded:: 1.7 .. versionchanged:: 1.9 - `multiclass_colors` is now also used when `response_method="predict"`, - except for when `plot_method='contour'`, where it is ignored and "black" is - used instead. + `multiclass_colors` is now also used when `response_method="predict"`, + except for when `plot_method='contour'`, where it is ignored and "black" is + used instead. + The default colors changed from 'tab10' to the more accessible `Petroff + colors <https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352>`_. xlabel : str, default=None Default label to place on x axis. @@ -475,19 +482,18 @@ def from_estimator( .. versionadded:: 1.4 - multiclass_colors : list of str, or str, default=None + multiclass_colors : str or list of matplotlib colors, default=None Specifies how to color each class when plotting :term:`multiclass` problems and `class_of_interest` is None. Possible inputs are: - * list: list of Matplotlib - `color <https://matplotlib.org/stable/users/explain/colors/colors.html#colors-def>`_ - strings, of length `n_classes` + * None: defaults to list of accessible `Petroff colors + <https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352>`_ + if `n_classes <= 10`, otherwise 'gist_rainbow' colormap * str: name of :class:`matplotlib.colors.Colormap` - * None: 'tab10' colormap is used to sample colors if the number of - classes is less than or equal to 10, otherwise 'gist_rainbow' - colormap. + * list: list of length `n_classes` of `matplotlib colors + <https://matplotlib.org/stable/users/explain/colors/colors.html#colors-def>`_ Single color (fading to white) colormaps will be generated from the colors in the list or colors taken from the colormap, and passed to the `cmap` @@ -504,7 +510,11 @@ def from_estimator( .. versionadded:: 1.7 .. versionchanged:: 1.9 - `multiclass_colors` is now also used when `response_method="predict"` + `multiclass_colors` is now also used when `response_method="predict"`, + except for when `plot_method='contour'`, where it is ignored and "black" + is used instead. + The default colors changed from 'tab10' to the more accessible `Petroff + colors <https://github.com/matplotlib/matplotlib/issues/9460#issuecomment-875185352>`_. xlabel : str, default=None The label used for the x-axis. If `None`, an attempt is made to diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index ac127106a2625..116e37d1fc5d7 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -27,7 +27,7 @@ assert_allclose, assert_array_equal, ) -from sklearn.utils.fixes import parse_version +from sklearn.utils.fixes import PETROFF_COLORS, parse_version X, y = make_classification( n_informative=1, @@ -670,15 +670,14 @@ def test_multiclass_colors_cmap( assert isinstance(disp.multiclass_colors_, np.ndarray) if multiclass_colors is None: - if len(clf.classes_) <= 10: - multiclass_colors = "tab10" + # make sure the correct colors are selected from the corresponding petroff color + # sequences or "gist_rainbow" + if len(clf.classes_) == 3: + multiclass_colors = PETROFF_COLORS[:3] else: multiclass_colors = "gist_rainbow" - if multiclass_colors in ["tab10", "tab20"]: - cmap = mpl.pyplot.get_cmap(multiclass_colors) - colors = mpl.colors.to_rgba_array(cmap.colors[: len(clf.classes_)]) - elif multiclass_colors in ["Blues", "gist_rainbow", "plasma"]: + if isinstance(multiclass_colors, str): cmap = mpl.pyplot.get_cmap(multiclass_colors) colors = cmap(np.linspace(0, 1, len(clf.classes_))) else: diff --git a/sklearn/utils/fixes.py b/sklearn/utils/fixes.py index eaee5b2b1237d..4a14cf39f6ec4 100644 --- a/sklearn/utils/fixes.py +++ b/sklearn/utils/fixes.py @@ -1,4 +1,4 @@ -"""Compatibility fixes for older version of python, numpy and scipy +"""Compatibility fixes for older version of the dependencies If you add content to this file, please give the version of the package at which the fix is no longer needed. @@ -541,3 +541,19 @@ def _safely_cast_index_arrays(A, idx_dtype=np.int32, msg=""): indptr = A.indptr.astype(idx_dtype, copy=False) return indices, indptr # DOK and LIL formats are not associated with index arrays. + + +# TODO remove when matplotlib 3.10 is the minimal supported version +# and replace usage with `mpl.color_sequences['petroff10']` +PETROFF_COLORS = [ + "#3f90da", + "#ffa90e", + "#bd1f01", + "#94a4a2", + "#832db6", + "#a96b59", + "#e76300", + "#b9ac70", + "#717581", + "#92dadd", +] From c1e7857fd3717a5531124d845719afe561c01f19 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:09:37 +0000 Subject: [PATCH 360/462] Fix allow_nan_estimators directive to check all constructed instances (#33749) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: adrinjalali <1663864+adrinjalali@users.noreply.github.com> Co-authored-by: ogrisel <89061+ogrisel@users.noreply.github.com> --- doc/sphinxext/allow_nan_estimators.py | 16 ++++++++++------ sklearn/utils/_test_common/instance_generator.py | 4 ++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/doc/sphinxext/allow_nan_estimators.py b/doc/sphinxext/allow_nan_estimators.py index 3b85ce6c87508..4835433e48636 100644 --- a/doc/sphinxext/allow_nan_estimators.py +++ b/doc/sphinxext/allow_nan_estimators.py @@ -19,12 +19,16 @@ def make_paragraph_for_estimator_type(estimator_type): lst = nodes.bullet_list() for name, est_class in all_estimators(type_filter=estimator_type): with suppress(SkipTest): - # Here we generate the text only for one instance. This directive - # should not be used for meta-estimators where tags depend on the - # sub-estimator. - est = next(_construct_instances(est_class)) - - if est.__sklearn_tags__().input_tags.allow_nan: + # Check all instances generated by _construct_instances, since + # some estimators support NaN only with specific + # hyper-parameters (e.g. SplineTransformer with + # handle_missing="zeros"). + allows_nan = any( + est.__sklearn_tags__().input_tags.allow_nan + for est in _construct_instances(est_class) + ) + + if allows_nan: module_name = ".".join(est_class.__module__.split(".")[:2]) class_title = f"{est_class.__name__}" class_url = f"./generated/{module_name}.{class_title}.html" diff --git a/sklearn/utils/_test_common/instance_generator.py b/sklearn/utils/_test_common/instance_generator.py index 64e067bd36e52..6c040acff48c4 100644 --- a/sklearn/utils/_test_common/instance_generator.py +++ b/sklearn/utils/_test_common/instance_generator.py @@ -472,6 +472,10 @@ # Default "auto" parameter can lead to different ordering of eigenvalues on # windows: #24105 SpectralEmbedding: dict(eigen_tol=1e-05), + # SplineTransformer supports NaN only with handle_missing="zeros", so we + # need this additional parameter set for the allow_nan_estimators Sphinx + # directive to detect it. + SplineTransformer: [dict(), dict(handle_missing="zeros")], StackingClassifier: dict( estimators=[ ("est1", DecisionTreeClassifier(max_depth=3, random_state=0)), From 4cdcdc09044cd71a4238b9ac2de30034de486981 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Wed, 15 Apr 2026 18:09:50 +0200 Subject: [PATCH 361/462] FIX Metadata routing: register remainder when `remainder="passthrough"` (#33665) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.compose/33665.fix.rst | 4 +++ sklearn/compose/_column_transformer.py | 5 ++- .../compose/tests/test_column_transformer.py | 35 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.compose/33665.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.compose/33665.fix.rst b/doc/whats_new/upcoming_changes/sklearn.compose/33665.fix.rst new file mode 100644 index 0000000000000..aa29d57288bba --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.compose/33665.fix.rst @@ -0,0 +1,4 @@ +- Fixes the regression that a `KeyError` was thrown when using + :func:`compose.ColumnTransformer.fit_transform` with metadata routing and + `remainder="passthrough"`. + By :user:`Anne Beyer <AnneBeyer>`. diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index b676738768f8c..50115f8ba3769 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -1240,7 +1240,10 @@ def get_metadata_routing(self): # might happen if no columns are selected for that transformer. We # request all metadata requested by all transformers. transformers = self.transformers - if self.remainder not in ("drop", "passthrough"): + if self.remainder != "drop": + # Note: remainder="passthrough" will be converted into a FunctionTransformer + # internally, so it needs to be added to the router as well here, even if it + # doesn't consume any metadata, to avoid a `KeyError` later. transformers = chain(transformers, [("remainder", self.remainder, None)]) for name, step, _ in transformers: method_mapping = MethodMapping() diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index d633d6f890bdd..8bd60b00a97cb 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -2858,5 +2858,40 @@ def test_unused_transformer_request_present(): assert router.consumes("fit", ["metadata"]) == set(["metadata"]) +@config_context(enable_metadata_routing=True) +@pytest.mark.parametrize( + "remainder", + [ + "drop", + "passthrough", # consumes no metadata + Trans(), # consumes no metadata + ConsumingTransformer(), # consumes metadata + ], +) +def test_metadata_routing_with_remainder_no_error(remainder): + # Make sure that metadata routing works with all possible remainder types. + # Non-regression test for https://github.com/scikit-learn/scikit-learn/issues/33614 + + X = np.array([[1, 2], [3, 4]]) + y = [0, 1] + sample_weight = [1, 1] + + # This can only be set here because metadata routing has to be enabled first. + if isinstance(remainder, ConsumingTransformer): + remainder.set_fit_request(sample_weight=True).set_transform_request( + sample_weight=True + ) + + transformer = ( + ConsumingTransformer() + .set_fit_request(sample_weight=True) + .set_transform_request(sample_weight=True) + ) + ct = ColumnTransformer([("trans", transformer, [0])], remainder=remainder) + + # Check that no error is raised + ct.fit_transform(X, y=y, sample_weight=sample_weight) + + # End of Metadata Routing Tests # ============================= From d86a1dfe450ab8b6988e6acbb83a12bc581f0e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= <deamarialeon@gmail.com> Date: Wed, 15 Apr 2026 18:52:53 +0200 Subject: [PATCH 362/462] ENH: Display the number and names of output features (#31937) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> Co-authored-by: Antoine Baker <antoinebaker@users.noreply.github.com> --- .../many-modules/31937.enhancement.rst | 9 ++ .../plot_cyclical_feature_engineering.py | 35 ++++- .../plot_column_transformer_mixed_types.py | 5 +- sklearn/compose/_column_transformer.py | 6 +- .../compose/tests/test_column_transformer.py | 12 +- sklearn/utils/_repr_html/base.py | 12 ++ sklearn/utils/_repr_html/estimator.css | 3 +- sklearn/utils/_repr_html/estimator.js | 55 +++++++ sklearn/utils/_repr_html/estimator.py | 76 ++++++--- sklearn/utils/_repr_html/features.css | 120 ++++++++++++++ sklearn/utils/_repr_html/features.py | 61 ++++++++ .../utils/_repr_html/tests/test_features.py | 146 ++++++++++++++++++ sklearn/utils/_repr_html/tests/test_js.py | 46 ++++++ 13 files changed, 551 insertions(+), 35 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/many-modules/31937.enhancement.rst create mode 100644 sklearn/utils/_repr_html/features.css create mode 100644 sklearn/utils/_repr_html/features.py create mode 100644 sklearn/utils/_repr_html/tests/test_features.py diff --git a/doc/whats_new/upcoming_changes/many-modules/31937.enhancement.rst b/doc/whats_new/upcoming_changes/many-modules/31937.enhancement.rst new file mode 100644 index 0000000000000..d8fc54ff139bb --- /dev/null +++ b/doc/whats_new/upcoming_changes/many-modules/31937.enhancement.rst @@ -0,0 +1,9 @@ +- The HTML representation of all scikit-learn estimators inheriting from + :class:`base.BaseEstimator` now displays a new block showing the number + and names of the output features when using a :class:`compose.ColumnTransformer` + or a :class:`pipeline.FeatureUnion`. A copy-paste button is available + for the output features name. By :user:`Dea María Léon <DeaMariaLeon>`, + :user:`Guillaume Lemaitre <glemaitre>`, + :user:`Jérémie du Boisberranger <jeremiedbb>`, + :user:`Olivier Grisel <ogrisel>`, + :user:`Antoine Baker <antoinebaker>`. diff --git a/examples/applications/plot_cyclical_feature_engineering.py b/examples/applications/plot_cyclical_feature_engineering.py index c684cb072b743..dbbc39479571e 100644 --- a/examples/applications/plot_cyclical_feature_engineering.py +++ b/examples/applications/plot_cyclical_feature_engineering.py @@ -210,7 +210,7 @@ def evaluate(model, X, y, cv, model_prop=None, model_step=None): y, cv=cv, scoring=["neg_mean_absolute_error", "neg_root_mean_squared_error"], - return_estimator=model_prop is not None, + return_estimator=True, ) if model_prop is not None: if model_step is not None: @@ -226,6 +226,8 @@ def evaluate(model, X, y, cv, model_prop=None, model_step=None): f"Mean Absolute Error: {mae.mean():.3f} +/- {mae.std():.3f}\n" f"Root Mean Squared Error: {rmse.mean():.3f} +/- {rmse.std():.3f}" ) + # To display the fitted estimator diagrams in the notebook. + return cv_results["estimator"][0] evaluate(gbrt, X, y, cv=ts_cv, model_prop="n_iter_") @@ -261,6 +263,7 @@ def evaluate(model, X, y, cv, model_prop=None, model_step=None): ("categorical", one_hot_encoder, categorical_columns), ], remainder=MinMaxScaler(), + verbose_feature_names_out=False, ), RidgeCV(alphas=alphas), ) @@ -308,6 +311,7 @@ def evaluate(model, X, y, cv, model_prop=None, model_step=None): ("one_hot_time", one_hot_encoder, ["hour", "weekday", "month"]), ], remainder=MinMaxScaler(), + verbose_feature_names_out=False, ), RidgeCV(alphas=alphas), ) @@ -348,11 +352,15 @@ def evaluate(model, X, y, cv, model_prop=None, model_step=None): def sin_transformer(period): - return FunctionTransformer(lambda x: np.sin(x / period * 2 * np.pi)) + return FunctionTransformer( + lambda x: np.sin(x / period * 2 * np.pi), feature_names_out="one-to-one" + ) def cos_transformer(period): - return FunctionTransformer(lambda x: np.cos(x / period * 2 * np.pi)) + return FunctionTransformer( + lambda x: np.cos(x / period * 2 * np.pi), feature_names_out="one-to-one" + ) # %% @@ -399,6 +407,7 @@ def cos_transformer(period): ("hour_cos", cos_transformer(24), ["hour"]), ], remainder=MinMaxScaler(), + verbose_feature_names_out=True, ) cyclic_cossin_linear_pipeline = make_pipeline( cyclic_cossin_transformer, @@ -472,6 +481,7 @@ def periodic_spline_transformer(period, n_splines=None, degree=3): ("cyclic_hour", periodic_spline_transformer(24, n_splines=12), ["hour"]), ], remainder=MinMaxScaler(), + verbose_feature_names_out=False, ) cyclic_spline_linear_pipeline = make_pipeline( cyclic_spline_transformer, @@ -615,8 +625,15 @@ def periodic_spline_transformer(period, n_splines=None, degree=3): ColumnTransformer( [ ("cyclic_hour", periodic_spline_transformer(24, n_splines=8), ["hour"]), - ("workingday", FunctionTransformer(lambda x: x == "True"), ["workingday"]), - ] + ( + "workingday", + FunctionTransformer( + lambda x: x == "True", feature_names_out="one-to-one" + ), + ["workingday"], + ), + ], + verbose_feature_names_out=False, ), PolynomialFeatures(degree=2, interaction_only=True, include_bias=False), ) @@ -631,8 +648,9 @@ def periodic_spline_transformer(period, n_splines=None, degree=3): [ ("marginal", cyclic_spline_transformer), ("interactions", hour_workday_interaction), - ] - ), + ], + verbose_feature_names_out=True, + ).set_output(transform="pandas"), RidgeCV(alphas=alphas), ) evaluate(cyclic_spline_interactions_pipeline, X, y, cv=ts_cv) @@ -683,10 +701,11 @@ def periodic_spline_transformer(period, n_splines=None, degree=3): ("one_hot_time", one_hot_encoder, ["hour", "weekday", "month"]), ], remainder="passthrough", + verbose_feature_names_out=False, ), Nystroem(kernel="poly", degree=2, n_components=300, random_state=0), RidgeCV(alphas=alphas), -) +).set_output(transform="pandas") evaluate(one_hot_poly_pipeline, X, y, cv=ts_cv) diff --git a/examples/compose/plot_column_transformer_mixed_types.py b/examples/compose/plot_column_transformer_mixed_types.py index 91768e261f271..a27c5dc56e3d4 100644 --- a/examples/compose/plot_column_transformer_mixed_types.py +++ b/examples/compose/plot_column_transformer_mixed_types.py @@ -78,7 +78,7 @@ categorical_features = ["embarked", "sex", "pclass"] categorical_transformer = Pipeline( steps=[ - ("encoder", OneHotEncoder(handle_unknown="ignore")), + ("encoder", OneHotEncoder(handle_unknown="ignore", sparse_output=False)), ("selector", SelectPercentile(chi2, percentile=50)), ] ) @@ -94,7 +94,7 @@ # Now we have a full prediction pipeline. clf = Pipeline( steps=[("preprocessor", preprocessor), ("classifier", LogisticRegression())] -) +).set_output(transform="pandas") X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) @@ -199,6 +199,7 @@ print("Best params:") print(search_cv.best_params_) +search_cv # %% # The internal cross-validation scores obtained by those parameters is: diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index 50115f8ba3769..bab1f4dc475d8 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -1173,9 +1173,13 @@ def _sk_visual_block_(self): remainder_columns = self.feature_names_in_[ remainder_columns ].tolist() + # get the fitted remainder function so we can access its methods to + # build the display in utils._repr_html.estimator.py + remainder_transformer = self.transformers_[-1][1] transformers = chain( - transformers, [("remainder", self.remainder, remainder_columns)] + transformers, + [("remainder", remainder_transformer, remainder_columns)], ) else: # not fitted if self.remainder != "drop": diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index 8bd60b00a97cb..98961a1ece7d4 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -1574,7 +1574,11 @@ def test_sk_visual_block_remainder_fitted_pandas(remainder): assert visual_block.name_details == (["col1", "col2"], ["col3", "col4"]) assert isinstance(visual_block.estimators[0], OneHotEncoder) if remainder == "passthrough": - assert visual_block.estimators[1] == "passthrough" + # comparing visual_block.estimators[1] to FunctionTransformer because + # _column_transformer.py::sk_visual_block needs to send the remainder + # as a transformer (not as a string) to estimator.py in order to + # display output names. + assert isinstance(visual_block.estimators[1], FunctionTransformer) else: assert isinstance(visual_block.estimators[1], StandardScaler) @@ -1593,7 +1597,11 @@ def test_sk_visual_block_remainder_fitted_numpy(remainder): assert visual_block.name_details == ([0, 2], [1]) assert isinstance(visual_block.estimators[0], StandardScaler) if remainder == "passthrough": - assert visual_block.estimators[1] == "passthrough" + # comparing visual_block.estimators[1] to FunctionTransformer because + # _column_transformer.py::sk_visual_block needs to send the remainder + # as a transformer (not as a string) to estimator.py in order to + # display output names. + assert isinstance(visual_block.estimators[1], FunctionTransformer) else: assert isinstance(visual_block.estimators[1], StandardScaler) diff --git a/sklearn/utils/_repr_html/base.py b/sklearn/utils/_repr_html/base.py index 61e6862ee8623..36aeea254badd 100644 --- a/sklearn/utils/_repr_html/base.py +++ b/sklearn/utils/_repr_html/base.py @@ -8,6 +8,18 @@ from sklearn.utils.fixes import parse_version +class _IDCounter: + """Generate sequential ids with a prefix.""" + + def __init__(self, prefix): + self.prefix = prefix + self.count = 0 + + def get_id(self): + self.count += 1 + return f"{self.prefix}-{self.count}" + + class _HTMLDocumentationLinkMixin: """Mixin class allowing to generate a link to the API documentation. diff --git a/sklearn/utils/_repr_html/estimator.css b/sklearn/utils/_repr_html/estimator.css index 75f55ce1499d8..dbc62ee9987ec 100644 --- a/sklearn/utils/_repr_html/estimator.css +++ b/sklearn/utils/_repr_html/estimator.css @@ -40,8 +40,7 @@ .sk-global input.sk-hidden--visually { border: 0; - clip: rect(1px 1px 1px 1px); - clip: rect(1px, 1px, 1px, 1px); + clip-path: inset(100%); height: 1px; margin: -1px; overflow: hidden; diff --git a/sklearn/utils/_repr_html/estimator.js b/sklearn/utils/_repr_html/estimator.js index cf1bcd2cf23f8..289d599779e52 100644 --- a/sklearn/utils/_repr_html/estimator.js +++ b/sklearn/utils/_repr_html/estimator.js @@ -1,3 +1,7 @@ +/* Authors: The scikit-learn developers + SPDX-License-Identifier: BSD-3-Clause +*/ + function copyToClipboard(text, element) { // Get the parameter prefix from the closest toggleable content const toggleableContent = element.closest('.sk-toggleable__content'); @@ -35,6 +39,13 @@ function copyToClipboard(text, element) { document.querySelectorAll('.copy-paste-icon').forEach(function(element) { const toggleableContent = element.closest('.sk-toggleable__content'); const paramPrefix = toggleableContent ? toggleableContent.dataset.paramPrefix : ''; + + const parent = element.parentElement; + if (!parent || !parent.nextElementSibling) { + console.warn('Expected copy-paste icon is missing from the DOM structure'); + return; + } + const paramName = element.parentElement.nextElementSibling .textContent.trim().split(' ')[0]; const fullParamName = paramPrefix ? `${paramPrefix}${paramName}` : paramName; @@ -42,7 +53,51 @@ document.querySelectorAll('.copy-paste-icon').forEach(function(element) { element.setAttribute('title', fullParamName); }); +/** + * Copy the list of feature names formatted as a Python list. + * + * @param {HTMLElement} element - The copy button inside a `.features` block; its siblings + * contain a `details` element and a table containing feature named. + * @returns {boolean} Always returns `false` so callers can prevent the default click behavior. + */ +function copyFeatureNamesToClipboard(element) { + var detailsElem = element.closest('.features').querySelector('details'); + var wasOpen = detailsElem.open; + detailsElem.open = true; + var content = element.closest('.features').querySelector('tbody') + .innerText.trim(); + if (!wasOpen) detailsElem.open = false; + const rows = content.split('\n').map(row => ` "${row}"`); + const formattedText = `[\n${rows.join(',\n')},\n]`; + const originalHTML = element.innerHTML.replace('✔', ''); + const originalStyle = element.style; + const copyMark = document.createElement('span'); + copyMark.innerHTML = '✔'; + copyMark.style.color = 'blue'; + copyMark.style.fontSize = '1em'; + + navigator.clipboard.writeText(formattedText) + .then(() => { + element.style.display = 'none'; + element.parentElement.appendChild(copyMark); + setTimeout(() => { + copyMark.remove(); + element.innerHTML = originalHTML; + element.style = originalStyle; + }, 1000); + }) + .catch(err => { + console.error('Failed to copy:', err); + element.style.color = 'orange'; + element.innerHTML = "Failed!"; + setTimeout(() => { + element.innerHTML = originalHTML; + element.style = originalStyle; + }, 1000); + }); + return false; +} /** * Adapted from Skrub * https://github.com/skrub-data/skrub/blob/403466d1d5d4dc76a7ef569b3f8228db59a31dc3/skrub/_reporting/_data/templates/report.js#L789 diff --git a/sklearn/utils/_repr_html/estimator.py b/sklearn/utils/_repr_html/estimator.py index be38702cd9174..a6e1ec33d8c4b 100644 --- a/sklearn/utils/_repr_html/estimator.py +++ b/sklearn/utils/_repr_html/estimator.py @@ -8,28 +8,20 @@ from pathlib import Path from sklearn import config_context - - -class _IDCounter: - """Generate sequential ids with a prefix.""" - - def __init__(self, prefix): - self.prefix = prefix - self.count = 0 - - def get_id(self): - self.count += 1 - return f"{self.prefix}-{self.count}" +from sklearn.utils._repr_html.base import _IDCounter +from sklearn.utils._repr_html.features import _features_html def _get_css_style(): estimator_css_file = Path(__file__).parent / "estimator.css" params_css_file = Path(__file__).parent / "params.css" + features_css_file = Path(__file__).parent / "features.css" estimator_css = estimator_css_file.read_text(encoding="utf-8") params_css = params_css_file.read_text(encoding="utf-8") + features_css = features_css_file.read_text(encoding="utf-8") - return f"{estimator_css}\n{params_css}" + return f"{estimator_css}\n{params_css}\n{features_css}" _CONTAINER_ID_COUNTER = _IDCounter("sk-container-id") @@ -112,6 +104,7 @@ def _write_label_html( name_details, name_caption=None, doc_link_label=None, + features=None, outer_class="sk-label-container", inner_class="sk-label", checked=False, @@ -225,9 +218,17 @@ def _write_label_html( out.write(f"<pre>{name_details}</pre>") out.write("</div>") + if features is None or len(features) == 0: + features_div = "" + else: + features_div = _features_html(features, is_fitted_css_class) + + out.write("</div></div>") + out.write(features_div) + else: out.write(f"<label>{name}</label>") - out.write("</div></div>") # outer_class inner_class + out.write("</div></div>") # outer_class inner_class def _get_visual_block(estimator): @@ -316,6 +317,7 @@ def _write_estimator_html( The prefix to prepend to parameter names for nested estimators. For example, in a pipeline this might be "pipeline__stepname__". """ + from sklearn.compose import ColumnTransformer if first_call: est_block = _get_visual_block(estimator) @@ -328,22 +330,23 @@ def _write_estimator_html( doc_link = estimator._get_doc_link() else: doc_link = "" + + has_feature_names_out = hasattr(estimator, "get_feature_names_out") + is_not_pipeline_step = not hasattr(estimator, "steps") + if est_block.kind in ("serial", "parallel"): dashed_wrapped = first_call or est_block.dash_wrapped dash_cls = " sk-dashed-wrapped" if dashed_wrapped else "" out.write(f'<div class="sk-item{dash_cls}">') if estimator_label: - if ( - hasattr(estimator, "get_params") - and not est_block.names == "passthrough" - and hasattr(estimator, "_get_params_html") + if hasattr(estimator, "get_params") and hasattr( + estimator, "_get_params_html" ): params = estimator._get_params_html(False, doc_link)._repr_html_inner() else: params = "" if ( hasattr(estimator, "_get_fitted_attr_html") - and not est_block.names == "passthrough" and is_fitted_css_class == "fitted" ): fitted_attrs = estimator._get_fitted_attr_html(doc_link) @@ -359,6 +362,7 @@ def _write_estimator_html( estimator_label, estimator_label_details, doc_link=doc_link, + features=None, is_fitted_css_class=is_fitted_css_class, is_fitted_icon=is_fitted_icon, param_prefix=param_prefix, @@ -403,8 +407,39 @@ def _write_estimator_html( ) out.write("</div>") # sk-parallel-item - out.write("</div></div>") + out.write("</div>") + + is_column_transformer = isinstance(estimator, ColumnTransformer) + has_single_estimator = len(est_block.estimators) == 1 + if ( + is_fitted_css_class + and has_feature_names_out + and is_not_pipeline_step + and not (is_column_transformer and has_single_estimator) + ): + features_div = _features_html( + estimator.get_feature_names_out(), is_fitted_css_class + ) + total_output_features_item = ( + f"<div class='total_features'>{features_div}</div>" + ) + out.write(total_output_features_item) + + out.write("</div>") elif est_block.kind == "single": + if ( + has_feature_names_out + and is_not_pipeline_step + and is_fitted_css_class + and hasattr(estimator, "n_features_in_") + ): + output_features = estimator.get_feature_names_out() + else: + output_features = "" + + if est_block.names == "NoneType(...)": + est_block.names = "passthrough" + if ( hasattr(estimator, "_get_params_html") and not est_block.names == "passthrough" @@ -435,6 +470,7 @@ def _write_estimator_html( inner_class="sk-estimator", checked=first_call, doc_link=doc_link, + features=output_features, is_fitted_css_class=is_fitted_css_class, is_fitted_icon=is_fitted_icon, param_prefix=param_prefix, diff --git a/sklearn/utils/_repr_html/features.css b/sklearn/utils/_repr_html/features.css new file mode 100644 index 0000000000000..8fb3c12b7a38a --- /dev/null +++ b/sklearn/utils/_repr_html/features.css @@ -0,0 +1,120 @@ +.features { + font-family: monospace; + cursor: pointer; + background-color: var(--sklearn-color-unfitted-level-0); + border: 1px dotted var(--sklearn-color-border-box); + border-radius: .20em; + margin-bottom: 0.5em; + font-size: inherit; /* Needed for jupyter */ +} + +.features.fitted { + background-color: var(--sklearn-color-fitted-level-0); +} + +.features summary { + cursor: pointer; + display: flex; + margin-bottom: 0; + text-align: center; + align-items: center; + justify-content: center; + gap: 0.5em; + padding: .25em; +} + +.features details[open] > summary { + color: var(--sklearn-color-text); + background-color: var(--sklearn-color-unfitted-level-2); + border-radius: .20em 0 0 0; +} + +.features.fitted details[open] > summary { + background-color: var(--sklearn-color-fitted-level-2); + border-radius: .20em 0 0 0; +} + +.features details > summary .arrow::before { + content: "▸"; + color: grey; +} + +.features details[open] > summary .arrow::before { + content: "▾"; +} + +.features details:hover > summary { + margin: 0; + background-color: var(--sklearn-color-unfitted-level-2); +} + +.features.fitted details:hover > summary { + margin: 0; + background-color: var(--sklearn-color-fitted-level-2); +} + +.features .features-container { + max-width: 15em; + max-height: 10em; + overflow: auto; + scrollbar-width: thin; + padding: .25em 0.1rem; + background-color: var(--sklearn-color-unfitted-level-0); + border-radius: 0 0 .5em .5em; +} + +.features.fitted .features-container { + background-color: var(--sklearn-color-fitted-level-0); +} + +.features .image-container { + block-size: 1em; + inline-size: 1em; + padding: 0; + margin: 0%; + display: flex; + justify-content: center; + align-items: center; +} + +.features .copy-paste-icon { + background-size: 1em 1em; + width: 1em; + height: 1em; + filter: grayscale(100%) opacity(60%); +} + +.features .features-container table { + width: 100%; + margin: 0.01em; +} + +.features .features-container table tr:nth-child(odd) { + background-color: #fff; +} + +.features .features-container table tr:nth-child(even) { + background-color: #f6f6f6; +} + +.features .features-container table tr:hover { + background-color: #e0e0e0; +} + +.features .features-container table { + table-layout: inherit; +} + +.features .features-container table td { + text-align: left; + padding: 0 0.5em; + border: 1px solid rgba(106, 105, 104, 0.232); + white-space: nowrap; + color: var(--sklearn-color-text); +} + +.total_features { + display: flex; + justify-content: center; + margin-top: 0.5em; +} diff --git a/sklearn/utils/_repr_html/features.py b/sklearn/utils/_repr_html/features.py new file mode 100644 index 0000000000000..855f3950fe705 --- /dev/null +++ b/sklearn/utils/_repr_html/features.py @@ -0,0 +1,61 @@ +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +import html + + +def _features_html(features, is_fitted_css_class=""): + """Generate HTML representation of feature names. + + Creates a collapsible HTML details element containing a table of feature + names with a summary line showing the total count. Includes a copy-to-clipboard + button for all feature names. + """ + FEATURES_TABLE_TEMPLATE = """ + <div class="features {is_fitted_css_class}"> + <details> + <summary> + <div class="arrow"></div> + <div>{total_features_line}</div> + <div class="image-container" title="Copy all output features"> + <i class="copy-paste-icon" + onclick=" + event.stopPropagation(); + event.preventDefault(); + copyFeatureNamesToClipboard(this); + " + > + </i> + </div> + </summary> + <div class="features-container"> + <table class="features-table"> + <tbody> + {rows} + </tbody> + </table> + </div> + </details> + </div> + """ + + FEATURES_ROW_TEMPLATE = """ + <tr> + <td>{feature}</td> + </tr> + + """ + total_features = len(features) + total_features_line = ( + f"{total_features} {'feature' if total_features == 1 else 'features'}" + ) + + rows = [ + FEATURES_ROW_TEMPLATE.format(feature=html.escape(feature)) + for feature in features + ] + return FEATURES_TABLE_TEMPLATE.format( + total_features_line=total_features_line, + is_fitted_css_class=html.escape(is_fitted_css_class), + rows="".join(rows), + ) diff --git a/sklearn/utils/_repr_html/tests/test_features.py b/sklearn/utils/_repr_html/tests/test_features.py new file mode 100644 index 0000000000000..e63caddb4bf13 --- /dev/null +++ b/sklearn/utils/_repr_html/tests/test_features.py @@ -0,0 +1,146 @@ +import numpy as np +import pytest + +from sklearn.compose import ColumnTransformer +from sklearn.decomposition import PCA, TruncatedSVD +from sklearn.pipeline import FeatureUnion, Pipeline +from sklearn.preprocessing import Normalizer, StandardScaler +from sklearn.utils._repr_html.estimator import estimator_html_repr +from sklearn.utils._repr_html.features import _features_html +from sklearn.utils._testing import MinimalTransformer + +ct = ColumnTransformer([("norm1", Normalizer(), [0, 1])], remainder="passthrough") +ct2 = FeatureUnion( + [("pca", PCA(n_components=1)), ("svd", TruncatedSVD(n_components=2))] +) +rng = np.random.RandomState(42) + + +def test_n_features_not_fitted(): + out = estimator_html_repr(ct) + assert "2 features" not in out + assert "x0" not in out + assert "x1" not in out + assert "<div class='features fitted'>" not in out + + +def test_with_MinimalTransformer(): + """Test works with MinimalTransformer in a pipeline + (doesn't inherit from BaseEstimator)""" + X, y = np.array([[0, 1], [1, 1]]), np.array([[0, 1]]) + + model = Pipeline([("transformer", MinimalTransformer())]) + model.fit(X, y) + out = estimator_html_repr(model) + assert "MinimalTransformer" in out + + +@pytest.mark.parametrize( + "pandas, feature_cols", + [ + (True, ["Feature A", "Feature B"]), + (False, ["x0", "x1"]), + ], +) +def test_estimator_html_repr_col_names(pandas, feature_cols): + """Test features names are kept with pandas col names and generic.""" + if pandas: + pd = pytest.importorskip("pandas") + X = pd.DataFrame({"Feature A": [0, 2], "Feature B": [1, 1]}) + else: + X = np.array([[0, 2], [1, 1]]) + + ct.fit(X) + out = estimator_html_repr(ct) + assert feature_cols[0] in out + assert feature_cols[1] in out + + +@pytest.mark.parametrize( + "pandas, total_output_features", + [ + (True, ["norm1__A", "norm1__B", "remainder__C"]), + (False, ["norm1__x0", "norm1__x1", "remainder__x2"]), + ], +) +def test_estimator_html_repr_total_feature_names(pandas, total_output_features): + """Test features names are kept with pandas col names and generic.""" + if pandas: + pd = pytest.importorskip("pandas") + X = pd.DataFrame({"A": [0, 2, 3], "B": [1, 1, 3], "C": [3, 5, 4]}) + else: + X = np.array([[0, 2, 3], [1, 1, 3], [3, 5, 4]]) + + ct.fit(X) + out = estimator_html_repr(ct) + + assert "<div class='total_features'>" in out + assert "3 features</div>" in out + for feature_name in total_output_features: + assert feature_name in out + + +def test_estimator_html_col_names_featureunion(): + X = [[0.0, 1.0, 3], [2.0, 2.0, 5]] + ct2.fit_transform(X) + out = estimator_html_repr(ct2) + + assert "pca__pca0" in out + assert "svd__truncatedsvd0" in out + assert "2 features" in out + + +def test_features_html_with_pipeline(): + """Test works with MinimalTransformer in a pipeline and scaler + to test number of features.""" + + pipe = Pipeline([("minimal", MinimalTransformer()), ("scaler", StandardScaler())]) + + X = rng.randn(10, 3) + pipe.fit(X) + html = estimator_html_repr(pipe) + assert "3 features" in html + + +def test_features_html_empty_features(): + """Test that _features_html handles empty feature list.""" + features = [] + html = _features_html(features) + + assert "0 features" in html + assert "<tbody>" in html + + +def test_features_html_special_characters(): + """Test that special characters in feature names are properly escaped.""" + features = [ + "feature&1", + 'feature"2', + "feature'3", + "feature>4", + "feature<5", + "<script>alert('xss')</script>", + ] + html = _features_html(features) + + assert "&" in html + assert "<script>alert('xss')</script>" in html + assert ">" in html + assert "<" in html + assert "6 features" in html + + +def test_features_html_structure(): + """Test that HTML structure contains expected elements.""" + features = ["feat1", "feat2"] + html = _features_html(features) + + assert "<details>" in html + assert "<summary>" in html + assert "</summary>" in html + assert "</details>" in html + assert '<table class="features-table">' in html + assert "<tbody>" in html + assert "</tbody>" in html + assert '<i class="copy-paste-icon"' in html + assert "copyFeatureNamesToClipboard" in html diff --git a/sklearn/utils/_repr_html/tests/test_js.py b/sklearn/utils/_repr_html/tests/test_js.py index 35cdf8057d8e1..6940d7caa51db 100644 --- a/sklearn/utils/_repr_html/tests/test_js.py +++ b/sklearn/utils/_repr_html/tests/test_js.py @@ -135,3 +135,49 @@ def test_force_theme(page, local_server, color, expected_theme): assert page.locator("#test").evaluate( f"el => el.classList.contains('{expected_theme}')" ) + + +FEATURE_NAMES_HTML = """ + <div class="features"> + <details> + <summary> + <div class="image-container" + title="Copy all output features"> + <i class="copy-paste-icon"></i> + </div> + </summary> + <div class="features-container"> + <table class="features-table"> + <tbody> + <tr><td>feature1</td></tr> + <tr><td>feature2</td></tr> + </tbody> + </table> + </div> + </details> + </div> + """ + + +def test_copy_paste_feature_names(page, local_server): + """Test that copyFeatureNamesToClipboard copies the right text to the clipboard. + + Test requires clipboard permissions, which are granted through page's context. + Assertion is done by reading back the clipboard content from the browser. + This is easier than writing a cross platform clipboard reader. + + Test adapted from test_copy_paste + """ + url, set_html_response = local_server + + copy_paste_html = _make_page(FEATURE_NAMES_HTML) + + set_html_response(copy_paste_html) + page.context.grant_permissions(["clipboard-read", "clipboard-write"]) + page.goto(url) + page.evaluate( + "copyFeatureNamesToClipboard(document.querySelector('.copy-paste-icon'))" + ) + clipboard_content = page.evaluate("navigator.clipboard.readText()") + + assert clipboard_content == '[\n "feature1",\n "feature2",\n]' From fb4f8fbcfee019b58eccecfd987eb6981d5988ce Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Thu, 16 Apr 2026 18:34:57 +1000 Subject: [PATCH 363/462] Deprecate `y_pred` in favour of `y_proba` in `log_loss` (#33740) --- benchmarks/bench_saga.py | 6 +- doc/modules/model_evaluation.rst | 18 +- .../sklearn.metrics/33740.fix.rst | 4 + sklearn/metrics/_classification.py | 153 ++++++++++---- sklearn/metrics/tests/test_classification.py | 198 +++++++++++------- 5 files changed, 247 insertions(+), 132 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/33740.fix.rst diff --git a/benchmarks/bench_saga.py b/benchmarks/bench_saga.py index b6e3d91885af4..f815d7d9835cd 100644 --- a/benchmarks/bench_saga.py +++ b/benchmarks/bench_saga.py @@ -120,15 +120,15 @@ def fit_single( scores = [] for X, y in [(X_train, y_train), (X_test, y_test)]: try: - y_pred = lr.predict_proba(X) + y_proba = lr.predict_proba(X) except NotImplementedError: # Lightning predict_proba is not implemented for n_classes > 2 - y_pred = _predict_proba(lr, X) + y_proba = _predict_proba(lr, X) if isinstance(lr, OneVsRestClassifier): coef = np.concatenate([est.coef_ for est in lr.estimators_]) else: coef = lr.coef_ - score = log_loss(y, y_pred, normalize=False) / n_samples + score = log_loss(y, y_proba, normalize=False) / n_samples score += 0.5 * alpha * np.sum(coef**2) + beta * np.sum(np.abs(coef)) scores.append(score) train_score, test_score = tuple(scores) diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index 5613e1d3554b1..0ce03d8ce24bf 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -1377,11 +1377,11 @@ method. >>> from sklearn.metrics import log_loss >>> y_true = [0, 0, 1, 1] - >>> y_pred = [[.9, .1], [.8, .2], [.3, .7], [.01, .99]] - >>> log_loss(y_true, y_pred) + >>> y_proba = [[.9, .1], [.8, .2], [.3, .7], [.01, .99]] + >>> log_loss(y_true, y_proba) 0.1738 -The first ``[.9, .1]`` in ``y_pred`` denotes 90% probability that the first +The first ``[.9, .1]`` in ``y_proba`` denotes 90% probability that the first sample has label 0. The log loss is non-negative. .. _matthews_corrcoef: @@ -2178,29 +2178,29 @@ of 0.0. >>> from sklearn.metrics import d2_log_loss_score >>> y_true = [1, 1, 2, 3] - >>> y_pred = [ + >>> y_proba = [ ... [0.5, 0.25, 0.25], ... [0.5, 0.25, 0.25], ... [0.5, 0.25, 0.25], ... [0.5, 0.25, 0.25], ... ] - >>> d2_log_loss_score(y_true, y_pred) + >>> d2_log_loss_score(y_true, y_proba) 0.0 >>> y_true = [1, 2, 3] - >>> y_pred = [ + >>> y_proba = [ ... [0.98, 0.01, 0.01], ... [0.01, 0.98, 0.01], ... [0.01, 0.01, 0.98], ... ] - >>> d2_log_loss_score(y_true, y_pred) + >>> d2_log_loss_score(y_true, y_proba) 0.981 >>> y_true = [1, 2, 3] - >>> y_pred = [ + >>> y_proba = [ ... [0.1, 0.6, 0.3], ... [0.1, 0.6, 0.3], ... [0.4, 0.5, 0.1], ... ] - >>> d2_log_loss_score(y_true, y_pred) + >>> d2_log_loss_score(y_true, y_proba) -0.552 diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/33740.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/33740.fix.rst new file mode 100644 index 0000000000000..14ac406feffee --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.metrics/33740.fix.rst @@ -0,0 +1,4 @@ +- `y_pred` was deprecated in favor of `y_proba` for :func:`metrics.log_loss` + and :func:`metrics.d2_log_loss_score` as predicted probabilities are expected, + not predicted labels. + By :user:`Lucy Liu <lucyleeow>`. diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 899d1afaaadea..0c1ac1eb7a04f 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -47,6 +47,7 @@ xpx, ) from sklearn.utils._param_validation import ( + Hidden, Interval, Options, StrOptions, @@ -3315,19 +3316,28 @@ def hamming_loss(y_true, y_pred, *, sample_weight=None): @validate_params( { "y_true": ["array-like"], - "y_pred": ["array-like"], + "y_proba": ["array-like", Hidden(None)], "normalize": ["boolean"], "sample_weight": ["array-like", None], "labels": ["array-like", None], + "y_pred": ["array-like", str], }, prefer_skip_nested_validation=True, ) -def log_loss(y_true, y_pred, *, normalize=True, sample_weight=None, labels=None): +def log_loss( + y_true, + y_proba=None, + *, + normalize=True, + sample_weight=None, + labels=None, + y_pred="deprecated", +): r"""Log loss, aka logistic loss or cross-entropy loss. This is the loss function used in (multinomial) logistic regression and extensions of it such as neural networks, defined as the negative - log-likelihood of a logistic model that returns ``y_pred`` probabilities + log-likelihood of a logistic model that returns ``y_proba`` probabilities for its training data ``y_true``. The log loss is only defined for two or more labels. For a single sample with true label :math:`y \in \{0,1\}` and @@ -3344,16 +3354,19 @@ def log_loss(y_true, y_pred, *, normalize=True, sample_weight=None, labels=None) y_true : array-like or label indicator matrix Ground truth (correct) labels for n_samples samples. - y_pred : array-like of float, shape = (n_samples, n_classes) or (n_samples,) + y_proba : array-like of float, shape = (n_samples, n_classes) or (n_samples,) Predicted probabilities, as returned by a classifier's - predict_proba method. If ``y_pred.shape = (n_samples,)`` + predict_proba method. If ``y_proba.shape = (n_samples,)`` the probabilities provided are assumed to be that of the - positive class. The labels in ``y_pred`` are assumed to be + positive class. The labels in ``y_proba`` are assumed to be ordered alphabetically, as done by :class:`~sklearn.preprocessing.LabelBinarizer`. - `y_pred` values are clipped to `[eps, 1-eps]` where `eps` is the machine - precision for `y_pred`'s dtype. + `y_proba` values are clipped to `[eps, 1-eps]` where `eps` is the machine + precision for `y_proba`'s dtype. + + .. versionadded:: 1.9 + `y_pred` was renamed to `y_proba`. normalize : bool, default=True If true, return the mean loss per sample. @@ -3369,6 +3382,21 @@ def log_loss(y_true, y_pred, *, normalize=True, sample_weight=None, labels=None) .. versionadded:: 0.18 + y_pred : array-like of float, shape = (n_samples, n_classes) or (n_samples,) + Predicted probabilities, as returned by a classifier's + predict_proba method. If ``y_pred.shape = (n_samples,)`` + the probabilities provided are assumed to be that of the + positive class. The labels in ``y_pred`` are assumed to be + ordered alphabetically, as done by + :class:`~sklearn.preprocessing.LabelBinarizer`. + + `y_pred` values are clipped to `[eps, 1-eps]` where `eps` is the machine + precision for `y_pred`'s dtype. + + .. deprecated:: 1.9 + `y_pred` was deprecated in favor of `y_proba` in v1.9 and will + be removed in v1.11. + Returns ------- loss : float @@ -3390,33 +3418,48 @@ def log_loss(y_true, y_pred, *, normalize=True, sample_weight=None, labels=None) ... [[.1, .9], [.9, .1], [.8, .2], [.35, .65]]) 0.21616 """ - xp, _, device_ = get_namespace_and_device(y_pred) - y_pred = check_array( - y_pred, ensure_2d=False, dtype=supported_float_dtypes(xp, device=device_) + # TODO(1.11): Remove check and remove default value for `y_proba`. + if not (isinstance(y_pred, str) and y_pred == "deprecated"): + if y_proba is not None: + raise ValueError( + "Cannot use both `y_pred` and `y_proba`. `y_pred` is deprecated, " + "use `y_proba` instead." + ) + else: + warnings.warn( + "`y_pred` was renamed to `y_proba` in version 1.9 and will be removed " + "in 1.11. Use `y_proba` instead.", + FutureWarning, + ) + y_proba = y_pred + + xp, _, device_ = get_namespace_and_device(y_proba) + y_proba = check_array( + y_proba, ensure_2d=False, dtype=supported_float_dtypes(xp, device=device_) ) if sample_weight is not None: sample_weight = move_to(sample_weight, xp=xp, device=device_) - transformed_labels, y_pred = _validate_multiclass_probabilistic_prediction( - y_true, y_pred, sample_weight, labels + transformed_labels, y_proba = _validate_multiclass_probabilistic_prediction( + y_true, y_proba, sample_weight, labels ) return _log_loss( transformed_labels, - y_pred, + y_proba, normalize=normalize, sample_weight=sample_weight, ) -def _log_loss(transformed_labels, y_pred, *, normalize=True, sample_weight=None): +def _log_loss(transformed_labels, y_proba, *, normalize=True, sample_weight=None): """Log loss for transformed labels and validated probabilistic predictions.""" - xp, _, device_ = get_namespace_and_device(y_pred) + xp, _, device_ = get_namespace_and_device(y_proba) if sample_weight is not None: sample_weight = move_to(sample_weight, xp=xp, device=device_) - eps = xp.finfo(y_pred.dtype).eps - y_pred = xp.clip(y_pred, eps, 1 - eps) - transformed_labels = xp.astype(transformed_labels, y_pred.dtype, copy=False) - loss = -xp.sum(_xlogy(transformed_labels, y_pred, xp=xp), axis=1) + eps = xp.finfo(y_proba.dtype).eps + y_proba = xp.clip(y_proba, eps, 1 - eps) + transformed_labels = xp.astype(transformed_labels, y_proba.dtype, copy=False) + loss = -xp.sum(_xlogy(transformed_labels, y_proba, xp=xp), axis=1) return float(_average(loss, weights=sample_weight, normalize=normalize)) @@ -3821,15 +3864,17 @@ def brier_score_loss( @validate_params( { "y_true": ["array-like"], - "y_pred": ["array-like"], + "y_proba": ["array-like", Hidden(None)], "sample_weight": ["array-like", None], "labels": ["array-like", None], + "y_pred": ["array-like", str], }, prefer_skip_nested_validation=True, ) -def d2_log_loss_score(y_true, y_pred, *, sample_weight=None, labels=None): - """ - :math:`D^2` score function, fraction of log loss explained. +def d2_log_loss_score( + y_true, y_proba=None, *, sample_weight=None, labels=None, y_pred="deprecated" +): + """:math:`D^2` score function, fraction of log loss explained. Best possible score is 1.0 and it can be negative (because the model can be arbitrarily worse). A model that always predicts the per-class proportions @@ -3844,14 +3889,17 @@ def d2_log_loss_score(y_true, y_pred, *, sample_weight=None, labels=None): y_true : array-like or label indicator matrix The actuals labels for the n_samples samples. - y_pred : array-like of shape (n_samples, n_classes) or (n_samples,) + y_proba : array-like of shape (n_samples, n_classes) or (n_samples,) Predicted probabilities, as returned by a classifier's - predict_proba method. If ``y_pred.shape = (n_samples,)`` + predict_proba method. If ``y_proba.shape = (n_samples,)`` the probabilities provided are assumed to be that of the - positive class. The labels in ``y_pred`` are assumed to be + positive class. The labels in ``y_proba`` are assumed to be ordered alphabetically, as done by :class:`~sklearn.preprocessing.LabelBinarizer`. + .. versionadded:: 1.9 + `y_pred` was renamed to `y_proba`. + sample_weight : array-like of shape (n_samples,), default=None Sample weights. @@ -3860,6 +3908,18 @@ def d2_log_loss_score(y_true, y_pred, *, sample_weight=None, labels=None): is ``None`` and ``y_pred`` has shape (n_samples,) the labels are assumed to be binary and are inferred from ``y_true``. + y_pred : array-like of shape (n_samples, n_classes) or (n_samples,) + Predicted probabilities, as returned by a classifier's + predict_proba method. If ``y_pred.shape = (n_samples,)`` + the probabilities provided are assumed to be that of the + positive class. The labels in ``y_pred`` are assumed to be + ordered alphabetically, as done by + :class:`~sklearn.preprocessing.LabelBinarizer`. + + .. deprecated:: 1.9 + `y_pred` was deprecated in favor of `y_proba` in v1.9 and will + be removed in v1.11. + Returns ------- d2 : float or ndarray of floats @@ -3875,35 +3935,50 @@ def d2_log_loss_score(y_true, y_pred, *, sample_weight=None, labels=None): This metric is not well-defined for a single sample and will return a NaN value if n_samples is less than two. """ - check_consistent_length(y_pred, y_true, sample_weight) - if _num_samples(y_pred) < 2: + # TODO(1.11): Remove check and remove default value for `y_proba`. + if not (isinstance(y_pred, str) and y_pred == "deprecated"): + if y_proba is not None: + raise ValueError( + "Cannot use both `y_pred` and `y_proba`. `y_pred` is deprecated, " + "use `y_proba` instead." + ) + else: + warnings.warn( + "`y_pred` was renamed to `y_proba` in version 1.9 and will be removed " + "in 1.11. Use `y_proba` instead.", + FutureWarning, + ) + y_proba = y_pred + + check_consistent_length(y_proba, y_true, sample_weight) + if _num_samples(y_proba) < 2: msg = "D^2 score is not well-defined with less than two samples." warnings.warn(msg, UndefinedMetricWarning) return float("nan") - xp, _, device_ = get_namespace_and_device(y_pred) - y_pred = check_array( - y_pred, ensure_2d=False, dtype=supported_float_dtypes(xp, device=device_) + xp, _, device_ = get_namespace_and_device(y_proba) + y_proba = check_array( + y_proba, ensure_2d=False, dtype=supported_float_dtypes(xp, device=device_) ) if sample_weight is not None: sample_weight = move_to(sample_weight, xp=xp, device=device_) - transformed_labels, y_pred = _validate_multiclass_probabilistic_prediction( - y_true, y_pred, sample_weight, labels + transformed_labels, y_proba = _validate_multiclass_probabilistic_prediction( + y_true, y_proba, sample_weight, labels ) - xp, _ = get_namespace(y_pred, transformed_labels) - y_pred_null = _average(transformed_labels, axis=0, weights=sample_weight) - y_pred_null = xp.tile(y_pred_null, (y_pred.shape[0], 1)) + xp, _ = get_namespace(y_proba, transformed_labels) + y_proba_null = _average(transformed_labels, axis=0, weights=sample_weight) + y_proba_null = xp.tile(y_proba_null, (y_proba.shape[0], 1)) numerator = _log_loss( transformed_labels, - y_pred, + y_proba, normalize=False, sample_weight=sample_weight, ) denominator = _log_loss( transformed_labels, - y_pred_null, + y_proba_null, normalize=False, sample_weight=sample_weight, ) diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index c561470f8bda5..c40c62411e646 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -2802,65 +2802,65 @@ def test_hinge_loss_multiclass_invariance_lists(): def test_log_loss(): # binary case with symbolic labels ("no" < "yes") y_true = ["no", "no", "no", "yes", "yes", "yes"] - y_pred = np.array( + y_proba = np.array( [[0.5, 0.5], [0.1, 0.9], [0.01, 0.99], [0.9, 0.1], [0.75, 0.25], [0.001, 0.999]] ) - loss = log_loss(y_true, y_pred) - loss_true = -np.mean(bernoulli.logpmf(np.array(y_true) == "yes", y_pred[:, 1])) + loss = log_loss(y_true, y_proba) + loss_true = -np.mean(bernoulli.logpmf(np.array(y_true) == "yes", y_proba[:, 1])) assert_allclose(loss, loss_true) # multiclass case; adapted from http://bit.ly/RJJHWA y_true = [1, 0, 2] - y_pred = [[0.2, 0.7, 0.1], [0.6, 0.2, 0.2], [0.6, 0.1, 0.3]] - loss = log_loss(y_true, y_pred, normalize=True) + y_proba = [[0.2, 0.7, 0.1], [0.6, 0.2, 0.2], [0.6, 0.1, 0.3]] + loss = log_loss(y_true, y_proba, normalize=True) assert_allclose(loss, 0.6904911) # check that we got all the shapes and axes right - # by doubling the length of y_true and y_pred + # by doubling the length of y_true and y_proba y_true *= 2 - y_pred *= 2 - loss = log_loss(y_true, y_pred, normalize=False) + y_proba *= 2 + loss = log_loss(y_true, y_proba, normalize=False) assert_allclose(loss, 0.6904911 * 6) # raise error if number of classes are not equal. y_true = [1, 0, 2] - y_pred = [[0.3, 0.7], [0.6, 0.4], [0.4, 0.6]] + y_proba = [[0.3, 0.7], [0.6, 0.4], [0.4, 0.6]] with pytest.raises(ValueError): - log_loss(y_true, y_pred) + log_loss(y_true, y_proba) # raise error if labels do not contain all values of y_true y_true = ["a", "b", "c"] - y_pred = [[0.9, 0.1, 0.0], [0.1, 0.9, 0.0], [0.1, 0.1, 0.8]] + y_proba = [[0.9, 0.1, 0.0], [0.1, 0.9, 0.0], [0.1, 0.1, 0.8]] labels = ["a", "c", "d"] error_str = ( "y_true contains values {'b'} not belonging to the passed " "labels ['a', 'c', 'd']." ) with pytest.raises(ValueError, match=re.escape(error_str)): - log_loss(y_true, y_pred, labels=labels) + log_loss(y_true, y_proba, labels=labels) # case when y_true is a string array object y_true = ["ham", "spam", "spam", "ham"] - y_pred = [[0.3, 0.7], [0.6, 0.4], [0.4, 0.6], [0.7, 0.3]] - loss = log_loss(y_true, y_pred) + y_proba = [[0.3, 0.7], [0.6, 0.4], [0.4, 0.6], [0.7, 0.3]] + loss = log_loss(y_true, y_proba) assert_allclose(loss, 0.7469410) # test labels option y_true = [2, 2] - y_pred = [[0.2, 0.8], [0.6, 0.4]] + y_proba = [[0.2, 0.8], [0.6, 0.4]] y_score = np.array([[0.1, 0.9], [0.1, 0.9]]) error_str = ( "y_true contains only one label (2). Please provide the list of all " "expected class labels explicitly through the labels argument." ) with pytest.raises(ValueError, match=re.escape(error_str)): - log_loss(y_true, y_pred) + log_loss(y_true, y_proba) - y_pred = [[0.2, 0.8], [0.6, 0.4], [0.7, 0.3]] + y_proba = [[0.2, 0.8], [0.6, 0.4], [0.7, 0.3]] error_str = "Found input variables with inconsistent numbers of samples: [3, 2]" with pytest.raises(ValueError, match=re.escape(error_str)): - log_loss(y_true, y_pred) + log_loss(y_true, y_proba) # works when the labels argument is used @@ -2868,7 +2868,7 @@ def test_log_loss(): calculated_log_loss = log_loss(y_true, y_score, labels=[1, 2]) assert_allclose(calculated_log_loss, true_log_loss) - # ensure labels work when len(np.unique(y_true)) != y_pred.shape[1] + # ensure labels work when len(np.unique(y_true)) != y_proba.shape[1] y_true = [1, 2, 2] y_score2 = [[0.7, 0.1, 0.2], [0.2, 0.7, 0.1], [0.1, 0.7, 0.2]] loss = log_loss(y_true, y_score2, labels=[1, 2, 3]) @@ -2883,34 +2883,34 @@ def test_log_loss_eps(dtype): https://github.com/scikit-learn/scikit-learn/issues/24315 """ y_true = np.array([0, 1], dtype=dtype) - y_pred = np.array([1, 0], dtype=dtype) + y_proba = np.array([1, 0], dtype=dtype) - loss = log_loss(y_true, y_pred) + loss = log_loss(y_true, y_proba) assert np.isfinite(loss) @pytest.mark.parametrize("dtype", [np.float64, np.float32, np.float16]) def test_log_loss_not_probabilities_warning(dtype): - """Check that log_loss raises a warning when y_pred values don't sum to 1.""" + """Check that log_loss raises a warning when y_proba values don't sum to 1.""" y_true = np.array([0, 1, 1, 0]) - y_pred = np.array([[0.2, 0.7], [0.6, 0.3], [0.4, 0.7], [0.8, 0.3]], dtype=dtype) + y_proba = np.array([[0.2, 0.7], [0.6, 0.3], [0.4, 0.7], [0.8, 0.3]], dtype=dtype) with pytest.warns(UserWarning, match="The y_prob values do not sum to one."): - log_loss(y_true, y_pred) + log_loss(y_true, y_proba) @pytest.mark.parametrize( - "y_true, y_pred", + "y_true, y_proba", [ ([0, 1, 0], [0, 1, 0]), ([0, 1, 0], [[1, 0], [0, 1], [1, 0]]), ([0, 1, 2], [[1, 0, 0], [0, 1, 0], [0, 0, 1]]), ], ) -def test_log_loss_perfect_predictions(y_true, y_pred): +def test_log_loss_perfect_predictions(y_true, y_proba): """Check that log_loss returns 0 for perfect predictions.""" # Because of the clipping, the result is not exactly 0 - assert log_loss(y_true, y_pred) == pytest.approx(0) + assert log_loss(y_true, y_proba) == pytest.approx(0) def test_log_loss_pandas_input(): @@ -2925,9 +2925,9 @@ def test_log_loss_pandas_input(): except ImportError: pass for TrueInputType, PredInputType in types: - # y_pred dataframe, y_true series - y_true, y_pred = TrueInputType(y_tr), PredInputType(y_pr) - loss = log_loss(y_true, y_pred) + # y_proba dataframe, y_true series + y_true, y_proba = TrueInputType(y_tr), PredInputType(y_pr) + loss = log_loss(y_true, y_proba) assert_allclose(loss, 0.7469410) @@ -2946,6 +2946,24 @@ def test_log_loss_warnings(): ) +# TODO(1.11): Remove +def test_log_loss_y_pred_deprecation(): + """Test `y_pred` deprecation in favor of `y_proba` for `log_loss`.""" + y_true = np.array([0, 1, 1, 0]) + y_proba = np.array([[0.1, 0.9], [0.9, 0.1], [0.8, 0.2], [0.35, 0.65]]) + + # Check no error raised + log_loss(y_true, y_proba) + + msg = "`y_pred` was renamed to `y_proba` in version 1.9 and will be removed " + with pytest.warns(FutureWarning, match=re.escape(msg)): + log_loss(y_true, y_pred=y_proba) + + msg = "Cannot use both `y_pred` and `y_proba`. `y_pred` is deprecated, " + with pytest.raises(ValueError, match=re.escape(msg)): + log_loss(y_true, y_pred=y_proba, y_proba=y_proba) + + def test_brier_score_loss_binary(): # Check brier_score_loss function y_true = np.array([0, 1, 1, 0, 1, 1]) @@ -3223,7 +3241,7 @@ def test_classification_metric_division_by_zero_nan_validaton(scoring): def test_d2_log_loss_score(): y_true = [0, 0, 0, 1, 1, 1] y_true_string = ["no", "no", "no", "yes", "yes", "yes"] - y_pred = np.array( + y_proba = np.array( [ [0.5, 0.5], [0.9, 0.1], @@ -3233,7 +3251,7 @@ def test_d2_log_loss_score(): [0.01, 0.99], ] ) - y_pred_null = np.array( + y_proba_null = np.array( [ [0.5, 0.5], [0.5, 0.5], @@ -3243,28 +3261,28 @@ def test_d2_log_loss_score(): [0.5, 0.5], ] ) - d2_score = d2_log_loss_score(y_true=y_true, y_pred=y_pred) - log_likelihood = log_loss(y_true=y_true, y_pred=y_pred, normalize=False) - log_likelihood_null = log_loss(y_true=y_true, y_pred=y_pred_null, normalize=False) + d2_score = d2_log_loss_score(y_true=y_true, y_proba=y_proba) + log_likelihood = log_loss(y_true=y_true, y_proba=y_proba, normalize=False) + log_likelihood_null = log_loss(y_true=y_true, y_proba=y_proba_null, normalize=False) d2_score_true = 1 - log_likelihood / log_likelihood_null assert d2_score == pytest.approx(d2_score_true) # check that using sample weight also gives the correct d2 score sample_weight = np.array([2, 1, 3, 4, 3, 1]) - y_pred_null[:, 0] = sample_weight[:3].sum() / sample_weight.sum() - y_pred_null[:, 1] = sample_weight[3:].sum() / sample_weight.sum() + y_proba_null[:, 0] = sample_weight[:3].sum() / sample_weight.sum() + y_proba_null[:, 1] = sample_weight[3:].sum() / sample_weight.sum() d2_score = d2_log_loss_score( - y_true=y_true, y_pred=y_pred, sample_weight=sample_weight + y_true=y_true, y_proba=y_proba, sample_weight=sample_weight ) log_likelihood = log_loss( y_true=y_true, - y_pred=y_pred, + y_proba=y_proba, sample_weight=sample_weight, normalize=False, ) log_likelihood_null = log_loss( y_true=y_true, - y_pred=y_pred_null, + y_proba=y_proba_null, sample_weight=sample_weight, normalize=False, ) @@ -3272,7 +3290,7 @@ def test_d2_log_loss_score(): assert d2_score == pytest.approx(d2_score_true) # check if good predictions give a relatively higher value for the d2 score - y_pred = np.array( + y_proba = np.array( [ [0.9, 0.1], [0.8, 0.2], @@ -3282,14 +3300,14 @@ def test_d2_log_loss_score(): [0.1, 0.9], ] ) - d2_score = d2_log_loss_score(y_true, y_pred) + d2_score = d2_log_loss_score(y_true, y_proba) assert 0.5 < d2_score < 1.0 # check that a similar value is obtained for string labels - d2_score_string = d2_log_loss_score(y_true_string, y_pred) + d2_score_string = d2_log_loss_score(y_true_string, y_proba) assert d2_score_string == pytest.approx(d2_score) # check if poor predictions gives a relatively low value for the d2 score - y_pred = np.array( + y_proba = np.array( [ [0.5, 0.5], [0.1, 0.9], @@ -3299,16 +3317,16 @@ def test_d2_log_loss_score(): [0.1, 0.9], ] ) - d2_score = d2_log_loss_score(y_true, y_pred) + d2_score = d2_log_loss_score(y_true, y_proba) assert d2_score < 0 # check that a similar value is obtained for string labels - d2_score_string = d2_log_loss_score(y_true_string, y_pred) + d2_score_string = d2_log_loss_score(y_true_string, y_proba) assert d2_score_string == pytest.approx(d2_score) # check if simply using the average of the classes as the predictions # gives a d2 score of 0 y_true = [0, 0, 0, 1, 1, 1] - y_pred = np.array( + y_proba = np.array( [ [0.5, 0.5], [0.5, 0.5], @@ -3318,23 +3336,23 @@ def test_d2_log_loss_score(): [0.5, 0.5], ] ) - d2_score = d2_log_loss_score(y_true, y_pred) + d2_score = d2_log_loss_score(y_true, y_proba) assert d2_score == 0 - d2_score_string = d2_log_loss_score(y_true_string, y_pred) + d2_score_string = d2_log_loss_score(y_true_string, y_proba) assert d2_score_string == 0 # check if simply using the average of the classes as the predictions # gives a d2 score of 0 when the positive class has a higher proportion y_true = [0, 1, 1, 1] y_true_string = ["no", "yes", "yes", "yes"] - y_pred = np.array([[0.25, 0.75], [0.25, 0.75], [0.25, 0.75], [0.25, 0.75]]) - d2_score = d2_log_loss_score(y_true, y_pred) + y_proba = np.array([[0.25, 0.75], [0.25, 0.75], [0.25, 0.75], [0.25, 0.75]]) + d2_score = d2_log_loss_score(y_true, y_proba) assert d2_score == 0 - d2_score_string = d2_log_loss_score(y_true_string, y_pred) + d2_score_string = d2_log_loss_score(y_true_string, y_proba) assert d2_score_string == 0 sample_weight = [2, 2, 2, 2] d2_score_with_sample_weight = d2_log_loss_score( - y_true, y_pred, sample_weight=sample_weight + y_true, y_proba, sample_weight=sample_weight ) assert d2_score_with_sample_weight == 0 @@ -3343,7 +3361,7 @@ def test_d2_log_loss_score(): y_true = ["high", "high", "low", "neutral"] sample_weight = [1.4, 0.6, 0.8, 0.2] - y_pred = np.array( + y_proba = np.array( [ [0.8, 0.1, 0.1], [0.8, 0.1, 0.1], @@ -3351,12 +3369,12 @@ def test_d2_log_loss_score(): [0.1, 0.1, 0.8], ] ) - d2_score = d2_log_loss_score(y_true, y_pred) + d2_score = d2_log_loss_score(y_true, y_proba) assert 0.5 < d2_score < 1.0 - d2_score = d2_log_loss_score(y_true, y_pred, sample_weight=sample_weight) + d2_score = d2_log_loss_score(y_true, y_proba, sample_weight=sample_weight) assert 0.5 < d2_score < 1.0 - y_pred = np.array( + y_proba = np.array( [ [0.2, 0.5, 0.3], [0.1, 0.7, 0.2], @@ -3364,9 +3382,9 @@ def test_d2_log_loss_score(): [0.2, 0.7, 0.1], ] ) - d2_score = d2_log_loss_score(y_true, y_pred) + d2_score = d2_log_loss_score(y_true, y_proba) assert d2_score < 0 - d2_score = d2_log_loss_score(y_true, y_pred, sample_weight=sample_weight) + d2_score = d2_log_loss_score(y_true, y_proba, sample_weight=sample_weight) assert d2_score < 0 @@ -3378,23 +3396,23 @@ def test_d2_log_loss_score_missing_labels(): y_true = [2, 0, 2, 0] labels = [0, 1, 2] sample_weight = [1.4, 0.6, 0.7, 0.3] - y_pred = np.tile([1, 0, 0], (4, 1)) + y_proba = np.tile([1, 0, 0], (4, 1)) - log_loss_obs = log_loss(y_true, y_pred, sample_weight=sample_weight, labels=labels) + log_loss_obs = log_loss(y_true, y_proba, sample_weight=sample_weight, labels=labels) # Null model consists of weighted average of the classes. # Given that the sum of the weights is 3, # - weighted average of 0s is (0.6 + 0.3) / 3 = 0.3 # - weighted average of 1s is 0 # - weighted average of 2s is (1.4 + 0.7) / 3 = 0.7 - y_pred_null = np.tile([0.3, 0, 0.7], (4, 1)) + y_proba_null = np.tile([0.3, 0, 0.7], (4, 1)) log_loss_null = log_loss( - y_true, y_pred_null, sample_weight=sample_weight, labels=labels + y_true, y_proba_null, sample_weight=sample_weight, labels=labels ) expected_d2_score = 1 - log_loss_obs / log_loss_null d2_score = d2_log_loss_score( - y_true, y_pred, sample_weight=sample_weight, labels=labels + y_true, y_proba, sample_weight=sample_weight, labels=labels ) assert_allclose(d2_score, expected_d2_score) @@ -3402,10 +3420,10 @@ def test_d2_log_loss_score_missing_labels(): def test_d2_log_loss_score_label_order(): """Check that d2_log_loss_score doesn't depend on the order of the labels.""" y_true = [2, 0, 2, 0] - y_pred = np.tile([1, 0, 0], (4, 1)) + y_proba = np.tile([1, 0, 0], (4, 1)) - d2_score = d2_log_loss_score(y_true, y_pred, labels=[0, 1, 2]) - d2_score_other = d2_log_loss_score(y_true, y_pred, labels=[0, 2, 1]) + d2_score = d2_log_loss_score(y_true, y_proba, labels=[0, 1, 2]) + d2_score_other = d2_log_loss_score(y_true, y_proba, labels=[0, 2, 1]) assert_allclose(d2_score, d2_score_other) @@ -3414,49 +3432,67 @@ def test_d2_log_loss_score_raises(): """Test that d2_log_loss_score raises the appropriate errors on invalid inputs.""" y_true = [0, 1, 2] - y_pred = [[0.2, 0.8], [0.5, 0.5], [0.4, 0.6]] + y_proba = [[0.2, 0.8], [0.5, 0.5], [0.4, 0.6]] err = "contain different number of classes" with pytest.raises(ValueError, match=err): - d2_log_loss_score(y_true, y_pred) + d2_log_loss_score(y_true, y_proba) # check error if the number of classes in labels do not match the number - # of classes in y_pred. + # of classes in y_proba. y_true = [0, 1, 2] - y_pred = [[0.5, 0.5], [0.5, 0.5], [0.5, 0.5]] + y_proba = [[0.5, 0.5], [0.5, 0.5], [0.5, 0.5]] labels = [0, 1, 2] err = "number of classes in labels is different" with pytest.raises(ValueError, match=err): - d2_log_loss_score(y_true, y_pred, labels=labels) + d2_log_loss_score(y_true, y_proba, labels=labels) - # check error if y_true and y_pred do not have equal lengths + # check error if y_true and y_proba do not have equal lengths y_true = [0, 1, 2] - y_pred = [[0.5, 0.5, 0.5], [0.6, 0.3, 0.1]] + y_proba = [[0.5, 0.5, 0.5], [0.6, 0.3, 0.1]] err = "inconsistent numbers of samples" with pytest.raises(ValueError, match=err): - d2_log_loss_score(y_true, y_pred) + d2_log_loss_score(y_true, y_proba) # check warning for samples < 2 y_true = [1] - y_pred = [[0.5, 0.5]] + y_proba = [[0.5, 0.5]] err = "score is not well-defined" with pytest.warns(UndefinedMetricWarning, match=err): - d2_log_loss_score(y_true, y_pred) + d2_log_loss_score(y_true, y_proba) # check error when y_true only has 1 label y_true = [1, 1, 1] - y_pred = [[0.5, 0.5], [0.5, 0.5], [0.5, 0.5]] + y_proba = [[0.5, 0.5], [0.5, 0.5], [0.5, 0.5]] err = "y_true contains only one label" with pytest.raises(ValueError, match=err): - d2_log_loss_score(y_true, y_pred) + d2_log_loss_score(y_true, y_proba) # check error when y_true only has 1 label and labels also has # only 1 label y_true = [1, 1, 1] labels = [1] - y_pred = [[0.5, 0.5], [0.5, 0.5], [0.5, 0.5]] + y_proba = [[0.5, 0.5], [0.5, 0.5], [0.5, 0.5]] err = "The labels array needs to contain at least two" with pytest.raises(ValueError, match=err): - d2_log_loss_score(y_true, y_pred, labels=labels) + d2_log_loss_score(y_true, y_proba, labels=labels) + + +# TODO(1.11): Remove +def test_d2_log_loss_score_y_pred_deprecation(): + """Test `y_pred` deprecation in favor of `y_proba` for `d2_log_loss_score`.""" + y_true = np.array([0, 1, 1, 0]) + y_proba = np.array([[0.1, 0.9], [0.9, 0.1], [0.8, 0.2], [0.35, 0.65]]) + + # Check no error raised + d2_log_loss_score(y_true, y_proba) + + msg = "`y_pred` was renamed to `y_proba` in version 1.9 and will be removed " + with pytest.warns(FutureWarning, match=re.escape(msg)): + d2_log_loss_score(y_true, y_pred=y_proba) + + msg = "Cannot use both `y_pred` and `y_proba`. `y_pred` is deprecated, " + with pytest.raises(ValueError, match=re.escape(msg)): + d2_log_loss_score(y_true, y_pred=y_proba, y_proba=y_proba) def test_d2_brier_score(): From 97ab219cbae07f6e18cb5ec5c2701cd4fd7e2dee Mon Sep 17 00:00:00 2001 From: Andy <andymucyo@gmail.com> Date: Thu, 16 Apr 2026 12:34:05 +0200 Subject: [PATCH 364/462] DOC added link to user guide for LocalFactorOutlier (#33767) --- sklearn/neighbors/_lof.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sklearn/neighbors/_lof.py b/sklearn/neighbors/_lof.py index e7c417eb74ca4..16bd9e9032a5c 100644 --- a/sklearn/neighbors/_lof.py +++ b/sklearn/neighbors/_lof.py @@ -30,6 +30,8 @@ class LocalOutlierFactor(KNeighborsMixin, OutlierMixin, NeighborsBase): neighbors, one can identify samples that have a substantially lower density than their neighbors. These are considered outliers. + Read more in the :ref:`User Guide <local_outlier_factor>`. + .. versionadded:: 0.19 Parameters From 20c0129906b26803f810e41936e5487d5becfcf4 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Thu, 16 Apr 2026 13:39:04 +0200 Subject: [PATCH 365/462] MNT Clean-up matplotlib version checks for < v3.5 (#33769) --- .../tests/test_boundary_decision_display.py | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index 116e37d1fc5d7..826eec4332148 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -592,13 +592,6 @@ def test_class_of_interest_multiclass(pyplot, response_method): @pytest.mark.parametrize("response_method", ["predict_proba", "decision_function"]) def test_multiclass_plot_max_class(pyplot, response_method): """Check plot correct when plotting max multiclass class.""" - import matplotlib as mpl - - # In matplotlib < v3.5, default value of `pcolormesh(shading)` is 'flat', which - # results in the last row and column being dropped. Thus older versions produce - # a 99x99 grid, while newer versions produce a 100x100 grid. - if parse_version(mpl.__version__) < parse_version("3.5"): - pytest.skip("`pcolormesh` in Matplotlib >= 3.5 gives smaller grid size.") X, y = load_iris_2d_scaled() clf = LogisticRegression().fit(X, y) @@ -650,11 +643,6 @@ def test_multiclass_colors_cmap( """Check correct cmap used for all `multiclass_colors` inputs.""" import matplotlib as mpl - if parse_version(mpl.__version__) < parse_version("3.5"): - pytest.skip( - "Matplotlib >= 3.5 is needed for `==` to check equivalence of colormaps" - ) - X, y = make_blobs(n_samples=150, centers=n_classes, n_features=2, random_state=42) clf = LogisticRegression().fit(X, y) @@ -670,7 +658,7 @@ def test_multiclass_colors_cmap( assert isinstance(disp.multiclass_colors_, np.ndarray) if multiclass_colors is None: - # make sure the correct colors are selected from the corresponding petroff color + # Make sure the correct colors are selected from the corresponding petroff color # sequences or "gist_rainbow" if len(clf.classes_) == 3: multiclass_colors = PETROFF_COLORS[:3] @@ -678,7 +666,7 @@ def test_multiclass_colors_cmap( multiclass_colors = "gist_rainbow" if isinstance(multiclass_colors, str): - cmap = mpl.pyplot.get_cmap(multiclass_colors) + cmap = pyplot.get_cmap(multiclass_colors) colors = cmap(np.linspace(0, 1, len(clf.classes_))) else: colors = mpl.colors.to_rgba_array(multiclass_colors) From 15b253ecdcd72cd3b86b8541e00202529bbc7108 Mon Sep 17 00:00:00 2001 From: Isaacc <122677090+isaacambrogetti@users.noreply.github.com> Date: Fri, 17 Apr 2026 11:53:39 +0200 Subject: [PATCH 366/462] DOC improved description of offset parameter for LocalOutlierFactor (#33773) --- doc/modules/outlier_detection.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/modules/outlier_detection.rst b/doc/modules/outlier_detection.rst index f68e3dc8d9f66..73fea5dd4cfd1 100644 --- a/doc/modules/outlier_detection.rst +++ b/doc/modules/outlier_detection.rst @@ -366,6 +366,10 @@ on new unseen data when LOF is applied for novelty detection, i.e. when the ``novelty`` parameter is set to ``True``, but the result of ``predict`` may differ from that of ``fit_predict``. See :ref:`novelty_with_lof`. +When the ``contamination`` parameter is set, the threshold (called ``offset_``) +is determined as the corresponding percentile of ``negative_outlier_factor_`` +scores on the training data. Samples with scores strictly below this threshold +are classified as outliers. This strategy is illustrated below. From e3ce8d95e3922ff8b6785fc5c233a9afc7a9eaa7 Mon Sep 17 00:00:00 2001 From: Ashutosh Devpura <46817661+AshutoshDevpura@users.noreply.github.com> Date: Fri, 17 Apr 2026 06:43:56 -0400 Subject: [PATCH 367/462] MNT Clean-up deprecations for 1.9: sparse from fowlkes_mallows_score (#33761) --- sklearn/metrics/cluster/_supervised.py | 18 +----------------- .../metrics/cluster/tests/test_supervised.py | 10 ---------- 2 files changed, 1 insertion(+), 27 deletions(-) diff --git a/sklearn/metrics/cluster/_supervised.py b/sklearn/metrics/cluster/_supervised.py index 03ce5e72aa8c3..e815f81de5ac6 100644 --- a/sklearn/metrics/cluster/_supervised.py +++ b/sklearn/metrics/cluster/_supervised.py @@ -23,7 +23,6 @@ get_namespace_and_device, ) from sklearn.utils._param_validation import ( - Hidden, Interval, StrOptions, validate_params, @@ -1190,11 +1189,10 @@ def normalized_mutual_info_score( { "labels_true": ["array-like"], "labels_pred": ["array-like"], - "sparse": ["boolean", Hidden(StrOptions({"deprecated"}))], }, prefer_skip_nested_validation=True, ) -def fowlkes_mallows_score(labels_true, labels_pred, *, sparse="deprecated"): +def fowlkes_mallows_score(labels_true, labels_pred): """Measure the similarity of two clusterings of a set of points. .. versionadded:: 0.18 @@ -1225,13 +1223,6 @@ def fowlkes_mallows_score(labels_true, labels_pred, *, sparse="deprecated"): labels_pred : array-like of shape (n_samples,), dtype=int A clustering of the data into disjoint subsets. - sparse : bool, default=False - Compute contingency matrix internally with sparse matrix. - - .. deprecated:: 1.7 - The ``sparse`` parameter is deprecated and will be removed in 1.9. It has - no effect. - Returns ------- score : float @@ -1265,13 +1256,6 @@ def fowlkes_mallows_score(labels_true, labels_pred, *, sparse="deprecated"): >>> fowlkes_mallows_score([0, 0, 0, 0], [0, 1, 2, 3]) 0.0 """ - # TODO(1.9): remove the sparse parameter - if sparse != "deprecated": - warnings.warn( - "The 'sparse' parameter was deprecated in 1.7 and will be removed in 1.9. " - "It has no effect. Leave it to its default value to silence this warning.", - FutureWarning, - ) labels_true, labels_pred = check_clusterings(labels_true, labels_pred) (n_samples,) = labels_true.shape diff --git a/sklearn/metrics/cluster/tests/test_supervised.py b/sklearn/metrics/cluster/tests/test_supervised.py index b7f0084e5332f..9bd5009ac4c1b 100644 --- a/sklearn/metrics/cluster/tests/test_supervised.py +++ b/sklearn/metrics/cluster/tests/test_supervised.py @@ -518,13 +518,3 @@ def test_normalized_mutual_info_score_bounded(average_method): # non constant, non perfect matching labels nmi = normalized_mutual_info_score(labels2, labels3, average_method=average_method) assert 0 <= nmi < 1 - - -# TODO(1.9): remove -@pytest.mark.parametrize("sparse", [True, False]) -def test_fowlkes_mallows_sparse_deprecated(sparse): - """Check deprecation warning for 'sparse' parameter of fowlkes_mallows_score.""" - with pytest.warns( - FutureWarning, match="The 'sparse' parameter was deprecated in 1.7" - ): - fowlkes_mallows_score([0, 1], [1, 1], sparse=sparse) From 88c3106c257dc9eeed90ee13000871ff5a27c218 Mon Sep 17 00:00:00 2001 From: Ashutosh Devpura <46817661+AshutoshDevpura@users.noreply.github.com> Date: Fri, 17 Apr 2026 07:17:22 -0400 Subject: [PATCH 368/462] MNT Clean-up deprecations for 1.9: Raise for integer dtype in partial_dependence (#33762) --- sklearn/inspection/_partial_dependence.py | 16 +++------ .../tests/test_partial_dependence.py | 36 +++++++------------ 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/sklearn/inspection/_partial_dependence.py b/sklearn/inspection/_partial_dependence.py index 4111f153c74e1..98786550425bd 100644 --- a/sklearn/inspection/_partial_dependence.py +++ b/sklearn/inspection/_partial_dependence.py @@ -3,7 +3,6 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause -import warnings from collections.abc import Iterable import numpy as np @@ -653,7 +652,7 @@ def partial_dependence( if response_method != "decision_function": raise ValueError( "With the 'recursion' method, the response_method must be " - "'decision_function'. Got {}.".format(response_method) + f"'decision_function'. Got {response_method}." ) if sample_weight is not None: @@ -664,7 +663,7 @@ def partial_dependence( # the indexing to be positive. The upper bound will be checked # by _get_column_indices() if np.any(np.less(features, 0)): - raise ValueError("all features must be in [0, {}]".format(X.shape[1] - 1)) + raise ValueError(f"all features must be in [0, {X.shape[1] - 1}]") features_indices = np.asarray( _get_column_indices(X, features), dtype=np.intp, order="C" @@ -717,18 +716,13 @@ def partial_dependence( continue if _safe_indexing(X, feature_idx, axis=1).dtype.kind in "iu": - # TODO(1.9): raise a ValueError instead. - warnings.warn( + raise ValueError( f"The column {feature!r} contains integer data. Partial " "dependence plots are not supported for integer data: this " "can lead to implicit rounding with NumPy arrays or even errors " - "with newer pandas versions. Please convert numerical features" - "to floating point dtypes ahead of time to avoid problems. " - "This will raise ValueError in scikit-learn 1.9.", - FutureWarning, + "with newer pandas versions. Please convert numerical features " + "to floating point dtypes ahead of time to avoid problems." ) - # Do not warn again for other features to avoid spamming the caller. - break X_subset = _safe_indexing(X, features_indices, axis=1) diff --git a/sklearn/inspection/tests/test_partial_dependence.py b/sklearn/inspection/tests/test_partial_dependence.py index 914fed607d5cb..dc5b949ab97ef 100644 --- a/sklearn/inspection/tests/test_partial_dependence.py +++ b/sklearn/inspection/tests/test_partial_dependence.py @@ -3,7 +3,6 @@ """ import re -import warnings import numpy as np import pytest @@ -1144,26 +1143,21 @@ def test_reject_array_with_integer_dtype(): y = np.array([0, 1, 0, 1]) clf = DummyClassifier() clf.fit(X, y) - with pytest.warns( - FutureWarning, match=re.escape("The column 0 contains integer data.") + with pytest.raises( + ValueError, match=re.escape("The column 0 contains integer data.") ): partial_dependence(clf, X, features=0) - - with pytest.warns( - FutureWarning, match=re.escape("The column 1 contains integer data.") + with pytest.raises( + ValueError, match=re.escape("The column 1 contains integer data.") ): partial_dependence(clf, X, features=[1], categorical_features=[0]) - - with pytest.warns( - FutureWarning, match=re.escape("The column 0 contains integer data.") + with pytest.raises( + ValueError, match=re.escape("The column 0 contains integer data.") ): partial_dependence(clf, X, features=[0, 1]) - # The following should not raise as we do not compute numerical partial # dependence on integer columns. - with warnings.catch_warnings(): - warnings.simplefilter("error") - partial_dependence(clf, X, features=1, categorical_features=[1]) + partial_dependence(clf, X, features=1, categorical_features=[1]) def test_reject_pandas_with_integer_dtype(): @@ -1179,22 +1173,18 @@ def test_reject_pandas_with_integer_dtype(): clf = DummyClassifier() clf.fit(X, y) - with pytest.warns( - FutureWarning, match=re.escape("The column 'c' contains integer data.") + with pytest.raises( + ValueError, match=re.escape("The column 'c' contains integer data.") ): partial_dependence(clf, X, features="c") - - with pytest.warns( - FutureWarning, match=re.escape("The column 'c' contains integer data.") + with pytest.raises( + ValueError, match=re.escape("The column 'c' contains integer data.") ): partial_dependence(clf, X, features=["a", "c"]) - # The following should not raise as we do not compute numerical partial # dependence on integer columns. - with warnings.catch_warnings(): - warnings.simplefilter("error") - partial_dependence(clf, X, features=["a"]) - partial_dependence(clf, X, features=["c"], categorical_features=["c"]) + partial_dependence(clf, X, features=["a"]) + partial_dependence(clf, X, features=["c"], categorical_features=["c"]) def test_partial_dependence_empty_categorical_features(): From 7b6d1bd554f1c4b9f3a61b8e2aaeb8b53f8e2a2c Mon Sep 17 00:00:00 2001 From: Ashutosh Devpura <46817661+AshutoshDevpura@users.noreply.github.com> Date: Fri, 17 Apr 2026 07:21:34 -0400 Subject: [PATCH 369/462] MNT Clean-up deprecations for 1.9: default quantile_method of KBinsDiscretizer (#33763) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- sklearn/preprocessing/_discretization.py | 21 ++------ .../tests/test_discretization.py | 54 +++++++++---------- 2 files changed, 31 insertions(+), 44 deletions(-) diff --git a/sklearn/preprocessing/_discretization.py b/sklearn/preprocessing/_discretization.py index 847c388599821..de473834ceb0d 100644 --- a/sklearn/preprocessing/_discretization.py +++ b/sklearn/preprocessing/_discretization.py @@ -59,7 +59,7 @@ class KBinsDiscretizer(TransformerMixin, BaseEstimator): quantile_method : {"inverted_cdf", "averaged_inverted_cdf", "closest_observation", "interpolated_inverted_cdf", "hazen", "weibull", "linear", "median_unbiased", "normal_unbiased"}, - default="linear" + default="averaged_inverted_cdf" Method to pass on to np.percentile calculation when using strategy="quantile". Only `averaged_inverted_cdf` and `inverted_cdf` support the use of `sample_weight != None` when subsampling is not @@ -67,6 +67,9 @@ class KBinsDiscretizer(TransformerMixin, BaseEstimator): .. versionadded:: 1.7 + .. versionchanged:: 1.9 + The default value changed from `"linear"` to `"averaged_inverted_cdf"`. + dtype : {np.float32, np.float64}, default=None The desired data-type for the output. If None, output dtype is consistent with input dtype. Only np.float32 and np.float64 are @@ -196,7 +199,6 @@ class KBinsDiscretizer(TransformerMixin, BaseEstimator): "quantile_method": [ StrOptions( { - "warn", "inverted_cdf", "averaged_inverted_cdf", "closest_observation", @@ -220,7 +222,7 @@ def __init__( *, encode="onehot", strategy="quantile", - quantile_method="warn", + quantile_method="averaged_inverted_cdf", dtype=None, subsample=200_000, random_state=None, @@ -297,20 +299,7 @@ def fit(self, X, y=None, sample_weight=None): bin_edges = np.zeros(n_features, dtype=object) - # TODO(1.9): remove and switch to quantile_method="averaged_inverted_cdf" - # by default. quantile_method = self.quantile_method - if self.strategy == "quantile" and quantile_method == "warn": - warnings.warn( - "The current default behavior, quantile_method='linear', will be " - "changed to quantile_method='averaged_inverted_cdf' in " - "scikit-learn version 1.9 to naturally support sample weight " - "equivalence properties by default. Pass " - "quantile_method='averaged_inverted_cdf' explicitly to silence this " - "warning.", - FutureWarning, - ) - quantile_method = "linear" if ( self.strategy == "quantile" diff --git a/sklearn/preprocessing/tests/test_discretization.py b/sklearn/preprocessing/tests/test_discretization.py index 7463a8608291c..e9892719f92e8 100644 --- a/sklearn/preprocessing/tests/test_discretization.py +++ b/sklearn/preprocessing/tests/test_discretization.py @@ -22,13 +22,13 @@ [ ( "uniform", - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default [[0, 0, 0, 0], [1, 1, 1, 0], [2, 2, 2, 1], [2, 2, 2, 2]], None, ), ( "kmeans", - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default [[0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2]], None, ), @@ -40,13 +40,13 @@ ), ( "uniform", - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default [[0, 0, 0, 0], [1, 1, 1, 0], [2, 2, 2, 1], [2, 2, 2, 2]], [1, 1, 2, 1], ), ( "uniform", - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default [[0, 0, 0, 0], [1, 1, 1, 0], [2, 2, 2, 1], [2, 2, 2, 2]], [1, 1, 1, 1], ), @@ -70,13 +70,13 @@ ), ( "kmeans", - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default [[0, 0, 0, 0], [1, 1, 1, 0], [1, 1, 1, 1], [2, 2, 2, 2]], [1, 0, 3, 1], ), ( "kmeans", - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default [[0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [2, 2, 2, 2]], [1, 1, 1, 1], ), @@ -145,13 +145,13 @@ def test_invalid_n_bins_array(): [ ( "uniform", - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default [[0, 0, 0, 0], [0, 1, 1, 0], [1, 2, 2, 1], [1, 2, 2, 2]], None, ), ( "kmeans", - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default [[0, 0, 0, 0], [0, 0, 0, 0], [1, 1, 1, 1], [1, 2, 2, 2]], None, ), @@ -187,7 +187,7 @@ def test_invalid_n_bins_array(): ), ( "kmeans", - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default [[0, 0, 0, 0], [0, 1, 1, 0], [1, 1, 1, 1], [1, 2, 2, 2]], [1, 0, 3, 1], ), @@ -328,8 +328,20 @@ def test_encode_options(): @pytest.mark.parametrize( "strategy, quantile_method, expected_2bins, expected_3bins, expected_5bins", [ - ("uniform", "warn", [0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 2, 2], [0, 0, 1, 1, 4, 4]), - ("kmeans", "warn", [0, 0, 0, 0, 1, 1], [0, 0, 1, 1, 2, 2], [0, 0, 1, 2, 3, 4]), + ( + "uniform", + "averaged_inverted_cdf", + [0, 0, 0, 0, 1, 1], + [0, 0, 0, 0, 2, 2], + [0, 0, 1, 1, 4, 4], + ), + ( + "kmeans", + "averaged_inverted_cdf", + [0, 0, 0, 0, 1, 1], + [0, 0, 1, 1, 2, 2], + [0, 0, 1, 2, 3, 4], + ), ( "quantile", "averaged_inverted_cdf", @@ -377,7 +389,7 @@ def test_nonuniform_strategies( [0.5, 4.0, -1.5, 0.5], [0.5, 4.0, -1.5, 1.5], ], - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default ), ( "kmeans", @@ -387,7 +399,7 @@ def test_nonuniform_strategies( [-0.125, 3.375, -2.125, 0.5625], [0.75, 4.25, -1.25, 1.625], ], - "warn", # default, will not warn when strategy != "quantile" + "averaged_inverted_cdf", # default ), ( "quantile", @@ -452,7 +464,7 @@ def test_overwrite(): "strategy, expected_bin_edges, quantile_method", [ ("quantile", [0, 1.5, 3], "averaged_inverted_cdf"), - ("kmeans", [0, 1.5, 3], "warn"), + ("kmeans", [0, 1.5, 3], "averaged_inverted_cdf"), ], ) def test_redundant_bins(strategy, expected_bin_edges, quantile_method): @@ -634,20 +646,6 @@ def test_kbinsdiscretizer_subsample(strategy, global_random_seed): ) -def test_quantile_method_future_warnings(): - X = [[-2, 1, -4], [-1, 2, -3], [0, 3, -2], [1, 4, -1]] - with pytest.warns( - FutureWarning, - match="The current default behavior, quantile_method='linear', will be " - "changed to quantile_method='averaged_inverted_cdf' in " - "scikit-learn version 1.9 to naturally support sample weight " - "equivalence properties by default. Pass " - "quantile_method='averaged_inverted_cdf' explicitly to silence this " - "warning.", - ): - KBinsDiscretizer(strategy="quantile").fit(X) - - def test_invalid_quantile_method_with_sample_weight(): X = [[-2, 1, -4], [-1, 2, -3], [0, 3, -2], [1, 4, -1]] expected_msg = ( From 43ad580d12d2d370c8b9e314373224962a8875d9 Mon Sep 17 00:00:00 2001 From: Stefanie Senger <91849487+StefanieSenger@users.noreply.github.com> Date: Fri, 17 Apr 2026 16:05:38 +0200 Subject: [PATCH 370/462] DOC Fix function paths in Array API docs (#33768) --- doc/modules/array_api.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index 5f003d0700195..41ebdc50259e5 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -182,7 +182,7 @@ Metrics - :func:`sklearn.metrics.average_precision_score` - :func:`sklearn.metrics.balanced_accuracy_score` - :func:`sklearn.metrics.brier_score_loss` -- :func:`sklearn.metrics.cluster.calinski_harabasz_score` +- :func:`sklearn.metrics.calinski_harabasz_score` - :func:`sklearn.metrics.cohen_kappa_score` - :func:`sklearn.metrics.confusion_matrix` - :func:`sklearn.metrics.d2_absolute_error_score` @@ -212,8 +212,8 @@ Metrics - :func:`sklearn.metrics.pairwise.chi2_kernel` - :func:`sklearn.metrics.pairwise.cosine_similarity` - :func:`sklearn.metrics.pairwise.cosine_distances` -- :func:`sklearn.metrics.pairwise.pairwise_distances` (only supports "cosine", "euclidean", "manhattan" and "l2" metrics) -- :func:`sklearn.metrics.pairwise.pairwise_distances_argmin` +- :func:`sklearn.metrics.pairwise_distances` (only supports "cosine", "euclidean", "manhattan" and "l2" metrics) +- :func:`sklearn.metrics.pairwise_distances_argmin` - :func:`sklearn.metrics.pairwise.euclidean_distances` (see :ref:`device_support_for_float64`) - :func:`sklearn.metrics.pairwise.laplacian_kernel` - :func:`sklearn.metrics.pairwise.linear_kernel` From c8697f7a48d577f20b3ecb13c7beac08c4b6a8a6 Mon Sep 17 00:00:00 2001 From: Guillaume Lemaitre <guillaume@probabl.ai> Date: Fri, 17 Apr 2026 16:06:54 +0200 Subject: [PATCH 371/462] FIX handling nan during scoring of early-stopping in MLPClassifier (#33774) --- .../sklearn.neural_network/33774.fix.rst | 5 ++++ .../neural_network/_multilayer_perceptron.py | 2 +- sklearn/neural_network/tests/test_mlp.py | 25 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.neural_network/33774.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.neural_network/33774.fix.rst b/doc/whats_new/upcoming_changes/sklearn.neural_network/33774.fix.rst new file mode 100644 index 0000000000000..7bb5d4a537a8b --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.neural_network/33774.fix.rst @@ -0,0 +1,5 @@ +- :class:`neural_network.MLPClassifier` with ``early_stopping=True`` no longer + raises a `TypeError` when ``y`` contains non-numeric class labels (e.g. + strings): validation scoring now checks finiteness only for floating + predictions. + By :user:`Guillaume Lemaitre <glemaitre>`. diff --git a/sklearn/neural_network/_multilayer_perceptron.py b/sklearn/neural_network/_multilayer_perceptron.py index 4a56d4fe43b69..17e6f2219158a 100644 --- a/sklearn/neural_network/_multilayer_perceptron.py +++ b/sklearn/neural_network/_multilayer_perceptron.py @@ -865,7 +865,7 @@ def _score_with_function(self, X, y, sample_weight, score_function): # Input validation would remove feature names, so we disable it y_pred = self._predict(X, check_input=False) - if np.isnan(y_pred).any() or np.isinf(y_pred).any(): + if np.issubdtype(y_pred.dtype, np.floating) and not np.isfinite(y_pred).all(): return np.nan return score_function(y, y_pred, sample_weight=sample_weight) diff --git a/sklearn/neural_network/tests/test_mlp.py b/sklearn/neural_network/tests/test_mlp.py index 72eac916aaeb0..4e1ca92f10c67 100644 --- a/sklearn/neural_network/tests/test_mlp.py +++ b/sklearn/neural_network/tests/test_mlp.py @@ -15,6 +15,7 @@ from sklearn.datasets import ( load_digits, load_iris, + make_classification, make_multilabel_classification, make_regression, ) @@ -831,6 +832,30 @@ def test_early_stopping_stratified(): mlp.fit(X, y) +def test_mlp_early_stopping_string_labels(): + """Check that labels can be strings when `early_stopping=True`. + + Non-regression test for: + https://github.com/scikit-learn/scikit-learn/issues/33760 + """ + X, y = make_classification( + n_samples=200, + n_features=10, + n_classes=3, + n_informative=5, + random_state=42, + ) + labels = np.array(["class_a", "class_b", "class_c"], dtype=object) + y = labels[y] + + mlp = MLPClassifier(early_stopping=True, max_iter=50, random_state=42) + mlp.fit(X, y) + + assert mlp.validation_scores_ is not None + assert len(mlp.validation_scores_) == mlp.n_iter_ + assert np.isfinite(mlp.validation_scores_).all() + + def test_mlp_classifier_dtypes_casting(): # Compare predictions for different dtypes mlp_64 = MLPClassifier( From c1d955e67a9f11a7ff80e1bd2dc8c2c180255f67 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Fri, 17 Apr 2026 16:10:19 +0200 Subject: [PATCH 372/462] DOC better marketing in user guid for Array API and set_output pandas/polars (#33466) --- doc/conf.py | 1 + doc/data_interoperability.rst | 9 +++++++++ doc/dispatching.rst | 8 -------- doc/modules/df_output_transform.rst | 8 ++++++++ doc/user_guide.rst | 2 +- 5 files changed, 19 insertions(+), 9 deletions(-) create mode 100644 doc/data_interoperability.rst delete mode 100644 doc/dispatching.rst create mode 100644 doc/modules/df_output_transform.rst diff --git a/doc/conf.py b/doc/conf.py index 8cfa3ef1f4b4a..dbeaaca45ab28 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -440,6 +440,7 @@ def add_js_css_files(app, pagename, templatename, context, doctree): "documentation": "index", "contents": "index", "preface": "index", + "dispatching": "data_interoperability", "modules/classes": "api/index", "tutorial/machine_learning_map/index": "machine_learning_map", "auto_examples/feature_selection/plot_permutation_test_for_classification": ( diff --git a/doc/data_interoperability.rst b/doc/data_interoperability.rst new file mode 100644 index 0000000000000..82cf19a67da26 --- /dev/null +++ b/doc/data_interoperability.rst @@ -0,0 +1,9 @@ +===================== +Data Interoperability +===================== + +.. toctree:: + :maxdepth: 2 + + modules/df_output_transform + modules/array_api diff --git a/doc/dispatching.rst b/doc/dispatching.rst deleted file mode 100644 index 101e493ee96b7..0000000000000 --- a/doc/dispatching.rst +++ /dev/null @@ -1,8 +0,0 @@ -=========== -Dispatching -=========== - -.. toctree:: - :maxdepth: 2 - - modules/array_api diff --git a/doc/modules/df_output_transform.rst b/doc/modules/df_output_transform.rst new file mode 100644 index 0000000000000..017e1de632e66 --- /dev/null +++ b/doc/modules/df_output_transform.rst @@ -0,0 +1,8 @@ +.. _df_output_transform: + +===================================================== +Pandas/Polars Output for Transformers with set_output +===================================================== + +See `SLEP018 <https://scikit-learn-enhancement-proposals.readthedocs.io/en/latest/slep018/proposal.html>`__ +and :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py`. diff --git a/doc/user_guide.rst b/doc/user_guide.rst index 0c1a6ee66ebf9..eaf0ef3cf04d8 100644 --- a/doc/user_guide.rst +++ b/doc/user_guide.rst @@ -19,6 +19,6 @@ User Guide computing.rst model_persistence.rst common_pitfalls.rst - dispatching.rst + data_interoperability.rst machine_learning_map.rst presentations.rst From 3609526e1e8040a49fbce5de9d88ec34189735a3 Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Fri, 17 Apr 2026 16:23:57 +0200 Subject: [PATCH 373/462] MAINT bump circle ci dependencies (#33785) --- build_tools/circle/doc_environment.yml | 4 +- build_tools/circle/doc_linux-64_conda.lock | 105 +++++++++--------- .../update_environments_and_lock_files.py | 5 +- sklearn/utils/_testing.py | 8 ++ sklearn/utils/tests/test_testing.py | 3 + 5 files changed, 67 insertions(+), 58 deletions(-) diff --git a/build_tools/circle/doc_environment.yml b/build_tools/circle/doc_environment.yml index 6621687fee54d..27a63592e5bbe 100644 --- a/build_tools/circle/doc_environment.yml +++ b/build_tools/circle/doc_environment.yml @@ -4,7 +4,7 @@ channels: - conda-forge dependencies: - - python=3.11 + - python=3.14 - numpy - blas - scipy @@ -30,7 +30,7 @@ dependencies: - numpydoc - sphinx-prompt - plotly - - polars=1.34.0 + - polars - pooch - sphinxext-opengraph - sphinx-remove-toctrees diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 2464e1438ad97..c9e29e93e8e37 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 8ee751e2ee3835d0218c5e31f6b17221595b6def62eaad571cdb80dd568a67db +# input_hash: f7007183330647b43c31a485b766a37201f3827f99e12ab6d756823013915178 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -8,7 +8,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77 https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_10.conda#590b5a14299d67b9669fe5eb1fdd4d3b -https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 +https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 @@ -39,10 +39,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18. https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb -https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 +https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda#7af961ef4aa2c1136e11dd43ded245ab https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c @@ -55,6 +55,7 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f +https://conda.anaconda.org/conda-forge/linux-64/xorg-xorgproto-2025.1-hb03c661_0.conda#aa8d21be4b461ce612d8f5fb791decae https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h280c20c_3.conda#a77f85f77be52ff59391544bfe73390a https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_102.conda#212fe5f1067445544c99dc1c847d032c https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_102.conda#2a307a17309d358c9b42afdd3199ddcc @@ -101,7 +102,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 @@ -122,10 +123,10 @@ https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.3-h8d634f6_0.conda#792d5b6e99677177f5527a758a02bc07 -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.27.0-h8d634f6_0.conda#8397bb8cf4b370f5df7d7ee3d80ea977 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 @@ -135,17 +136,17 @@ https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda#7 https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda#c6b0543676ecb1fb2d7643941fe375f2 https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 -https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a -https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 +https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 +https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2#576d629e47797577ab0f1b351297ef4a https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/click-8.3.2-pyhc90fa1f_0.conda#4d18bc3af7cfcea97bd817164672a08c https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.11.15-py311hd8ed1ab_0.conda#bf0d09d5c2b61aaf7b11c551c8545cfa +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2#961b3a227b437d82ad7054484cfa71b2 https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 https://conda.anaconda.org/conda-forge/noarch/doit-0.37.0-pyhcf101f3_0.conda#37b3d4c558f2bb2b5378c43f4d6f1fb5 @@ -160,29 +161,30 @@ https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda#1269891272187518a0a75c286f7d0bbf https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda#89bf346df77603055d3c8fe5811691e6 -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b965c999135d43a3d0f7bd7d024e26a https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/narwhals-2.19.0-pyhcf101f3_0.conda#b94cbc2227cdca1e9a65d7ad4ee636c1 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b +https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.25.0-pyhd8ed1ab_0.conda#a11ab1f31af799dd93c3a39881528884 -https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f +https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py314h0f05182_0.conda#4f225a966cfee267a79c5cb6382bd121 https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd8ed1ab_1.conda#7d9daffbb8d8e0af0f769dbbcd173a54 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 @@ -191,11 +193,10 @@ https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#4 https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda#23029aae904a2ba587daba708208012f https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda#a61bf9ec79426938ff785eb69dbb1960 https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.1-pyhd8ed1ab_0.conda#d8d30923ccee7525704599efd722aa16 -https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py311h3778330_1.conda#a24add9a3bababee946f3bc1c829acfe -https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py311h57d2397_2.conda#759edfe34f07c5c4565b6c5ec0c7fb17 +https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda#2035f68f96be30dc60a5dfd7452c7941 https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 -https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py311h902ca64_0.conda#3893f7b40738f9fe87510cb4468cdda5 +https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.30.0-py314h2e6c369_0.conda#c1c368b5437b0d1a68f372ccf01cb133 https://conda.anaconda.org/conda-forge/noarch/send2trash-2.1.0-pyha191276_1.conda#28eb91468df04f655a57bcfbb35fc5c5 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 @@ -204,11 +205,11 @@ https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.8.3-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_1.conda#fa839b5ff59e192f411ccc7dae6588bb https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda#73b44a114241e564deb5846e7394bf19 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py314h5bd0f2a_0.conda#dc1ff1e915ab35a06b6fa61efae73ab5 https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda#019a7385be9af33791c989871317e1ed https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda#f6d7aa696c67756a650e91e15e88223c -https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py311h49ec1c0_0.conda#2889f0c0b6a6d7a37bd64ec60f4cc210 +https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py314h5bd0f2a_0.conda#494fdf358c152f9fdd0673c128c2f3dd https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.conda#e7cb0f5745e4c5035a460248334af7eb https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda#6639b6b0d8b5a284f027a2003669aa65 https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda#2841eb5bfc75ce15e9a0054b98dcd64d @@ -220,27 +221,27 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 -https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 +https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda#e1c36c6121a7c9c76f2f148f1e83b983 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda#7c5ebdc286220e8021bf55e6384acd67 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 -https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b +https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda#cf45f4278afd6f4e6d03eda0f435d527 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a -https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.0.0-pyhd8ed1ab_0.conda#724309d702b3a44f59987f9be424c040 +https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda#0ba6225c279baf7ea9473a62ea0ec9ae https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_0.conda#9b47a4cd3aabb73201a2b8ed9f127189 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_1.conda#80daec8cf93185515ac7b5d359e3f929 +https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 @@ -250,7 +251,7 @@ https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda#3e9427ee186846052e81fadde8ebe96a https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.11.15-hd8ed1ab_0.conda#8793751936480e56ce4047b4f54b997f +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 @@ -258,28 +259,25 @@ https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda#17b43cee5cc84969529d5d0b0309b2cb https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda#f1acf5fdefa8300de697982bcb1761c9 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda#af2df4b9108808da3dc76710fe50eae2 -https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py311h49ec1c0_2.conda#6e36e9d2b535c3fbe2e093108df26695 +https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py314h5bd0f2a_2.conda#3cca1b74b2752917b5b65b81f61f0553 https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda#85c4f19f377424eafc4ed7911b291642 https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda#f11a319b9700b203aa14c295858782b6 https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 -https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.0.0-pyhd8ed1ab_0.conda#62fa494c03634a688a28748902579881 +https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.1.0-pyhd8ed1ab_0.conda#e3bffa82b874f8b9a2631bddb3869529 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a -https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda#7b8bace4943e0dc345fc45938826f2b8 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.4-pyhcf101f3_0.conda#e81089ba496151ed0bfe3e9cb196ca11 +https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_2.conda#c6ba2de6b22dedf2f20eba3bde1dbe8e https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e @@ -288,39 +286,42 @@ https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.con https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.1-pyhcf101f3_0.conda#4552b601cf622dea2bb5075baccc2c5b https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.34.0-py310hffdcd12_0.conda#496b18392ef5af544d22d18d91a2a371 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py311hf27b23e_1.conda#b3fb332c110fee191999153ccf69fad2 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda#082985717303dab433c976986c674b35 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda#8368d58342d0825f0843dc6acdd0c483 +https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea -https://conda.anaconda.org/conda-forge/noarch/polars-1.34.0-pyh6a1acc5_0.conda#d398dbcb3312bbebc2b2f3dbb98b4262 +https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda#d5a4e013a30dd8dfde9ab39f45aaf9c1 https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyhe01879c_0.conda#31e11c30bbee1682a55627f953c6725a https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.1-pyhbbac1ac_0.conda#d8f030e3730713c93a358fdb46f08281 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py311h2e04523_0.conda#cfc8f864dea571677095ebae8e6f0c07 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 -https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py311h724c32c_4.conda#d04e508f5a03162c8bab4586a65d00bf -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 +https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py314h1ae5b44_2.conda#63c263894d9cf9540fec26d9e67115f1 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda#2bce0d047658a91b99441390b9b27045 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py311h8032f78_0.conda#138e5d98884407fcc8ccc6088574b1c7 +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py314hb4ffadd_0.conda#41ee6fe2a848876bc9f524c5a500b85b https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda#d79a87dcfa726bcea8e61275feed6f83 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py311h0f3be63_0.conda#21a0139015232dc0edbf6c2179b5ec24 -https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 -https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py311h0372a8f_0.conda#dd92402db25b74b98489a4c144f14b62 -https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.3.3-pyhd8ed1ab_0.conda#cecacab21bc8f4ed17fac11bc8b08cf0 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f +https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 +https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py314hc02f841_0.conda#224e6e308b3df5c0c99d8ca5244bb34c +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.4.11-pyhd8ed1ab_0.conda#e0ed123314d08b63cd1ee95331c67ae3 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py311h38be061_0.conda#08b5a4eac150c688c9f924bcb3317e02 -https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py311h2a99c40_0.conda#557f5d7ca735d89d706742bc19cd7e26 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 +https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py314hda1ea4c_0.conda#50d6faa367ca045c438d3bb25315b476 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.1-pyhcf101f3_0.conda#1f90643873d0cc2f7b0bf2752db71016 @@ -335,7 +336,7 @@ https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda#910f28a05c178feba832f842155cbfff https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-htmlhelp-2.1.0-pyhd8ed1ab_1.conda#e9fb3fe8a5b758b4aff187d434f94f03 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-2.0.0-pyhd8ed1ab_1.conda#00534ebcc0375929b45c3039b5ba7636 -https://conda.anaconda.org/conda-forge/noarch/sphinx-9.0.4-pyhd8ed1ab_0.conda#950eae33376107d143a529d48c363832 +https://conda.anaconda.org/conda-forge/noarch/sphinx-9.1.0-pyhd8ed1ab_0.conda#aabfbc2813712b71ba8beb217a978498 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_1.conda#3bc61f7161d28137797e038263c04c54 https://conda.anaconda.org/conda-forge/noarch/sphinxext-opengraph-0.13.0-pyhd8ed1ab_0.conda#1a159db0a9774bd77c1ea293bcaf17b7 # pip libsass @ https://files.pythonhosted.org/packages/fd/5a/eb5b62641df0459a3291fc206cf5bd669c0feed7814dded8edef4ade8512/libsass-0.23.0-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.whl#sha256=4a218406d605f325d234e4678bd57126a66a88841cb95bee2caeafdc6f138306 diff --git a/build_tools/update_environments_and_lock_files.py b/build_tools/update_environments_and_lock_files.py index 94619e7d35bdb..a89a4d4e91765 100644 --- a/build_tools/update_environments_and_lock_files.py +++ b/build_tools/update_environments_and_lock_files.py @@ -401,10 +401,7 @@ def remove_from(alist, to_remove): "sphinxcontrib-sass", ], "package_constraints": { - "python": "3.11", - # Pinned while https://github.com/pola-rs/polars/issues/25039 is - # not fixed. - "polars": "1.34.0", + "python": "3.14", }, }, { diff --git a/sklearn/utils/_testing.py b/sklearn/utils/_testing.py index e0e4387606db2..dcd4fbdb9825a 100644 --- a/sklearn/utils/_testing.py +++ b/sklearn/utils/_testing.py @@ -1471,6 +1471,14 @@ def to_filterwarning_str(self): WarningInfo( "ignore", message="Attribute s is deprecated", category=DeprecationWarning ), + # sphinx-gallery uses codecs.open(); deprecated in Python 3.14. Remove once + # a sphinx-gallery release includes + # https://github.com/sphinx-gallery/sphinx-gallery/pull/1594 + WarningInfo( + "ignore", + message=r"codecs\.open\(\) is deprecated", + category=DeprecationWarning, + ), # Plotly deprecated something which we're not using, but internally it's used # and needs to be fixed on their side. # https://github.com/plotly/plotly.py/issues/4997 diff --git a/sklearn/utils/tests/test_testing.py b/sklearn/utils/tests/test_testing.py index fdd197712cf48..7e5349869d401 100644 --- a/sklearn/utils/tests/test_testing.py +++ b/sklearn/utils/tests/test_testing.py @@ -1121,6 +1121,9 @@ def check_warnings_as_errors(warning_info, warnings_as_errors): # Special treatment when regex is used if "Pyarrow" in message: message = "\nPyarrow will become a required dependency" + # Regex in _testing.py; emit the real Python 3.14 deprecation text. + elif message == r"codecs\.open\(\) is deprecated": + message = "codecs.open() is deprecated. Use open() instead." warnings.warn( message=message, From 4e88ecfc3722975197b3afc1417e7f1049e33fd0 Mon Sep 17 00:00:00 2001 From: Andy <andymucyo@gmail.com> Date: Sat, 18 Apr 2026 15:24:56 +0200 Subject: [PATCH 374/462] ENH Add support for sparse `importance_getter` in `RFE` and `SelectFromModel` (#33786) Co-authored-by: iambrogetti <isaac.ambrogetti@unifr.ch> Co-authored-by: Isaacc <122677090+isaacambrogetti@users.noreply.github.com> Co-authored-by: Guillaume Lemaitre <guillaume@probabl.ai> --- .../33786.enhancement.rst | 5 ++++ sklearn/feature_selection/_base.py | 9 ++++++-- .../tests/test_from_model.py | 20 ++++++++++++++++ sklearn/feature_selection/tests/test_rfe.py | 23 +++++++++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.feature_selection/33786.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.feature_selection/33786.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.feature_selection/33786.enhancement.rst new file mode 100644 index 0000000000000..aa61e2076bacc --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.feature_selection/33786.enhancement.rst @@ -0,0 +1,5 @@ +- :class:`feature_selection.SelectFromModel` and :class:`feature_selection.RFE` + now support estimators whose feature importance is a sparse matrix or array, notably + by passing a user-defined callable to the parameter `importance_getter`. + By :user:`andymucyo-ops <andymucyo-ops>` and + :user:`isaacambrogetti <isaacambrogetti>`. diff --git a/sklearn/feature_selection/_base.py b/sklearn/feature_selection/_base.py index 462d90aa165c5..b001f84bb5c4b 100644 --- a/sklearn/feature_selection/_base.py +++ b/sklearn/feature_selection/_base.py @@ -8,7 +8,8 @@ from operator import attrgetter import numpy as np -from scipy.sparse import csc_array, issparse +import scipy.sparse +from scipy.sparse import csc_array, csr_array, issparse from sklearn.base import TransformerMixin from sklearn.utils import _safe_indexing, check_array, safe_sqr @@ -246,13 +247,17 @@ def _get_feature_importances(estimator, getter, transform_func=None, norm_order= importances = getter(estimator) + if issparse(importances): + importances = _align_api_if_sparse(csr_array(importances)) + if transform_func is None: return importances elif transform_func == "norm": if importances.ndim == 1: importances = np.abs(importances) else: - importances = np.linalg.norm(importances, axis=0, ord=norm_order) + norm = scipy.sparse.linalg.norm if issparse(importances) else np.linalg.norm + importances = norm(importances, axis=0, ord=norm_order) elif transform_func == "square": if importances.ndim == 1: importances = safe_sqr(importances) diff --git a/sklearn/feature_selection/tests/test_from_model.py b/sklearn/feature_selection/tests/test_from_model.py index f1781f3f2f768..6c075c18aab39 100644 --- a/sklearn/feature_selection/tests/test_from_model.py +++ b/sklearn/feature_selection/tests/test_from_model.py @@ -670,3 +670,23 @@ def test_from_model_estimator_attribute_error(): from_model.fit(data, y).partial_fit(data) assert isinstance(exec_info.value.__cause__, AttributeError) assert inner_msg in str(exec_info.value.__cause__) + + +@pytest.mark.parametrize( + "feature_importance", + [ + lambda estimator: estimator.sparsify().coef_, + lambda estimator: estimator.sparsify().coef_.tocsc(), + ], +) +def test_feature_importance_sparse(feature_importance): + from_model_sparse = SelectFromModel( + estimator=LogisticRegression(), importance_getter=feature_importance + ) + from_model_dense = SelectFromModel(estimator=LogisticRegression()) + + from_model_sparse.fit(data, y) + from_model_dense.fit(data, y) + + assert_array_equal(from_model_sparse.get_support(), from_model_dense.get_support()) + assert_allclose(from_model_sparse.transform(data), from_model_dense.transform(data)) diff --git a/sklearn/feature_selection/tests/test_rfe.py b/sklearn/feature_selection/tests/test_rfe.py index b7d5457202ed3..a559d0d79480e 100644 --- a/sklearn/feature_selection/tests/test_rfe.py +++ b/sklearn/feature_selection/tests/test_rfe.py @@ -753,3 +753,26 @@ def test_results_per_cv_in_rfecv(global_random_seed): assert len(rfecv.cv_results_["split1_ranking"]) == len( rfecv.cv_results_["split2_ranking"] ) + + +@pytest.mark.parametrize( + "feature_importance", + [ + lambda estimator: estimator.sparsify().coef_, + lambda estimator: estimator.sparsify().coef_.tocsc(), + ], +) +def test_rfe_sparse_coef(feature_importance): + X = [[0, 1, 3], [1, 0, 0], [2, 0, 4], [0, 2, 4]] + y = [0, 1, 2, 3] + + estimator = LogisticRegression() + selector_sparse = RFE( + estimator, n_features_to_select=1, importance_getter=feature_importance + ) + selector_dense = RFE(estimator, n_features_to_select=1) + selector_sparse.fit(X, y) + selector_dense.fit(X, y) + + assert_array_equal(selector_sparse.support_, selector_dense.support_) + assert_array_equal(selector_sparse.ranking_, selector_dense.ranking_) From 52673b18536087b0642c31e6bcfa9408895ddb2e Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 20 Apr 2026 04:08:14 -0400 Subject: [PATCH 375/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33803) Co-authored-by: Lock file bot <noreply@github.com> --- ...a_forge_cuda_array-api_linux-64_conda.lock | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index b4859a901e859..35a2773d5f4eb 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -57,7 +57,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb9d3cd8_0.conda#db63358239cbe1ff86242406d440e44a https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c @@ -70,6 +70,7 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f +https://conda.anaconda.org/conda-forge/linux-64/xorg-xorgproto-2025.1-hb03c661_0.conda#aa8d21be4b461ce612d8f5fb791decae https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.13-h2c9d079_1.conda#3c3d02681058c3d206b562b2e3bc337f https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.2-h8b1a151_0.conda#f16f498641c9e05b645fe65902df661a @@ -108,7 +109,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libudev1-260.1-h6569c3e_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 -https://conda.anaconda.org/conda-forge/linux-64/nccl-2.29.3.1-h4d09622_0.conda#71546ecb7c830d277af20cac43a5bdd0 +https://conda.anaconda.org/conda-forge/linux-64/nccl-2.29.7.1-h8b5a6f3_0.conda#b093fe1438c5e5a1fd38850df59cf699 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 @@ -122,7 +123,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.cond https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-hc87160b_0.conda#dde6a3e4fe6bb2ecd2a7050dd1e701fb https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_1.conda#55a83761db33f82d92d7d7a4a61662e5 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca @@ -141,7 +142,7 @@ https://conda.anaconda.org/rapidsai/linux-64/librmm-26.04.00-cuda12_260408_48b36 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 @@ -169,7 +170,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2 https://conda.anaconda.org/conda-forge/linux-64/libcusparse-dev-12.5.10.65-hecca717_2.conda#db94469fbd554c107acc3afd0af5d8ec https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-26.04.00-cuda12_260408_b01e3028.conda#4c79a5c4309aa770d00749683f941c70 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df @@ -187,32 +188,32 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.2-pyhc364b38_0.conda#63c7ba46fbfc291fab512005c1753041 +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.3-pyhc364b38_0.conda#a6ec14cbc8d512bfd94404e0f8d7338f https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b +https://conda.anaconda.org/conda-forge/noarch/filelock-3.29.0-pyhd8ed1ab_0.conda#8fa8358d022a3a9bd101384a808044c6 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-dev-11.7.5.82-h676940d_2.conda#0fe12e558abf507458bcec839e29778d https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.49.00-cuda12_260408_8d47a9ff.conda#b8ddfc6e13aa7b755392fe8cb6f9250a https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.595.45-pyhd8ed1ab_1.conda#dc8587ae654e96031728802016e8258c https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -246,8 +247,8 @@ https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.cond https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_0.conda#9b47a4cd3aabb73201a2b8ed9f127189 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_1.conda#80daec8cf93185515ac7b5d359e3f929 +https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 @@ -263,26 +264,27 @@ https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_ https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h4c8aef7_3.conda#798a499cf76e530a992365d557ba5827 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.conda#8d3dbe5292af711edd6df92c68e55a89 +https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_2.conda#c6ba2de6b22dedf2f20eba3bde1dbe8e https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_1.conda#5abdb958cf8cc0b43cf078d0559f7969 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 -https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda#d5a4e013a30dd8dfde9ab39f45aaf9c1 +https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_9_cpu.conda#b3ba3597c481a636fc161185819cf6b1 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 From 4a35782d10ca520576e6b05b0e7c0521e2dfb1d7 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 20 Apr 2026 04:08:49 -0400 Subject: [PATCH 376/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33802) Co-authored-by: Lock file bot <noreply@github.com> --- .../github/pylatest_pip_scipy_dev_linux-64_conda.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index 9f4975fe2f105..b9b5abee1cdc2 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -25,7 +25,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#60 https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f @@ -40,9 +40,9 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip imagesize @ https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl#sha256=5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip markupsafe @ https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 -# pip meson @ https://files.pythonhosted.org/packages/0b/78/7d049e63e624d51d0065191dae101a1e36d5d3a2360633772d9ad8afb2d5/meson-1.10.2-py3-none-any.whl#sha256=5f84ef186e6e788d9154db63620fc61b3ece69f643b94b43c8b9203c43d89b36 +# pip meson @ https://files.pythonhosted.org/packages/08/84/1ae2022a3562ac011c80c090e387a07e189d077b01fe58a266759b8fc2ff/meson-1.11.0-py3-none-any.whl#sha256=9774eb62bbf2cb8043aa3feb771c09b510d112c0c382221e29aea7453ecce753 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa -# pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +# pip packaging @ https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl#sha256=5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f # pip platformdirs @ https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl#sha256=e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl#sha256=81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 From 06aded051fe6c7c9970b7e13c3669f952a799831 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 20 Apr 2026 04:44:26 -0400 Subject: [PATCH 377/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33801) Co-authored-by: Lock file bot <noreply@github.com> --- .../github/pylatest_free_threaded_linux-64_conda.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index 80bef3b3c1bfe..7c45329bf72db 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -28,7 +28,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.c https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e @@ -39,8 +39,8 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.con https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 From 9ca303d01457e051ac959a05304ca2f41934a96b Mon Sep 17 00:00:00 2001 From: Adrin Jalali <adrin.jalali@gmail.com> Date: Tue, 21 Apr 2026 12:43:33 +0200 Subject: [PATCH 378/462] FIX correctly set loss Cy* classe' __module__ (#33770) --- sklearn/_loss/meson.build | 6 ++- sklearn/_loss/tests/test_loss.py | 24 +++++++++ sklearn/cluster/_hdbscan/meson.build | 9 +++- .../_hist_gradient_boosting/meson.build | 9 +++- sklearn/tests/test_build.py | 54 +++++++++++++++++++ 5 files changed, 99 insertions(+), 3 deletions(-) diff --git a/sklearn/_loss/meson.build b/sklearn/_loss/meson.build index a4b3425a21cd2..7add6d48d231d 100644 --- a/sklearn/_loss/meson.build +++ b/sklearn/_loss/meson.build @@ -1,6 +1,10 @@ # .pyx is generated, so this is needed to make Cython compilation work +# We add sklearn_root_cython_tree and __init__.py so Cython can detect the +# package hierarchy and set the correct __module__ on extension types. _loss_cython_tree = [ - fs.copyfile('_loss.pxd') + sklearn_root_cython_tree, + fs.copyfile('__init__.py'), + fs.copyfile('_loss.pxd'), ] _loss_pyx = custom_target( diff --git a/sklearn/_loss/tests/test_loss.py b/sklearn/_loss/tests/test_loss.py index 07329c06f7249..a8854195b0018 100644 --- a/sklearn/_loss/tests/test_loss.py +++ b/sklearn/_loss/tests/test_loss.py @@ -1,3 +1,4 @@ +import inspect import pickle import numpy as np @@ -13,6 +14,7 @@ from scipy.special import logsumexp from sklearn import config_context +from sklearn._loss import _loss as _loss_module from sklearn._loss.link import IdentityLink, _inclusive_low_high from sklearn._loss.loss import ( _LOSSES, @@ -1505,3 +1507,25 @@ def test_log1pexp(namespace, device_name, dtype_name): rel=1e-5 if dtype_name == "float32" else 1e-12, abs=0, ) + + +def test_cy_loss_classes_module(): + """Check that Cython extension types in _loss have the correct __module__. + + When _loss_cython_tree in meson.build is missing __init__.py files, Cython + can not detect the package hierarchy and set __module__ = '_loss' instead + of 'sklearn._loss._loss' on all Cy* extension types, e.g. + `CyHalfMultinomialLoss`. This breaks downstream tools like skops that rely + on __module__ for serialization. + """ + cy_classes = [ + obj + for name, obj in inspect.getmembers(_loss_module, inspect.isclass) + if name.startswith("Cy") + ] + assert len(cy_classes) > 0, "No Cy* classes found in sklearn._loss._loss" + for cls in cy_classes: + assert cls.__module__ == "sklearn._loss._loss", ( + f"{cls.__name__}.__module__ == {cls.__module__!r}, " + f"expected 'sklearn._loss._loss'" + ) diff --git a/sklearn/cluster/_hdbscan/meson.build b/sklearn/cluster/_hdbscan/meson.build index 8d880b39a4db5..64be26f2c28b3 100644 --- a/sklearn/cluster/_hdbscan/meson.build +++ b/sklearn/cluster/_hdbscan/meson.build @@ -1,3 +1,10 @@ +# We add sklearn_root_cython_tree and __init__.py so Cython can detect the +# package hierarchy and set the correct __module__ on extension types. +cluster_hdbscan_cython_tree = [ + sklearn_root_cython_tree, + fs.copyfile('__init__.py'), +] + cluster_hdbscan_extension_metadata = { '_linkage': {'sources': [cython_gen.process('_linkage.pyx'), metrics_cython_tree]}, '_reachability': {'sources': [cython_gen.process('_reachability.pyx')]}, @@ -7,7 +14,7 @@ cluster_hdbscan_extension_metadata = { foreach ext_name, ext_dict : cluster_hdbscan_extension_metadata py.extension_module( ext_name, - ext_dict.get('sources'), + [ext_dict.get('sources'), cluster_hdbscan_cython_tree], dependencies: [np_dep], subdir: 'sklearn/cluster/_hdbscan', install: true diff --git a/sklearn/ensemble/_hist_gradient_boosting/meson.build b/sklearn/ensemble/_hist_gradient_boosting/meson.build index 122a2102800f3..1114b7719a2f4 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/meson.build +++ b/sklearn/ensemble/_hist_gradient_boosting/meson.build @@ -1,3 +1,10 @@ +# We add sklearn_root_cython_tree and __init__.py so Cython can detect the +# package hierarchy and set the correct __module__ on extension types. +hist_gradient_boosting_cython_tree = [ + sklearn_root_cython_tree, + fs.copyfile('__init__.py'), +] + hist_gradient_boosting_extension_metadata = { '_gradient_boosting': {'sources': [cython_gen.process('_gradient_boosting.pyx')], 'dependencies': [openmp_dep]}, @@ -12,7 +19,7 @@ hist_gradient_boosting_extension_metadata = { foreach ext_name, ext_dict : hist_gradient_boosting_extension_metadata py.extension_module( ext_name, - ext_dict.get('sources'), + [ext_dict.get('sources'), hist_gradient_boosting_cython_tree], dependencies: ext_dict.get('dependencies', []), subdir: 'sklearn/ensemble/_hist_gradient_boosting', install: true diff --git a/sklearn/tests/test_build.py b/sklearn/tests/test_build.py index 40a960cba6283..c86032c6fafbd 100644 --- a/sklearn/tests/test_build.py +++ b/sklearn/tests/test_build.py @@ -1,12 +1,66 @@ +import importlib +import inspect import os +import pkgutil import textwrap import pytest +import sklearn from sklearn import __version__ from sklearn.utils._openmp_helpers import _openmp_parallelism_enabled +@pytest.mark.thread_unsafe # import side-effects +def test_extension_type_module(): + """Check that Cython extension types have a correct ``__module__``. + + When a subpackage containing Cython extension types has a misconfigured + ``meson.build`` (e.g. missing ``__init__.py`` in its Cython tree), Cython + cannot detect the package hierarchy and sets ``__module__`` to just the + submodule name (e.g. ``'_loss'``) instead of the fully qualified + ``'sklearn._loss._loss'``. This breaks downstream tools like skops that + rely on ``__module__`` for serialization. + """ + sklearn_path = [os.path.dirname(sklearn.__file__)] + failures = [] + for _, modname, ispkg in pkgutil.walk_packages( + path=sklearn_path, prefix="sklearn.", onerror=lambda _: None + ): + # Packages are directories, not modules that can hold extension + # types. ``tests`` and ``externals`` (vendored third-party code) are + # out of scope for this check. + if ispkg or ".tests." in modname or ".externals." in modname: + continue + mod = importlib.import_module(modname) + mod_file = getattr(mod, "__file__", "") or "" + # Only compiled extension modules can produce the misconfigured + # ``__module__`` this test guards against. Pure-Python modules get + # the correct ``__module__`` from the import system by construction. + if not mod_file.endswith((".so", ".pyd")): + continue + for name, cls in inspect.getmembers(mod, inspect.isclass): + try: + cls_file = inspect.getfile(cls) + except TypeError: # pragma: no cover + # Raised for built-in types (``object``, stdlib C types) that + # have no source file — they were not defined in ``mod``. + continue # pragma: no cover + # Skip classes imported into ``mod`` from elsewhere (e.g. numpy, + # scipy, or another sklearn module). Only classes whose source + # file *is* this extension's .so are candidates for the bug. + if cls_file != mod_file: + continue + if cls.__module__ != modname: + failures.append( # pragma: no cover + f"{modname}.{name}.__module__ == {cls.__module__!r}, " + f"expected {modname!r}" + ) + assert not failures, "Extension types with incorrect __module__:\n" + "\n".join( + failures + ) + + def test_openmp_parallelism_enabled(): # Check that sklearn is built with OpenMP-based parallelism enabled. # This test can be skipped by setting the environment variable From 865e5cbd04b4028d35be0846dd57272254859767 Mon Sep 17 00:00:00 2001 From: "Christine P. Chai" <star1327p@gmail.com> Date: Wed, 22 Apr 2026 02:08:54 -0700 Subject: [PATCH 379/462] DOC: Add URL to log_loss reference (#33814) --- sklearn/metrics/_classification.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 0c1ac1eb7a04f..88ff99adca3a3 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -3408,8 +3408,9 @@ def log_loss( References ---------- - C.M. Bishop (2006). Pattern Recognition and Machine Learning. Springer, - p. 209. + C.M. Bishop (2006). `Pattern Recognition and Machine Learning + <https://www.microsoft.com/en-us/research/wp-content/uploads/2006/01/Bishop-Pattern-Recognition-and-Machine-Learning-2006.pdf>`_. + Springer, p. 209. Examples -------- From ad136afbe4d316f219d8d770d15a76a1b5e9cd05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Wed, 22 Apr 2026 12:50:54 +0200 Subject: [PATCH 380/462] MNT Clean-up deprecations for 1.9 in RocCurveDisplay (#33823) --- sklearn/metrics/_plot/roc_curve.py | 54 ++----------------- .../_plot/tests/test_common_curve_display.py | 4 -- .../_plot/tests/test_roc_curve_display.py | 25 --------- 3 files changed, 3 insertions(+), 80 deletions(-) diff --git a/sklearn/metrics/_plot/roc_curve.py b/sklearn/metrics/_plot/roc_curve.py index 4d68594fac24d..4cf2257f64435 100644 --- a/sklearn/metrics/_plot/roc_curve.py +++ b/sklearn/metrics/_plot/roc_curve.py @@ -8,8 +8,6 @@ _BinaryClassifierCurveDisplayMixin, _check_param_lengths, _convert_to_list_leaving_none, - _deprecate_estimator_name, - _deprecate_y_pred_parameter, _despine, _validate_style_kwargs, ) @@ -79,13 +77,6 @@ class RocCurveDisplay(_BinaryClassifierCurveDisplayMixin): .. versionadded:: 0.24 - estimator_name : str, default=None - Name of estimator. If None, the estimator name is not shown. - - .. deprecated:: 1.7 - `estimator_name` is deprecated and will be removed in 1.9. Use `name` - instead. - Attributes ---------- line_ : matplotlib Artist or list of matplotlib Artists @@ -141,12 +132,11 @@ def __init__( roc_auc=None, name=None, pos_label=None, - estimator_name="deprecated", ): self.fpr = fpr self.tpr = tpr self.roc_auc = roc_auc - self.name = _deprecate_estimator_name(estimator_name, name, "1.7") + self.name = name self.pos_label = pos_label def _validate_plot_params(self, *, ax, name): @@ -176,7 +166,6 @@ def plot( plot_chance_level=False, chance_level_kw=None, despine=False, - **kwargs, ): """Plot visualization. @@ -231,13 +220,6 @@ def plot( .. versionadded:: 1.6 - **kwargs : dict - Keyword arguments to be passed to matplotlib's `plot`. - - .. deprecated:: 1.7 - kwargs is deprecated and will be removed in 1.9. Pass matplotlib - arguments to `curve_kwargs` as a dictionary instead. - Returns ------- display : :class:`~sklearn.metrics.RocCurveDisplay` @@ -260,7 +242,6 @@ def plot( "linestyle": "--", "color": "blue", }, - **kwargs, ) default_chance_level_line_kw = { @@ -329,7 +310,6 @@ def from_estimator( plot_chance_level=False, chance_level_kw=None, despine=False, - **kwargs, ): """Create a ROC Curve display from an estimator. @@ -399,13 +379,6 @@ def from_estimator( .. versionadded:: 1.6 - **kwargs : dict - Keyword arguments to be passed to matplotlib's `plot`. - - .. deprecated:: 1.7 - kwargs is deprecated and will be removed in 1.9. Pass matplotlib - arguments to `curve_kwargs` as a dictionary instead. - Returns ------- display : :class:`~sklearn.metrics.RocCurveDisplay` @@ -457,7 +430,6 @@ def from_estimator( plot_chance_level=plot_chance_level, chance_level_kw=chance_level_kw, despine=despine, - **kwargs, ) @classmethod @@ -475,8 +447,6 @@ def from_predictions( plot_chance_level=False, chance_level_kw=None, despine=False, - y_pred="deprecated", - **kwargs, ): """Plot ROC curve given the true and predicted values. @@ -543,22 +513,6 @@ class or non-thresholded decision values (as returned by .. versionadded:: 1.6 - y_pred : array-like of shape (n_samples,) - Target scores, can either be probability estimates of the positive - class or non-thresholded decision values (as returned by - :term:`decision_function` on some classifiers). - - .. deprecated:: 1.7 - `y_pred` is deprecated and will be removed in 1.9. Use - `y_score` instead. - - **kwargs : dict - Additional keywords arguments passed to matplotlib `plot` function. - - .. deprecated:: 1.7 - kwargs is deprecated and will be removed in 1.9. Pass matplotlib - arguments to `curve_kwargs` as a dictionary instead. - Returns ------- display : :class:`~sklearn.metrics.RocCurveDisplay` @@ -589,7 +543,6 @@ class or non-thresholded decision values (as returned by <...> >>> plt.show() """ - y_score = _deprecate_y_pred_parameter(y_score, y_pred, "1.7") pos_label_validated, name = cls._validate_from_predictions_params( y_true, y_score, sample_weight=sample_weight, pos_label=pos_label, name=name ) @@ -617,7 +570,6 @@ class or non-thresholded decision values (as returned by plot_chance_level=plot_chance_level, chance_level_kw=chance_level_kw, despine=despine, - **kwargs, ) @classmethod @@ -753,7 +705,7 @@ def from_cv_results( cv_results["estimator"], cv_results["indices"]["test"] ): y_true = _safe_indexing(y, test_indices) - y_pred, pos_label_ = _get_response_values_binary( + y_score, pos_label_ = _get_response_values_binary( estimator, _safe_indexing(X, test_indices), response_method=response_method, @@ -766,7 +718,7 @@ def from_cv_results( ) fpr, tpr, _ = roc_curve( y_true, - y_pred, + y_score, pos_label=pos_label_, sample_weight=sample_weight_fold, drop_intermediate=drop_intermediate, diff --git a/sklearn/metrics/_plot/tests/test_common_curve_display.py b/sklearn/metrics/_plot/tests/test_common_curve_display.py index 124c85b8b4205..b9433571cbef8 100644 --- a/sklearn/metrics/_plot/tests/test_common_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_common_curve_display.py @@ -802,8 +802,6 @@ def test_display_from_cv_results_curve_kwargs_default_kwargs( PrecisionRecallDisplay, {"precision": np.array([1, 0.5, 0]), "recall": np.array([0, 0.5, 1])}, ), - # TODO(1.9): Remove - (RocCurveDisplay, {"fpr": np.array([0, 0.5, 1]), "tpr": np.array([0, 0.5, 1])}), ], ) def test_display_estimator_name_deprecation(pyplot, Display, display_kwargs): @@ -820,8 +818,6 @@ def test_display_estimator_name_deprecation(pyplot, Display, display_kwargs): PrecisionRecallDisplay, {"precision": np.array([1, 0.5, 0]), "recall": np.array([0, 0.5, 1])}, ), - # TODO(1.9): Remove - (RocCurveDisplay, {"fpr": np.array([0, 0.5, 1]), "tpr": np.array([0, 0.5, 1])}), ], ) @pytest.mark.parametrize( diff --git a/sklearn/metrics/_plot/tests/test_roc_curve_display.py b/sklearn/metrics/_plot/tests/test_roc_curve_display.py index 4bb7a89e236ad..68699dac9c7cb 100644 --- a/sklearn/metrics/_plot/tests/test_roc_curve_display.py +++ b/sklearn/metrics/_plot/tests/test_roc_curve_display.py @@ -535,31 +535,6 @@ def _check_auc(display, constructor_name, pos_label): ) -# TODO(1.9): remove -def test_y_score_and_y_pred_specified_error(pyplot): - """1. Check that an error is raised when both y_score and y_pred are specified. - 2. Check that a warning is raised when y_pred is specified. - """ - y_true = np.array([0, 1, 1, 0]) - y_score = np.array([0.1, 0.4, 0.35, 0.8]) - y_pred = np.array([0.2, 0.3, 0.5, 0.1]) - - with pytest.raises( - ValueError, match="`y_pred` and `y_score` cannot be both specified" - ): - RocCurveDisplay.from_predictions(y_true, y_score=y_score, y_pred=y_pred) - - with pytest.warns(FutureWarning, match="y_pred was deprecated in 1.7"): - display_y_pred = RocCurveDisplay.from_predictions(y_true, y_pred=y_score) - desired_fpr, desired_fnr, _ = roc_curve(y_true, y_score) - assert_allclose(display_y_pred.fpr, desired_fpr) - assert_allclose(display_y_pred.tpr, desired_fnr) - - display_y_score = RocCurveDisplay.from_predictions(y_true, y_score) - assert_allclose(display_y_score.fpr, desired_fpr) - assert_allclose(display_y_score.tpr, desired_fnr) - - @pytest.mark.parametrize("despine", [True, False]) @pytest.mark.parametrize( "constructor_name", ["from_estimator", "from_predictions", "from_cv_results"] From 9d20a66833d9b28e3359d14de56a1c4facf9b30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Wed, 22 Apr 2026 14:27:02 +0200 Subject: [PATCH 381/462] MNT Clean-up deprecations for 1.9: force_int_remainder_cols in ColumnTransformer (2) (#33826) --- sklearn/utils/_indexing.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sklearn/utils/_indexing.py b/sklearn/utils/_indexing.py index 6ac7bb01aaa1c..7931c75a65360 100644 --- a/sklearn/utils/_indexing.py +++ b/sklearn/utils/_indexing.py @@ -4,7 +4,6 @@ import numbers import sys import warnings -from collections import UserList from itertools import compress, islice import numpy as np @@ -236,9 +235,7 @@ def _determine_key_type(key, accept_slice=True): if key_start_type is not None: return key_start_type return key_stop_type - # TODO(1.9) remove UserList when the force_int_remainder_cols param - # of ColumnTransformer is removed - if isinstance(key, (list, tuple, UserList)): + if isinstance(key, (list, tuple)): unique_key = set(key) key_type = {_determine_key_type(elt) for elt in unique_key} if not key_type: From 199b55ec0620e2ddd034a75ac0ebd5f4e5e9c946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Paugam?= <35327799+FrancoisPgm@users.noreply.github.com> Date: Wed, 22 Apr 2026 14:37:33 +0200 Subject: [PATCH 382/462] MNT Clean-up deprecations for 1.9: quantile_method in KBinsDiscretizer (2) (#33828) --- sklearn/tests/test_docstring_parameters.py | 4 ---- sklearn/utils/_test_common/instance_generator.py | 16 ---------------- 2 files changed, 20 deletions(-) diff --git a/sklearn/tests/test_docstring_parameters.py b/sklearn/tests/test_docstring_parameters.py index 4b6a2636f0831..d8b6fa0361ffd 100644 --- a/sklearn/tests/test_docstring_parameters.py +++ b/sklearn/tests/test_docstring_parameters.py @@ -224,10 +224,6 @@ def test_fit_docstring_attributes(name, Estimator): elif Estimator.__name__ == "TSNE": # default raises an error, perplexity must be less than n_samples est.set_params(perplexity=2) - # TODO(1.9) remove - elif Estimator.__name__ == "KBinsDiscretizer": - # default raises a FutureWarning if quantile method is at default "warn" - est.set_params(quantile_method="averaged_inverted_cdf") # TODO(1.10) remove elif Estimator.__name__ == "MDS": # default raises a FutureWarning diff --git a/sklearn/utils/_test_common/instance_generator.py b/sklearn/utils/_test_common/instance_generator.py index 6c040acff48c4..bf77a4514aa9e 100644 --- a/sklearn/utils/_test_common/instance_generator.py +++ b/sklearn/utils/_test_common/instance_generator.py @@ -585,7 +585,6 @@ GraphicalLasso: {"check_array_api_input": dict(max_iter=5, alpha=1.0)}, IncrementalPCA: {"check_dict_unchanged": dict(batch_size=10, n_components=1)}, Isomap: {"check_dict_unchanged": dict(n_components=1)}, - # TODO(1.9) simplify when averaged_inverted_cdf is the default KBinsDiscretizer: { "check_sample_weight_equivalence_on_dense_data": [ # Using subsample != None leads to a stochastic fit that is not @@ -600,21 +599,6 @@ # The "kmeans" strategy leads to a stochastic fit that is not # handled by the check_sample_weight_equivalence test. ], - "check_sample_weights_list": dict( - strategy="quantile", quantile_method="averaged_inverted_cdf" - ), - "check_sample_weights_pandas_series": dict( - strategy="quantile", quantile_method="averaged_inverted_cdf" - ), - "check_sample_weights_shape": dict( - strategy="quantile", quantile_method="averaged_inverted_cdf" - ), - "check_sample_weights_not_an_array": dict( - strategy="quantile", quantile_method="averaged_inverted_cdf" - ), - "check_sample_weights_not_overwritten": dict( - strategy="quantile", quantile_method="averaged_inverted_cdf" - ), }, KernelPCA: { "check_dict_unchanged": dict(n_components=1), From 9bfc879ad92d07d14588340acfb29d121d222f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= <deamarialeon@gmail.com> Date: Wed, 22 Apr 2026 23:29:14 +0200 Subject: [PATCH 383/462] DOC FIX - Add scroll to HTML displays (#33821) --- sklearn/utils/_repr_html/estimator.css | 8 ++++++++ sklearn/utils/_repr_html/estimator.py | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sklearn/utils/_repr_html/estimator.css b/sklearn/utils/_repr_html/estimator.css index dbc62ee9987ec..3c7f9aa2b4c2a 100644 --- a/sklearn/utils/_repr_html/estimator.css +++ b/sklearn/utils/_repr_html/estimator.css @@ -414,3 +414,11 @@ div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover, /* fitted */ background-color: var(--sklearn-color-fitted-level-3); } + +.sk-top-container.sk-global { + /* pydata-sphinx-theme hides overflow, so scrolling is disabled. + We need to set it to !important and add tabindex="0" in the HTML + to allow keyboard-only users to navigate the display. */ + overflow-x: scroll !important; + max-width: 100%; +} diff --git a/sklearn/utils/_repr_html/estimator.py b/sklearn/utils/_repr_html/estimator.py index a6e1ec33d8c4b..dc8e6ac62fd92 100644 --- a/sklearn/utils/_repr_html/estimator.py +++ b/sklearn/utils/_repr_html/estimator.py @@ -540,7 +540,8 @@ def estimator_html_repr(estimator): html_template = ( f"<style>{_CSS_STYLE}</style>" f"<body>" - f'<div id="{container_id}" class="sk-top-container sk-global">' + # we need tabindex="0" to make it 'focusable' + f'<div id="{container_id}" tabindex="0" class="sk-top-container sk-global">' '<div class="sk-text-repr-fallback">' f"<pre>{html.escape(estimator_str)}</pre><b>{fallback_msg}</b>" "</div>" From 4b50d5ed26a1627dad41242a5fa88cbfd6c8403c Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Wed, 22 Apr 2026 23:39:41 +0200 Subject: [PATCH 384/462] DOC fix typos and unify spelling in `governance.rst` (#33807) --- doc/governance.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/governance.rst b/doc/governance.rst index cbe35c0ebe0a4..e0bc1a3503710 100644 --- a/doc/governance.rst +++ b/doc/governance.rst @@ -98,7 +98,7 @@ The following teams form the core contributors group: care. Being a maintainer allows contributors to more easily carry on with their project related activities by giving them direct access to the project's repository. Maintainers are expected to review code contributions, merge - approved pull requests, cast votes for and against merging a pull-request, + approved pull requests, cast votes for and against merging a pull request, and to be involved in deciding major changes to the API. Technical Committee @@ -156,11 +156,11 @@ are made according to the following rules: * **Code changes and major documentation changes** require +1 by two core contributors, no -1 by a core contributor (lazy - consensus), happens on the issue of pull-request page. + consensus), happens on the issue or pull request page. * **Changes to the API principles and changes to dependencies or supported versions** follow the decision-making process outlined above. In particular - changes to API principles are backed via a :ref:`slep`. Smaller decisions + changes to API principles are backed via :ref:`slep`. Smaller decisions like supported versions can happen on a GitHub issue or pull request. * **Changes to the governance model** follow the process outlined in `SLEP020 @@ -173,15 +173,15 @@ the decision making procedure outlined above. Governance Model Changes ------------------------ -Governance model changes occur through an enhancement proposal or a GitHub Pull -Request. An enhancement proposal will go through "**the decision-making process**" +Governance model changes occur through an enhancement proposal or a GitHub pull +request. An enhancement proposal will go through "**the decision-making process**" described in the previous section. Alternatively, an author may propose a change -directly to the governance model with a GitHub Pull Request. Logistically, an -author can open a Draft Pull Request for feedback and follow up with a new -revised Pull Request for voting. Once that author is happy with the state of the -Pull Request, they can call for a vote on the public mailing list. During the -one-month voting period, the Pull Request can not change. A Pull Request -Approval will count as a positive vote, and a "Request Changes" review will +directly to the governance model with a GitHub pull request. Logistically, an +author can open a draft pull request for feedback and follow up with a new +revised pull request for voting. Once that author is happy with the state of the +pull request, they can call for a vote on the public mailing list. During the +one-month voting period, the pull request can not change. A pull request +approval will count as a positive vote, and a "Request Changes" review will count as a negative vote. If two-thirds of the cast votes are positive, then the governance model change is accepted. @@ -192,7 +192,7 @@ Enhancement proposals (SLEPs) For all votes, a proposal must have been made public and discussed before the vote. Such proposal must be a consolidated document, in the form of a "Scikit-Learn Enhancement Proposal" (SLEP), rather than a long discussion on an -issue. A SLEP must be submitted as a pull-request to `enhancement proposals +issue. A SLEP must be submitted as a pull request to `enhancement proposals <https://scikit-learn-enhancement-proposals.readthedocs.io>`_ using the `SLEP template <https://scikit-learn-enhancement-proposals.readthedocs.io/en/latest/slep_template.html>`_. From bd386059165714f18d7576254af27caba73582ec Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Wed, 22 Apr 2026 23:41:35 +0200 Subject: [PATCH 385/462] DOC Update classification probability example to use default colors (#33808) --- examples/classification/plot_classification_probability.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/classification/plot_classification_probability.py b/examples/classification/plot_classification_probability.py index 54f9095d0b8e2..413b02fdff88a 100644 --- a/examples/classification/plot_classification_probability.py +++ b/examples/classification/plot_classification_probability.py @@ -152,7 +152,6 @@ response_method="predict_proba", class_of_interest=None, ax=axes[classifier_idx, len(y_unique)], - multiclass_colors="viridis", vmin=0, vmax=1, levels=levels, From defe8debf3e175c678a33940e510552cc01473a2 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Wed, 22 Apr 2026 23:44:29 +0200 Subject: [PATCH 386/462] DOC Fix colors in semi-supervised vs. SVM example (#33817) --- .../plot_semi_supervised_versus_svm_iris.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/semi_supervised/plot_semi_supervised_versus_svm_iris.py b/examples/semi_supervised/plot_semi_supervised_versus_svm_iris.py index b511af9716a46..58dda26b9a167 100644 --- a/examples/semi_supervised/plot_semi_supervised_versus_svm_iris.py +++ b/examples/semi_supervised/plot_semi_supervised_versus_svm_iris.py @@ -71,34 +71,34 @@ "SVC with rbf kernel\n(equivalent to Self-training with 100% labeled data)", ) -tab10 = plt.get_cmap("tab10") -color_map = {cls: tab10(cls) for cls in np.unique(y)} -color_map[-1] = (1, 1, 1) classifiers = (ls10, st10, ls30, st30, ls100, rbf_svc) fig, axes = plt.subplots(nrows=3, ncols=2, sharex="col", sharey="row", figsize=(10, 12)) axes = axes.ravel() - -handles = [ - mpatches.Patch(facecolor=tab10(i), edgecolor="black", label=iris.target_names[i]) - for i in np.unique(y) -] -handles.append(mpatches.Patch(facecolor="white", edgecolor="black", label="Unlabeled")) - for ax, (clf, y_train, title) in zip(axes, classifiers): - DecisionBoundaryDisplay.from_estimator( + disp = DecisionBoundaryDisplay.from_estimator( clf, X, response_method="predict_proba", plot_method="contourf", ax=ax, ) - colors = [color_map[label] for label in y_train] + colors = [ + (1, 1, 1, 1) if label == -1 else disp.multiclass_colors_[label] + for label in y_train + ] ax.scatter(X[:, 0], X[:, 1], c=colors, edgecolor="black") ax.set_title(title) fig.suptitle( "Semi-supervised decision boundaries with varying fractions of labeled data", y=1 ) +handles = [ + mpatches.Patch( + facecolor=color, edgecolor="black", label=iris.target_names[class_idx] + ) + for class_idx, color in enumerate(disp.multiclass_colors_) +] +handles.append(mpatches.Patch(facecolor="white", edgecolor="black", label="Unlabeled")) fig.legend( handles=handles, loc="lower center", ncol=len(handles), bbox_to_anchor=(0.5, 0.0) ) From 8ecc476dbf9bde1749204491414e3a6ae9863b22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= <deamarialeon@gmail.com> Date: Thu, 23 Apr 2026 00:08:00 +0200 Subject: [PATCH 387/462] DOC FIX display output features in `CountVectorizer` HTML (#33779) --- sklearn/utils/_repr_html/estimator.py | 12 +++++------- sklearn/utils/_repr_html/tests/test_features.py | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/sklearn/utils/_repr_html/estimator.py b/sklearn/utils/_repr_html/estimator.py index dc8e6ac62fd92..152e46f696ddd 100644 --- a/sklearn/utils/_repr_html/estimator.py +++ b/sklearn/utils/_repr_html/estimator.py @@ -427,13 +427,11 @@ def _write_estimator_html( out.write("</div>") elif est_block.kind == "single": - if ( - has_feature_names_out - and is_not_pipeline_step - and is_fitted_css_class - and hasattr(estimator, "n_features_in_") - ): - output_features = estimator.get_feature_names_out() + if has_feature_names_out and is_not_pipeline_step and is_fitted_css_class: + try: + output_features = estimator.get_feature_names_out() + except Exception: + output_features = "" else: output_features = "" diff --git a/sklearn/utils/_repr_html/tests/test_features.py b/sklearn/utils/_repr_html/tests/test_features.py index e63caddb4bf13..80b8267660e7c 100644 --- a/sklearn/utils/_repr_html/tests/test_features.py +++ b/sklearn/utils/_repr_html/tests/test_features.py @@ -3,6 +3,7 @@ from sklearn.compose import ColumnTransformer from sklearn.decomposition import PCA, TruncatedSVD +from sklearn.feature_extraction.text import CountVectorizer from sklearn.pipeline import FeatureUnion, Pipeline from sklearn.preprocessing import Normalizer, StandardScaler from sklearn.utils._repr_html.estimator import estimator_html_repr @@ -102,6 +103,21 @@ def test_features_html_with_pipeline(): assert "3 features" in html +def test_countvectorizer_output_features(): + """Non-regression test for + https://github.com/scikit-learn/scikit-learn/issues/33772""" + corpus = [ + "cat", + "dog", + "mouse", + "bird", + ] + vectorizer = CountVectorizer() + vectorizer.fit_transform(corpus) + html = estimator_html_repr(vectorizer) + assert "4 features" in html + + def test_features_html_empty_features(): """Test that _features_html handles empty feature list.""" features = [] From 34394959c9e0a4f0ab7d36cfe28cd59583c5ea2e Mon Sep 17 00:00:00 2001 From: Ralf Gommers <ralf.gommers@gmail.com> Date: Thu, 23 Apr 2026 00:44:06 +0200 Subject: [PATCH 388/462] ENH: make `sklearn/utils/cython_blas` compatible with an ILP64 SciPy (#33784) --- meson.build | 2 +- sklearn/utils/_blas_int.pxi.in | 3 ++ sklearn/utils/_cython_blas.pyx | 82 +++++++++++++++++++--------------- sklearn/utils/meson.build | 21 ++++++++- 4 files changed, 71 insertions(+), 37 deletions(-) create mode 100644 sklearn/utils/_blas_int.pxi.in diff --git a/meson.build b/meson.build index f843a1ff8f45c..99dea014d8800 100644 --- a/meson.build +++ b/meson.build @@ -3,7 +3,7 @@ project( 'c', 'cpp', 'cython', version: run_command('sklearn/_build_utils/version.py', check: true).stdout().strip(), license: 'BSD-3', - meson_version: '>= 1.1.0', + meson_version: '>= 1.9.0', default_options: [ 'c_std=c11', 'cpp_std=c++14', diff --git a/sklearn/utils/_blas_int.pxi.in b/sklearn/utils/_blas_int.pxi.in new file mode 100644 index 0000000000000..4e8f15f7c260b --- /dev/null +++ b/sklearn/utils/_blas_int.pxi.in @@ -0,0 +1,3 @@ +# This will be a plain `int` if scipy.linalg.cython_blas doesn't have `blas_int`, and +# `blas_int` if it does. See `meson.build` in this directory for the compile-time check. +@BLAS_INT_DEF@ diff --git a/sklearn/utils/_cython_blas.pyx b/sklearn/utils/_cython_blas.pyx index ac23d0c4000ff..04bba80dc561a 100644 --- a/sklearn/utils/_cython_blas.pyx +++ b/sklearn/utils/_cython_blas.pyx @@ -11,6 +11,7 @@ from scipy.linalg.cython_blas cimport srot, drot from scipy.linalg.cython_blas cimport sgemv, dgemv from scipy.linalg.cython_blas cimport sger, dger from scipy.linalg.cython_blas cimport sgemm, dgemm +include "sklearn/utils/_blas_int.pxi" ################ @@ -20,10 +21,11 @@ from scipy.linalg.cython_blas cimport sgemm, dgemm cdef floating _dot(int n, const floating *x, int incx, const floating *y, int incy) noexcept nogil: """x.T.y""" + cdef blas_int n_ = n, incx_ = incx, incy_ = incy if floating is float: - return sdot(&n, <float *> x, &incx, <float *> y, &incy) + return sdot(&n_, <float *> x, &incx_, <float *> y, &incy_) else: - return ddot(&n, <double *> x, &incx, <double *> y, &incy) + return ddot(&n_, <double *> x, &incx_, <double *> y, &incy_) cpdef _dot_memview(const floating[::1] x, const floating[::1] y): @@ -32,10 +34,11 @@ cpdef _dot_memview(const floating[::1] x, const floating[::1] y): cdef floating _asum(int n, const floating *x, int incx) noexcept nogil: """sum(|x_i|)""" + cdef blas_int n_ = n, incx_ = incx if floating is float: - return sasum(&n, <float *> x, &incx) + return sasum(&n_, <float *> x, &incx_) else: - return dasum(&n, <double *> x, &incx) + return dasum(&n_, <double *> x, &incx_) cpdef _asum_memview(const floating[::1] x): @@ -45,10 +48,11 @@ cpdef _asum_memview(const floating[::1] x): cdef void _axpy(int n, floating alpha, const floating *x, int incx, floating *y, int incy) noexcept nogil: """y := alpha * x + y""" + cdef blas_int n_ = n, incx_ = incx, incy_ = incy if floating is float: - saxpy(&n, &alpha, <float *> x, &incx, y, &incy) + saxpy(&n_, &alpha, <float *> x, &incx_, y, &incy_) else: - daxpy(&n, &alpha, <double *> x, &incx, y, &incy) + daxpy(&n_, &alpha, <double *> x, &incx_, y, &incy_) cpdef _axpy_memview(floating alpha, const floating[::1] x, floating[::1] y): @@ -57,10 +61,11 @@ cpdef _axpy_memview(floating alpha, const floating[::1] x, floating[::1] y): cdef floating _nrm2(int n, const floating *x, int incx) noexcept nogil: """sqrt(sum((x_i)^2))""" + cdef blas_int n_ = n, incx_ = incx if floating is float: - return snrm2(&n, <float *> x, &incx) + return snrm2(&n_, <float *> x, &incx_) else: - return dnrm2(&n, <double *> x, &incx) + return dnrm2(&n_, <double *> x, &incx_) cpdef _nrm2_memview(const floating[::1] x): @@ -69,10 +74,11 @@ cpdef _nrm2_memview(const floating[::1] x): cdef void _copy(int n, const floating *x, int incx, const floating *y, int incy) noexcept nogil: """y := x""" + cdef blas_int n_ = n, incx_ = incx, incy_ = incy if floating is float: - scopy(&n, <float *> x, &incx, <float *> y, &incy) + scopy(&n_, <float *> x, &incx_, <float *> y, &incy_) else: - dcopy(&n, <double *> x, &incx, <double *> y, &incy) + dcopy(&n_, <double *> x, &incx_, <double *> y, &incy_) cpdef _copy_memview(const floating[::1] x, const floating[::1] y): @@ -81,10 +87,11 @@ cpdef _copy_memview(const floating[::1] x, const floating[::1] y): cdef void _scal(int n, floating alpha, const floating *x, int incx) noexcept nogil: """x := alpha * x""" + cdef blas_int n_ = n, incx_ = incx if floating is float: - sscal(&n, &alpha, <float *> x, &incx) + sscal(&n_, &alpha, <float *> x, &incx_) else: - dscal(&n, &alpha, <double *> x, &incx) + dscal(&n_, &alpha, <double *> x, &incx_) cpdef _scal_memview(floating alpha, const floating[::1] x): @@ -107,10 +114,11 @@ cpdef _rotg_memview(floating a, floating b, floating c, floating s): cdef void _rot(int n, floating *x, int incx, floating *y, int incy, floating c, floating s) noexcept nogil: """Apply plane rotation""" + cdef blas_int n_ = n, incx_ = incx, incy_ = incy if floating is float: - srot(&n, x, &incx, y, &incy, &c, &s) + srot(&n_, x, &incx_, y, &incy_, &c, &s) else: - drot(&n, x, &incx, y, &incy, &c, &s) + drot(&n_, x, &incx_, y, &incy_, &c, &s) cpdef _rot_memview(floating[::1] x, floating[::1] y, floating c, floating s): @@ -125,22 +133,24 @@ cdef void _gemv(BLAS_Order order, BLAS_Trans ta, int m, int n, floating alpha, const floating *A, int lda, const floating *x, int incx, floating beta, floating *y, int incy) noexcept nogil: """y := alpha * op(A).x + beta * y""" - cdef char ta_ = ta + cdef: + char ta_ = ta + blas_int m_ = m, n_ = n, lda_ = lda, incx_ = incx, incy_ = incy if order == BLAS_Order.RowMajor: ta_ = BLAS_Trans.NoTrans if ta == BLAS_Trans.Trans else BLAS_Trans.Trans if floating is float: - sgemv(&ta_, &n, &m, &alpha, <float *> A, &lda, <float *> x, - &incx, &beta, y, &incy) + sgemv(&ta_, &n_, &m_, &alpha, <float *> A, &lda_, <float *> x, + &incx_, &beta, y, &incy_) else: - dgemv(&ta_, &n, &m, &alpha, <double *> A, &lda, <double *> x, - &incx, &beta, y, &incy) + dgemv(&ta_, &n_, &m_, &alpha, <double *> A, &lda_, <double *> x, + &incx_, &beta, y, &incy_) else: if floating is float: - sgemv(&ta_, &m, &n, &alpha, <float *> A, &lda, <float *> x, - &incx, &beta, y, &incy) + sgemv(&ta_, &m_, &n_, &alpha, <float *> A, &lda_, <float *> x, + &incx_, &beta, y, &incy_) else: - dgemv(&ta_, &m, &n, &alpha, <double *> A, &lda, <double *> x, - &incx, &beta, y, &incy) + dgemv(&ta_, &m_, &n_, &alpha, <double *> A, &lda_, <double *> x, + &incx_, &beta, y, &incy_) cpdef _gemv_memview(BLAS_Trans ta, floating alpha, const floating[:, :] A, @@ -160,16 +170,17 @@ cdef void _ger(BLAS_Order order, int m, int n, floating alpha, const floating *x, int incx, const floating *y, int incy, floating *A, int lda) noexcept nogil: """A := alpha * x.y.T + A""" + cdef blas_int m_ = m, n_ = n, incx_ = incx, incy_ = incy, lda_ = lda if order == BLAS_Order.RowMajor: if floating is float: - sger(&n, &m, &alpha, <float *> y, &incy, <float *> x, &incx, A, &lda) + sger(&n_, &m_, &alpha, <float *> y, &incy_, <float *> x, &incx_, A, &lda_) else: - dger(&n, &m, &alpha, <double *> y, &incy, <double *> x, &incx, A, &lda) + dger(&n_, &m_, &alpha, <double *> y, &incy_, <double *> x, &incx_, A, &lda_) else: if floating is float: - sger(&m, &n, &alpha, <float *> x, &incx, <float *> y, &incy, A, &lda) + sger(&m_, &n_, &alpha, <float *> x, &incx_, <float *> y, &incy_, A, &lda_) else: - dger(&m, &n, &alpha, <double *> x, &incx, <double *> y, &incy, A, &lda) + dger(&m_, &n_, &alpha, <double *> x, &incx_, <double *> y, &incy_, A, &lda_) cpdef _ger_memview(floating alpha, const floating[::1] x, @@ -198,20 +209,21 @@ cdef void _gemm(BLAS_Order order, BLAS_Trans ta, BLAS_Trans tb, int m, int n, cdef: char ta_ = ta char tb_ = tb + blas_int m_ = m, n_ = n, k_ = k, lda_ = lda, ldb_ = ldb, ldc_ = ldc if order == BLAS_Order.RowMajor: if floating is float: - sgemm(&tb_, &ta_, &n, &m, &k, &alpha, <float*>B, - &ldb, <float*>A, &lda, &beta, C, &ldc) + sgemm(&tb_, &ta_, &n_, &m_, &k_, &alpha, <float*>B, + &ldb_, <float*>A, &lda_, &beta, C, &ldc_) else: - dgemm(&tb_, &ta_, &n, &m, &k, &alpha, <double*>B, - &ldb, <double*>A, &lda, &beta, C, &ldc) + dgemm(&tb_, &ta_, &n_, &m_, &k_, &alpha, <double*>B, + &ldb_, <double*>A, &lda_, &beta, C, &ldc_) else: if floating is float: - sgemm(&ta_, &tb_, &m, &n, &k, &alpha, <float*>A, - &lda, <float*>B, &ldb, &beta, C, &ldc) + sgemm(&ta_, &tb_, &m_, &n_, &k_, &alpha, <float*>A, + &lda_, <float*>B, &ldb_, &beta, C, &ldc_) else: - dgemm(&ta_, &tb_, &m, &n, &k, &alpha, <double*>A, - &lda, <double*>B, &ldb, &beta, C, &ldc) + dgemm(&ta_, &tb_, &m_, &n_, &k_, &alpha, <double*>A, + &lda_, <double*>B, &ldb_, &beta, C, &ldc_) cpdef _gemm_memview(BLAS_Trans ta, BLAS_Trans tb, floating alpha, diff --git a/sklearn/utils/meson.build b/sklearn/utils/meson.build index ae490e987a4ff..0a8a7ff7fbe4e 100644 --- a/sklearn/utils/meson.build +++ b/sklearn/utils/meson.build @@ -1,3 +1,22 @@ +# Check if scipy's cython_blas exports blas_int (ILP64 support). +scipy_has_blas_int = cython.compiles( + 'from scipy.linalg.cython_blas cimport blas_int', + name: 'scipy cython_blas blas_int' +) + +_blas_int_conf = configuration_data() +if scipy_has_blas_int + _blas_int_conf.set('BLAS_INT_DEF', 'from scipy.linalg.cython_blas cimport blas_int') +else + _blas_int_conf.set('BLAS_INT_DEF', 'ctypedef int blas_int') +endif + +_blas_int_pxi = configure_file( + input: '_blas_int.pxi.in', + output: '_blas_int.pxi', + configuration: _blas_int_conf, +) + # utils is cimported from other subpackages so this is needed for the cimport # to work utils_cython_tree = [ @@ -17,7 +36,7 @@ utils_cython_tree = [ utils_extension_metadata = { 'sparsefuncs_fast': {'sources': [cython_gen.process('sparsefuncs_fast.pyx')]}, - '_cython_blas': {'sources': [cython_gen.process('_cython_blas.pyx')]}, + '_cython_blas': {'sources': [cython_gen.process('_cython_blas.pyx'), _blas_int_pxi]}, 'arrayfuncs': {'sources': [cython_gen.process('arrayfuncs.pyx')]}, 'murmurhash': { 'sources': [cython_gen.process('murmurhash.pyx'), 'src' / 'MurmurHash3.cpp'], From 6add33ef52e59aa154a008ee9d646260c3a3c0cc Mon Sep 17 00:00:00 2001 From: Adrin Jalali <adrin.jalali@gmail.com> Date: Thu, 23 Apr 2026 10:43:52 +0200 Subject: [PATCH 389/462] CI FIX hotfix for the wheel builder issue (#33839) --- sklearn/tests/test_build.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sklearn/tests/test_build.py b/sklearn/tests/test_build.py index c86032c6fafbd..1199e589556f7 100644 --- a/sklearn/tests/test_build.py +++ b/sklearn/tests/test_build.py @@ -28,9 +28,16 @@ def test_extension_type_module(): path=sklearn_path, prefix="sklearn.", onerror=lambda _: None ): # Packages are directories, not modules that can hold extension - # types. ``tests`` and ``externals`` (vendored third-party code) are - # out of scope for this check. - if ispkg or ".tests." in modname or ".externals." in modname: + # types. ``tests``, ``externals`` (vendored third-party code) and + # ``_build_utils`` (build-time helpers that import ``Cython``, which + # is not installed in the wheel test environment) are out of scope + # for this check. + if ( + ispkg + or ".tests." in modname + or ".externals." in modname + or "._build_utils." in modname + ): continue mod = importlib.import_module(modname) mod_file = getattr(mod, "__file__", "") or "" From edab2dbf15d4206f8b3238ec153963bd94068601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= <deamarialeon@gmail.com> Date: Thu, 23 Apr 2026 11:14:43 +0200 Subject: [PATCH 390/462] DOC FIX link in HTML displays for parameters that include backtics (#33831) --- sklearn/utils/_repr_html/common.py | 2 +- sklearn/utils/_repr_html/tests/test_params.py | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/sklearn/utils/_repr_html/common.py b/sklearn/utils/_repr_html/common.py index 1c1f610778e9d..3d09c170e406c 100644 --- a/sklearn/utils/_repr_html/common.py +++ b/sklearn/utils/_repr_html/common.py @@ -26,7 +26,7 @@ def generate_link_to_param_doc(estimator_class, param_name, doc_link): # Extract the whole line of the type information, up to the line break as # disambiguation suffix to build the fragment - param_type = m.group(1) + param_type = m.group(1).replace("`", "") text_fragment = f"{quote(param_name)},-{quote(param_type)}" return f"{doc_link}#:~:text={text_fragment}" diff --git a/sklearn/utils/_repr_html/tests/test_params.py b/sklearn/utils/_repr_html/tests/test_params.py index 8310da7a2cdb1..a86d28250cd90 100644 --- a/sklearn/utils/_repr_html/tests/test_params.py +++ b/sklearn/utils/_repr_html/tests/test_params.py @@ -212,3 +212,25 @@ class MockEstimator: doc_link = "mock_module.MockEstimator.html" url = generate_link_to_param_doc(MockEstimator, "alpha", doc_link) assert url is None + + +def test_generate_link_to_param_doc_special_char(): + """Non-regression test for + https://github.com/scikit-learn/scikit-learn/issues/33830 + """ + + class MockEstimator: + """Mock class. + + Attributes + ---------- + weird_attr_ : ndarray of shape (`n_features_in_`,) + """ + + doc_link = "mock_module.MockEstimator.html" + url = generate_link_to_param_doc(MockEstimator, "weird_attr_", doc_link) + expected_url = ( + "mock_module.MockEstimator.html#:~:text=weird_attr_," + "-ndarray%20of%20shape%20%28n_features_in_%2C%29" + ) + assert url == expected_url From c054af352f2493fc4e16e1e237a912c4345c56fe Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Thu, 23 Apr 2026 11:22:07 +0200 Subject: [PATCH 391/462] FIX polars 1.40 deprecated dataframe interchange protocol __dataframe__ (#33789) --- .../sklearn.utils/33789.fix.rst | 4 ++ sklearn/compose/_column_transformer.py | 15 +++++--- .../gradient_boosting.py | 17 +++++++-- sklearn/utils/_indexing.py | 26 ++++++++----- sklearn/utils/tests/test_indexing.py | 16 +++++--- sklearn/utils/tests/test_validation.py | 15 ++++++-- sklearn/utils/validation.py | 37 ++++++++++--------- 7 files changed, 87 insertions(+), 43 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/33789.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/33789.fix.rst b/doc/whats_new/upcoming_changes/sklearn.utils/33789.fix.rst new file mode 100644 index 0000000000000..9c3643f21cda5 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.utils/33789.fix.rst @@ -0,0 +1,4 @@ +- The code path for polars dataframes in :func:`validate_data` was made independent of + the dataframe interchange protocol `__dataframe__`. This change was necessary to + adapt to the recent deprecation of the interchange protocol in polars version 1.40. + By :user:`Christian Lorentzen <lorentzenchr>`. diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index bab1f4dc475d8..60c0a7f211565 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -19,7 +19,7 @@ from sklearn.pipeline import _fit_transform_one, _name_estimators, _transform_one from sklearn.preprocessing import FunctionTransformer from sklearn.utils import Bunch -from sklearn.utils._dataframe import is_pandas_df +from sklearn.utils._dataframe import is_pandas_df, is_polars_df from sklearn.utils._indexing import ( _determine_key_type, _get_column_indices, @@ -746,10 +746,14 @@ def _validate_output(self, result): ) ] for Xs, name in zip(result, names): - if not getattr(Xs, "ndim", 0) == 2 and not hasattr(Xs, "__dataframe__"): + if not ( + getattr(Xs, "ndim", 0) == 2 + or hasattr(Xs, "__dataframe__") + or is_polars_df(Xs) + ): raise ValueError( - "The output of the '{0}' transformer should be 2D (numpy array, " - "scipy sparse array, dataframe).".format(name) + f"The output of the '{name}' transformer should be 2D (numpy " + "array, scipy sparse array, dataframe)." ) if _get_output_config("transform", self)["dense"] == "pandas": return @@ -1041,7 +1045,7 @@ def transform(self, X, **params): # were not present in fit time, and the order of the columns doesn't # matter. fit_dataframe_and_transform_dataframe = hasattr(self, "feature_names_in_") and ( - is_pandas_df(X) or hasattr(X, "__dataframe__") + is_pandas_df(X) or is_polars_df(X) or hasattr(X, "__dataframe__") ) n_samples = _num_samples(X) @@ -1290,6 +1294,7 @@ def _check_X(X): if ( (hasattr(X, "__array__") and hasattr(X, "shape")) or hasattr(X, "__dataframe__") + or is_polars_df(X) or sparse.issparse(X) ): return X diff --git a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py index e96267228e081..9635162af773d 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py +++ b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py @@ -4,6 +4,7 @@ # SPDX-License-Identifier: BSD-3-Clause import itertools +import sys from abc import ABC, abstractmethod from contextlib import contextmanager, nullcontext, suppress from functools import partial @@ -40,7 +41,7 @@ from sklearn.model_selection import train_test_split from sklearn.preprocessing import FunctionTransformer, LabelEncoder, OrdinalEncoder from sklearn.utils import check_random_state, compute_sample_weight, resample -from sklearn.utils._dataframe import is_pandas_df +from sklearn.utils._dataframe import is_pandas_df, is_polars_df from sklearn.utils._missing import is_scalar_nan from sklearn.utils._openmp_helpers import _openmp_effective_n_threads from sklearn.utils._param_validation import Interval, RealNotInt, StrOptions @@ -374,6 +375,14 @@ def _check_categorical_features(self, X): if is_pandas_df(X): X_is_dataframe = True categorical_columns_mask = np.asarray(X.dtypes == "category") + elif is_polars_df(X): + # Special code for polars because polars 1.40 deprecates the __dataframe__ + # protocol. + X_is_dataframe = True + pl = sys.modules["polars"] + categorical_columns_mask = np.asarray( + [d in (pl.Categorical, pl.Enum) for d in X.dtypes] + ) elif hasattr(X, "__dataframe__"): X_is_dataframe = True categorical_columns_mask = np.asarray( @@ -1573,7 +1582,8 @@ class HistGradientBoostingRegressor(RegressorMixin, BaseHistGradientBoosting): - `"from_dtype"`: dataframe columns with dtype "category" are considered to be categorical features. The input must be an object exposing a ``__dataframe__`` method such as pandas or polars - DataFrames to use this feature. + DataFrames to use this feature. For polars dataframes, dtypes + pl.Categorical and pl.Enum are detected. For each categorical feature, there must be at most `max_bins` unique categories. Negative values for categorical features encoded as numeric @@ -1966,7 +1976,8 @@ class HistGradientBoostingClassifier(ClassifierMixin, BaseHistGradientBoosting): - `"from_dtype"`: dataframe columns with dtype "category" are considered to be categorical features. The input must be an object exposing a ``__dataframe__`` method such as pandas or polars - DataFrames to use this feature. + DataFrames to use this feature. For polars dataframes, dtypes + pl.Categorical and pl.Enum are detected. For each categorical feature, there must be at most `max_bins` unique categories. Negative values for categorical features encoded as numeric diff --git a/sklearn/utils/_indexing.py b/sklearn/utils/_indexing.py index 7931c75a65360..6d8a4fbf9e92b 100644 --- a/sklearn/utils/_indexing.py +++ b/sklearn/utils/_indexing.py @@ -17,6 +17,7 @@ ) from sklearn.utils._dataframe import ( is_pandas_df, + is_polars_df, is_polars_df_or_series, is_pyarrow_data, ) @@ -344,7 +345,7 @@ def _safe_indexing(X, indices, *, axis=0): if ( axis == 1 and indices_dtype == "str" - and not (is_pandas_df(X) or _use_interchange_protocol(X)) + and not (is_pandas_df(X) or is_polars_df(X) or _use_interchange_protocol(X)) ): raise ValueError( "Specifying the columns using strings is only supported for dataframes." @@ -433,8 +434,19 @@ def _get_column_indices(X, key): :func:`_safe_indexing`. """ key_dtype = _determine_key_type(key) - if _use_interchange_protocol(X): - return _get_column_indices_interchange(X.__dataframe__(), key, key_dtype) + if is_polars_df(X): + n_columns = X.shape[1] + column_names = X.columns + return _get_column_indices_interchange_and_polars( + n_columns, column_names, key, key_dtype + ) + elif _use_interchange_protocol(X): + X_interchange = X.__dataframe__() + n_columns = X_interchange.num_columns() + column_names = list(X_interchange.column_names()) + return _get_column_indices_interchange_and_polars( + n_columns, column_names, key, key_dtype + ) n_columns = X.shape[1] if isinstance(key, (list, tuple)) and not key: @@ -480,10 +492,8 @@ def _get_column_indices(X, key): return column_indices -def _get_column_indices_interchange(X_interchange, key, key_dtype): - """Same as _get_column_indices but for X with __dataframe__ protocol.""" - - n_columns = X_interchange.num_columns() +def _get_column_indices_interchange_and_polars(n_columns, column_names, key, key_dtype): + """Same as _get_column_indices but for X with __dataframe__ protocol or polars.""" if isinstance(key, (list, tuple)) and not key: # we get an empty list @@ -491,8 +501,6 @@ def _get_column_indices_interchange(X_interchange, key, key_dtype): elif key_dtype in ("bool", "int"): return _get_column_indices_for_bool_or_int(key, n_columns) else: - column_names = list(X_interchange.column_names()) - if isinstance(key, slice): if key.step not in [1, None]: raise NotImplementedError("key.step must be 1 or None") diff --git a/sklearn/utils/tests/test_indexing.py b/sklearn/utils/tests/test_indexing.py index 27bca5968f21d..9dbb71d1ff4bc 100644 --- a/sklearn/utils/tests/test_indexing.py +++ b/sklearn/utils/tests/test_indexing.py @@ -504,12 +504,16 @@ def test_get_column_indices_pandas_nonunique_columns_error(key): assert str(exc_info.value) == err_msg -def test_get_column_indices_interchange(): - """Check _get_column_indices for edge cases with the interchange""" - pl = pytest.importorskip("polars") - - # Polars dataframes go down the interchange path. - df = pl.DataFrame([[1, 2, 3], [4, 5, 6]], schema=["a", "b", "c"]) +@pytest.mark.parametrize("df_type", ["interchange", "polars"]) +def test_get_column_indices_interchange_and_polars(df_type): + """Check _get_column_indices for edge cases with the interchange and polars""" + if df_type == "polars": + pl = pytest.importorskip("polars") + df = pl.DataFrame([[1, 2, 3], [4, 5, 6]], schema=["a", "b", "c"]) + else: + # Pyarrow tables go down the interchange path. + pa = pytest.importorskip("pyarrow") + df = pa.table([[1, 4], [2, 5], [3, 6]], names=["a", "b", "c"]) key_results = [ (slice(1, None), [1, 2]), diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 0eefcf9a3cc09..0065d3a84bc35 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -2221,10 +2221,19 @@ def test_check_array_multiple_extensions( def test_num_samples_dataframe_protocol(): - """Use the DataFrame interchange protocol to get n_samples from polars.""" - pl = pytest.importorskip("polars") + """Use the DataFrame interchange protocol to get n_samples.""" + pa = pytest.importorskip("pyarrow") - df = pl.DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}) + class MockDFInterchange: + """A dataframe class without .shape attr but with __dataframe__ protocol""" + + def __init__(self, *args, **kwargs): + self.df = pa.table(*args, **kwargs) + + def __dataframe__(self): + return self.df.__dataframe__() + + df = MockDFInterchange({"a": [1, 2, 3], "b": [4, 5, 6]}) assert _num_samples(df) == 3 diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index 5cbbbd14b9678..ae6ed38a3e16f 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -29,7 +29,7 @@ get_namespace_and_device, move_to, ) -from sklearn.utils._dataframe import is_pandas_df, is_pandas_df_or_series +from sklearn.utils._dataframe import is_pandas_df, is_pandas_df_or_series, is_polars_df from sklearn.utils._isfinite import FiniteStatus, cy_isfinite from sklearn.utils._tags import get_tags from sklearn.utils.fixes import ( @@ -306,13 +306,16 @@ def _is_arraylike_not_scalar(array): def _use_interchange_protocol(X): - """Use interchange protocol for non-pandas dataframes that follow the protocol. + """Use interchange protocol for non-pandas/polars dataframes that follow the + protocol. - Note: at this point we chose not to use the interchange API on pandas dataframe + Note: At this point we chose not to use the interchange API on pandas dataframe to ensure strict behavioral backward compatibility with older versions of scikit-learn. + We also exclude the interchange protocol for polars because it was deprecated + in polars 1.40. """ - return not is_pandas_df(X) and hasattr(X, "__dataframe__") + return hasattr(X, "__dataframe__") and not is_pandas_df(X) and not is_polars_df(X) def _num_features(X): @@ -375,16 +378,6 @@ def _num_samples(x): # Don't get num_samples from an ensembles length! raise TypeError(message) - if _use_interchange_protocol(x): - return x.__dataframe__().num_rows() - - if not hasattr(x, "__len__") and not hasattr(x, "shape"): - if hasattr(x, "__array__"): - xp, _ = get_namespace(x) - x = xp.asarray(x) - else: - raise TypeError(message) - if hasattr(x, "shape") and x.shape is not None: if len(x.shape) == 0: raise TypeError( @@ -396,6 +389,16 @@ def _num_samples(x): if isinstance(x.shape[0], numbers.Integral): return x.shape[0] + if _use_interchange_protocol(x): + return x.__dataframe__().num_rows() + + if not hasattr(x, "__len__") and not hasattr(x, "shape"): + if hasattr(x, "__array__"): + xp, _ = get_namespace(x) + x = xp.asarray(x) + else: + raise TypeError(message) + try: return len(x) except TypeError as type_error: @@ -2346,13 +2349,13 @@ def _get_feature_names(X): feature_names = None # extract feature names for support array containers - if is_pandas_df(X): + if is_pandas_df(X) or is_polars_df(X): # Make sure we can inspect columns names from pandas, even with # versions too old to expose a working implementation of # __dataframe__.column_names() and avoid introducing any # additional copy. - # TODO: remove the pandas-specific branch once the minimum supported - # version of pandas has a working implementation of + # TODO: remove the pandas-specific branch (but keep polars) once the minimum + # supported version of pandas has a working implementation of # __dataframe__.column_names() that is guaranteed to not introduce any # additional copy of the data without having to impose allow_copy=False # that could fail with other libraries. Note: in the longer term, we From 3f5cd899a7e0403dbbaa3cb1b185e5fbbaccf8f8 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Thu, 23 Apr 2026 06:07:33 -0400 Subject: [PATCH 392/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33804) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lock file bot <noreply@github.com> Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- build_tools/circle/doc_linux-64_conda.lock | 4 +-- .../doc_min_dependencies_linux-64_conda.lock | 28 ++++++++--------- build_tools/github/debian_32bit_lock.txt | 4 +-- ...latest_conda_forge_mkl_linux-64_conda.lock | 30 ++++++++++--------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 12 ++++---- .../pylatest_conda_forge_osx-arm64_conda.lock | 15 +++++----- ...st_pip_openblas_pandas_linux-64_conda.lock | 6 ++-- ...n_conda_forge_arm_linux-aarch64_conda.lock | 24 ++++++++------- ...nblas_min_dependencies_linux-64_conda.lock | 20 ++++++------- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 8 ++--- ...min_conda_forge_openblas_win-64_conda.lock | 14 ++++----- build_tools/github/ubuntu_atlas_lock.txt | 4 +-- 12 files changed, 86 insertions(+), 83 deletions(-) diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index c9e29e93e8e37..860a6b0df9f11 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -286,7 +286,7 @@ https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.con https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.1-pyhcf101f3_0.conda#4552b601cf622dea2bb5075baccc2c5b https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda#082985717303dab433c976986c674b35 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 @@ -297,7 +297,7 @@ https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0. https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea -https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda#d5a4e013a30dd8dfde9ab39f45aaf9c1 +https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyhe01879c_0.conda#31e11c30bbee1682a55627f953c6725a diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 50a202b313025..5cacf16954921 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -46,7 +46,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -111,7 +111,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 @@ -132,10 +132,10 @@ https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/openjph-0.26.3-h8d634f6_0.conda#792d5b6e99677177f5527a758a02bc07 +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.27.0-h8d634f6_0.conda#8397bb8cf4b370f5df7d7ee3d80ea977 https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 @@ -169,11 +169,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7 https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -200,7 +200,7 @@ https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py311h49ec1c https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 -https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.0-pyhcf101f3_1.conda#30cd29cb87d819caead4d55184c1d115 +https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda#e1c36c6121a7c9c76f2f148f1e83b983 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab @@ -211,12 +211,12 @@ https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#191 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a -https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.0.0-pyhd8ed1ab_0.conda#724309d702b3a44f59987f9be424c040 +https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda#0ba6225c279baf7ea9473a62ea0ec9ae https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.3-default_h99862b1_0.conda#4642265acfa1ad8dfe96c89d8d7b38fe -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_0.conda#9b47a4cd3aabb73201a2b8ed9f127189 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.3-default_h99862b1_1.conda#1cf5d6f2ae346ea959f223401764845c +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_1.conda#80daec8cf93185515ac7b5d359e3f929 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda#9f6a8664f1fe752f79473eeb9bf33a60 @@ -229,8 +229,8 @@ https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bd https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f -https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 -https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.0.0-pyhd8ed1ab_0.conda#62fa494c03634a688a28748902579881 +https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.11-h29cf534_0.conda#1e0e854b77451ac918b4a68f28932b1d +https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.1.0-pyhd8ed1ab_0.conda#e3bffa82b874f8b9a2631bddb3869529 https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.5-pyhd8ed1ab_0.conda#4c8327180586e7b1cd8b6815fc8827f1 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b @@ -240,7 +240,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_ https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e -https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 +https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.11-h6d08254_0.conda#971da16e7fc43161329213557688d315 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 @@ -255,7 +255,7 @@ https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.con https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h9837d23_1.conda#c589e43a6bccf41b0f5a3351efc96442 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h2f21a4e_2.conda#1a7670cc9bddc4310c7cd411d05a8e43 https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.conda#643f8cb35133eb1be4919fb953f0a25f https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 diff --git a/build_tools/github/debian_32bit_lock.txt b/build_tools/github/debian_32bit_lock.txt index 67aae0f7dd32b..b02d9a6e4243e 100644 --- a/build_tools/github/debian_32bit_lock.txt +++ b/build_tools/github/debian_32bit_lock.txt @@ -14,13 +14,13 @@ iniconfig==2.3.0 # via pytest joblib==1.5.3 # via -r build_tools/github/debian_32bit_requirements.txt -meson==1.10.2 +meson==1.11.0 # via meson-python meson-python==0.19.0 # via -r build_tools/github/debian_32bit_requirements.txt ninja==1.13.0 # via -r build_tools/github/debian_32bit_requirements.txt -packaging==26.0 +packaging==26.1 # via # meson-python # pyproject-metadata diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock index 81c957c22efe4..751f1dd6399b3 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -42,7 +42,7 @@ https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c @@ -55,6 +55,7 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda#fb901ff28063514abb6046c9ec2c4a45 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f +https://conda.anaconda.org/conda-forge/linux-64/xorg-xorgproto-2025.1-hb03c661_0.conda#aa8d21be4b461ce612d8f5fb791decae https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.9.13-h2c9d079_1.conda#3c3d02681058c3d206b562b2e3bc337f https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.3.2-h8b1a151_0.conda#f16f498641c9e05b645fe65902df661a @@ -93,7 +94,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.cond https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-hc87160b_0.conda#dde6a3e4fe6bb2ecd2a7050dd1e701fb https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 @@ -106,7 +107,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1. https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 @@ -124,7 +125,7 @@ https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.14.1-h3d65ac4_0.conda#fa4e76aac348ef9c27e72c79b02833fc https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -149,7 +150,7 @@ https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.c https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b +https://conda.anaconda.org/conda-forge/noarch/filelock-3.29.0-pyhd8ed1ab_0.conda#8fa8358d022a3a9bd101384a808044c6 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.4.0-py314h42812f9_0.conda#bf19183372b78e064d41f42c1a1846a1 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e @@ -158,20 +159,20 @@ https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm21-21.1.8-hf7376ad_0.conda#1a2708a460884d6861425b7f9a7bef99 https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/linux-64/playwright-1.59.1-h5585027_0.conda#3ec4a57c54725b9be3cad126ccbad2c0 @@ -208,8 +209,8 @@ https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc4 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp21.1-21.1.8-default_h99862b1_3.conda#24a2802074d26aecfdbc9b3f1d8168d1 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_0.conda#9b47a4cd3aabb73201a2b8ed9f127189 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_1.conda#80daec8cf93185515ac7b5d359e3f929 +https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 @@ -225,13 +226,13 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.co https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h4c8aef7_3.conda#798a499cf76e530a992365d557ba5827 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 +https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.58.0-pyhcf101f3_0.conda#3b886c49cf44aa133d0eb07e4d0cac89 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_2.conda#c6ba2de6b22dedf2f20eba3bde1dbe8e https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf @@ -239,15 +240,16 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.39.3-py310hffdcd12_1.conda#f9327f9f2cfc4215f55b613e64afd3ba -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_1.conda#5abdb958cf8cc0b43cf078d0559f7969 +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 -https://conda.anaconda.org/conda-forge/noarch/polars-1.39.3-pyh58ad624_1.conda#d5a4e013a30dd8dfde9ab39f45aaf9c1 +https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_9_cpu.conda#b3ba3597c481a636fc161185819cf6b1 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 66d3067f4654f..0db3f02d98c4e 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -30,10 +30,10 @@ https://conda.anaconda.org/conda-forge/osx-64/lerc-4.1.0-h35c7297_0.conda#d2fe7e https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.conda#63186ac7a8a24b3528b4b14f21c03f54 https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda#5a088b358e37ccb4f4e5c573ff37a9f9 -https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.57-he930e7c_0.conda#42dab0e4f72a55f9bc3546deec60fe44 +https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.58-he930e7c_0.conda#9744d43d5200f284260637304a069ddd https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.53.0-h8f8c405_0.conda#f2bb6692dfb33a1bbce746aa812a9a5b https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc -https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.2-h7a90416_0.conda#0c8bdbfd118f5963ab343846094932a3 +https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.3-h7a90416_0.conda#c74ae93cd7876e3a9c4b5569d5e29e34 https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda#afda563484aa0017278866707807a335 https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.2-hc881268_0.conda#5cf0ece4375c73d7a5765e83565a69c7 https://conda.anaconda.org/conda-forge/osx-64/qhull-2020.2-h3c5361c_5.conda#dd1ea9ff27c93db7c01a7b7656bd4ad4 @@ -42,11 +42,11 @@ https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda#6e6efb7 https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.3-h8bce59a_1.conda#b3ecb6480fd46194e3f7dd0ff4445dff https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf -https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.3-h894318c_0.conda#070e696856881a647e57267344e6b478 +https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.4-h894318c_0.conda#5c38d938a042bf6cc8605cbaf8a9d769 https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.3-h58fbd8d_0.conda#27515b8ab8bf4abd8d3d90cf11212411 https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda#9a5cb96e43f5c2296690186e15b3296f https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 -https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.2-hd552753_0.conda#eea3155f3b4a3b75af504c871ec23858 +https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.3-h953d39d_0.conda#33f30d4878d1f047da82a669c33b307d https://conda.anaconda.org/conda-forge/osx-64/python-3.14.4-h7c6738f_100_cp314.conda#d4e8506d0ac094be21451682eed9ce4d https://conda.anaconda.org/conda-forge/osx-64/brotli-1.2.0-hf139dec_1.conda#149d8ee7d6541a02a6117d8814fd9413 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 @@ -59,10 +59,10 @@ https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.18-h90db99b_0.conda#753acc https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.3-h694c41f_0.conda#63b822fcf984c891f0afab2eedfcfaf4 https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda#ca52daf58cea766656266c8771d8be81 https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h52bb76a_0.conda#46e628da6e796c948fa8ec9d6d10bda3 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock index fe0ffe272276e..332199c46f263 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock @@ -10,7 +10,6 @@ https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98d https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda#620b85a3f45526a8bc4d23fd78fc22f0 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d -https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda#f1182c91c0de31a7abd40cedf6a5ebef https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.3-h55c6f16_0.conda#acbb3f547c4aae16b19e417db0c6e5ed https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 @@ -40,10 +39,10 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.2.0-hc919400_1.c https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.conda#b2b7c8288ca1a2d71ff97a8e6a1e8883 https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda#58b2c5aee0ad58549bf92baead9baead -https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.57-h132b30e_0.conda#1a28041d8d998688fd82e25b45582b21 +https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.58-h132b30e_0.conda#2259ae0949dbe20c0665850365109b27 https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.0-h1b79a29_0.conda#8423c008105df35485e184066cad4566 https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 -https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.2-h5ef1a60_0.conda#b284e2b02d53ef7981613839fb86beee +https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.3-h6967ea9_0.conda#6c8292c2ee808aeef2406083beaa6da7 https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda#175809cc57b2c67f27a0f238bd7f069d https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.2-hd24854e_0.conda#25dcccd4f80f1638428613e0d7c9b4e1 https://conda.anaconda.org/conda-forge/osx-arm64/qhull-2020.2-h420ef59_5.conda#6483b1f59526e05d7d894e466b5b6924 @@ -55,13 +54,13 @@ https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.2-h8088a28_2.conda#f1c https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.3-hed4e4f5_1.conda#d99c2a23a31b0172e90f456f580b695e https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c -https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.3-h414bf82_0.conda#a641199cf4a5a2a16367acd53dcb8532 +https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.4-h414bf82_0.conda#c6f4bfb11893878780f4b3eae6432e43 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.3-hdfa99f5_0.conda#e98ba7b5f09a5f450eca083d5a1c4649 https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda#92df6107310b1fff92c4cc84f0de247b https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.33.5-h4a5acfd_0.conda#b839e3295b66434f20969c8b940f056a https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda#c08557d00807785decafb932b5be7ef5 https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 -https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.2-h8d039ee_0.conda#e476ba84e57f2bd2004a27381812ad4e +https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.3-heed7d32_0.conda#0c1fdc80534d8f25fd74722aba81f044 https://conda.anaconda.org/conda-forge/osx-arm64/mpfr-4.2.2-h6bc93b0_0.conda#a47a14da2103c9c7a390f7c8bc8d7f9b https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.4-h4c637c5_100_cp314.conda#e1bc5a3015a4bbeb304706dba5a32b7f https://conda.anaconda.org/conda-forge/osx-arm64/brotli-1.2.0-h7d5ae5b_1.conda#48ece20aa479be6ac9a284772827d00c @@ -70,7 +69,7 @@ https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.c https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py314hc6117b3_0.conda#1289de88f884ac89144949cb97ccabe7 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.25.2-pyhd8ed1ab_0.conda#f58064cec97b12a7136ebb8a6f8a129b +https://conda.anaconda.org/conda-forge/noarch/filelock-3.29.0-pyhd8ed1ab_0.conda#8fa8358d022a3a9bd101384a808044c6 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.5.0-py314hf8a3a22_0.conda#eb1465d8a644ef290d18fb86af6e9bc4 @@ -79,13 +78,13 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.3-hce30654_0.c https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda#c4a6f7989cffb0544bfd9207b6789971 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py314h6e9b3f0_1.conda#d33c0a15882b70255abdd54711b06a45 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.4.0-h169892a_0.conda#2845c3a1d0d8da1db92aba8323892475 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hd9e9057_0.conda#4b5d3a91320976eec71678fad1e3569b -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 diff --git a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock index f16567821a235..5aafd911b1ce6 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -25,7 +25,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#60 https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda#05051be49267378d2fcd12931e319ac3 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f @@ -45,10 +45,10 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip joblib @ https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl#sha256=5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 # pip kiwisolver @ https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 -# pip meson @ https://files.pythonhosted.org/packages/0b/78/7d049e63e624d51d0065191dae101a1e36d5d3a2360633772d9ad8afb2d5/meson-1.10.2-py3-none-any.whl#sha256=5f84ef186e6e788d9154db63620fc61b3ece69f643b94b43c8b9203c43d89b36 +# pip meson @ https://files.pythonhosted.org/packages/08/84/1ae2022a3562ac011c80c090e387a07e189d077b01fe58a266759b8fc2ff/meson-1.11.0-py3-none-any.whl#sha256=9774eb62bbf2cb8043aa3feb771c09b510d112c0c382221e29aea7453ecce753 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip numpy @ https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83 -# pip packaging @ https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl#sha256=b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529 +# pip packaging @ https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl#sha256=5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f # pip pillow @ https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl#sha256=81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index fe7fe73aa714c..037fca9f12d56 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -34,7 +34,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.conda#76298a9e6d71ee6e832a8d0d7373b261 https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 -https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.57-h1abf092_0.conda#41ba1a3e77b5aeb55bc2b9a206760f6a +https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda#f51503ac45a4888bce71af9027a2ecc9 https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.0-h022381a_0.conda#86db4036fd08bf34e991bf48a8af405d https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42-h1022ec0_0.conda#a0b5de740d01c390bdbb46d7503c9fab @@ -46,6 +46,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_10 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libice-1.1.2-h86ecc28_0.conda#c8d8ec3e00cd0fd8a231789b91a7c5b7 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxau-1.0.12-he30d5cf_1.conda#1c246e1105000c3660558459e2fd6d43 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdmcp-1.1.5-he30d5cf_1.conda#bff06dcde4a707339d66d45d96ceb2e2 +https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-xorgproto-2025.1-he30d5cf_0.conda#999d230bcb0329c11d101118ace392d9 https://conda.anaconda.org/conda-forge/linux-aarch64/xxhash-0.8.3-hd794028_0.conda#f2accdfbd632e2be9a63bed23cb08045 https://conda.anaconda.org/conda-forge/linux-aarch64/double-conversion-3.4.0-hfae3067_0.conda#9fd794eaf983eabf975ead524540b4be https://conda.anaconda.org/conda-forge/linux-aarch64/graphite2-1.3.14-hfae3067_2.conda#4aa540e9541cc9d6581ab23ff2043f13 @@ -70,13 +71,13 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.25.0-h4f8a99f_0.c https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda#2d1409c50882819cb1af2de82e2b7208 https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda#f731af71c723065d91b4c01bb822641b https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 -https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.3-h185addb_0.conda#90fc92ca3f97be362ecf59413cef7ca2 +https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.4-h185addb_0.conda#5ec2a8d4764a2c0f70161ce26a852dbe https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda#d9ca108bd680ea86a963104b6b3e95ca https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda#a229e22d4d8814a07702b0919d8e6701 https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_1.conda#4ac4372fc4d7f20630a91314cdac8afd https://conda.anaconda.org/conda-forge/linux-aarch64/libopenblas-0.3.32-pthreads_h9d3fd7e_0.conda#5d2ce5cf40443d055ec6d33840192265 https://conda.anaconda.org/conda-forge/linux-aarch64/libtiff-4.7.1-hdb009f0_1.conda#8c6fd84f9c87ac00636007c6131e457d -https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.2-h79dcc73_0.conda#e3ec9079759d35b875097d6a9a69e744 +https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-16-2.15.3-h79dcc73_0.conda#68866231cfe8789e780347f2482df96d https://conda.anaconda.org/conda-forge/linux-aarch64/python-3.11.15-h91f4b29_0_cpython.conda#bb09184ea3313703da05516cd730e8f8 https://conda.anaconda.org/conda-forge/linux-aarch64/qhull-2020.2-h70be974_5.conda#bb138086d938e2b64f5f364945793ebf https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-0.4.1-hca56bd8_2.conda#159ffec8f7fab775669a538f0b29373a @@ -99,12 +100,12 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-6_haddc8a3_openblas.conda#652bb20bb4618cacd11e17ae070f47ce https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h4f2b762_6.conda#67828c963b17db7dc989fe5d509ef04a https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a -https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.2-h825857f_0.conda#19de96909ee1198e2853acd8aba89f6c -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b +https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.3-h869d058_0.conda#2cffef27cb2eb9ed1e315a1e269d4335 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.32-pthreads_h3a8cbd8_0.conda#62e1383bcaf8f5244d2598bbda509e3b https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 @@ -128,8 +129,8 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.62.0-py311h164a https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-6_hd72aa62_openblas.conda#939e300b110db241a96a1bed438c315b https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda#0d00176464ebb25af83d40736a2cd3bb +https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-devel-1.7.0-hd24410f_2.conda#1f9ddbb175a63401662d1c6222cef6ff https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-6_h88aeb00_openblas.conda#e23a27b52fb320687239e2c5ae4d7540 -https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm21-21.1.8-hfd2ba90_0.conda#de59c5148c2a8347c02e437e3ed242a0 https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.3-hfd2ba90_0.conda#c2e1304da2e44348df892c1425bf294d https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 @@ -146,8 +147,8 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda#1f64c613f0b8d67e9fb0e165d898fb6b https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.7-he30d5cf_0.conda#b15ca02584678f38df6e114c32f93959 https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-14.1.0-h1134a53_0.conda#5461f9f6ba3c30ee46e014fc127c8ac0 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang-cpp21.1-21.1.8-default_he95a3c9_3.conda#4ba7653ca09e74e8968120c6aea4bfb1 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.3-default_h94a09a5_0.conda#7c7dc469f56ce1831736c2827bc52b8c +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.3-default_h94a09a5_1.conda#59bdf54337dcba90b3910baaca02388f +https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-devel-1.7.0-hd24410f_2.conda#5d8323dff6a93596fb6f985cf6e8521a https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-6_hb558247_openblas.conda#12da32239ec4cc63d4f94d83b8425947 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.3-h7d4fc67_0.conda#7eb18b198b1d35da9352062c69c4ee64 https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.341.0-h8b8848b_0.conda#06bb91a87fb97ea09398d2e121e00c39 @@ -158,11 +159,12 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-6_h9678261_openblas.conda#64fe76410feeef76a105b2343edc4af7 https://conda.anaconda.org/conda-forge/linux-aarch64/contourpy-1.3.3-py311h04741b4_4.conda#1eeea54b0c520a475db39f8c711de661 +https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-devel-1.7.0-hd24410f_2.conda#cd8877e3833ba1bfac2fbaa5ae72c226 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.11.0-pl5321h598db47_2.conda#811e17440391dbcbb67032931cd2e752 https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.1-py311h399493a_0.conda#be28b3d39c6942f89652b505e85ae3d6 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.306-openblas.conda#cc7cac46a53a5c76f20439cb298d10a2 https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 -https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.11.0-py311hb02cd75_1.conda#da150e07831537629fb38495fefae7fb +https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.11.0-pl5321h598db47_4.conda#e93276397240a46199cc7ddee1cfeb2d +https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.11.0-py311hb02cd75_2.conda#0f363faaee54d4d8164b762f1afc336f https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.8-py311hfecb2dc_0.conda#3920b856b59a909812f1913b96adaad8 diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 28f5111e2c434..0654556d3487f 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -41,7 +41,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb03c661_3.conda# https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c @@ -89,7 +89,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1.conda#f883d61afbc95c50f7b3f62546da4235 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda#d1db1b8be7c3a8983dcbbbfe4f0765de @@ -105,7 +105,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.cond https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h8fd135c_2.conda#bbf65f7688512872f063810623b755dc https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda#f3bc152cb4f86babe30f3a4bf0dbef69 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318b08df404f9c9be5712aaa5a6f0bb0 https://conda.anaconda.org/conda-forge/linux-64/rdma-core-28.9-h59595ed_1.conda#aeffb7c06b5f65e55e6c637408dc4100 https://conda.anaconda.org/conda-forge/linux-64/re2-2023.03.02-h8c504da_0.conda#206f8fa808748f6e90599c3368a1114e @@ -128,7 +128,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda#e49238a1609f9a4a844b09d9926f2c3d +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-1.8.4-h2f23424_0.conda#4bb92585a250e67d49b46c073d29f9dd @@ -160,11 +160,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -196,8 +196,8 @@ https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc4 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.3-default_h99862b1_0.conda#4642265acfa1ad8dfe96c89d8d7b38fe -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_0.conda#9b47a4cd3aabb73201a2b8ed9f127189 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.3-default_h99862b1_1.conda#1cf5d6f2ae346ea959f223401764845c +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_1.conda#80daec8cf93185515ac7b5d359e3f929 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 @@ -205,7 +205,7 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba -https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.10-h17cb667_0.conda#0c38cdf4414540aae129822f961b5636 +https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.11-h29cf534_0.conda#1e0e854b77451ac918b4a68f28932b1d https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 @@ -217,7 +217,7 @@ https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1 https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.20.2-h2a5cb19_18.conda#7313674073496cec938f73b71163bc31 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-20_linux64_openblas.conda#9932a1d4e9ecf2d35fb19475446e361e https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.10-h0363672_0.conda#fd9738c3189541787bd967e19587de26 +https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.11-h6d08254_0.conda#971da16e7fc43161329213557688d315 https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 3d319d24ec14b..8e96fd6907e46 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -20,7 +20,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18. https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 -https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.57-h421ea60_0.conda#06f225e6d8c549ad6c0201679828a882 +https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -41,7 +41,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.cond https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.3-hedf47ba_0.conda#b224b81875fbacf570b4bbab0856f649 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 @@ -69,8 +69,8 @@ https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 diff --git a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock index 8c5fb4d778d4b..e139821dbeb3d 100644 --- a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock @@ -47,8 +47,8 @@ https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-6_h0adab6e_openblas https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.2.0-hfd05255_1.conda#450e3ae947fc46b60f1d8f8f318b40d4 https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.2.0-hfd05255_1.conda#ccd93cfa8e54fd9df4e83dbe55ff6e8c https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda#2cf0cf76cc15d360dfa2f17fd6cf9772 -https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.57-h7351971_0.conda#3e40866d979cf6faba7263de9c2b4b99 -https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h3cfd58e_0.conda#f6dd496a1f2b66951110a3a0817f699b +https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.58-h7351971_0.conda#52f1280563f3b48b5f75414cd2d15dd1 +https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.3-h3cfd58e_0.conda#9e8dd0d90ed830107b2c36801035b7db https://conda.anaconda.org/conda-forge/win-64/openblas-0.3.32-pthreads_h4a7f399_0.conda#d7b743c101c58cf009ec7a887e49489f https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda#77eaf2336f3ae749e712f63e36b0f0a1 https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda#3c8f2573569bb816483e5cf57efbbe29 @@ -70,10 +70,10 @@ https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.4-h0c9aed9_1.conda#03 https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-6_hd232482_openblas.conda#06d2ad5bf21e9b86c46783833b2e3c42 https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c -https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h779ef1b_0.conda#be3843e412c9f9d697958aa68c72d09d -https://conda.anaconda.org/conda-forge/noarch/meson-1.10.2-pyhcf101f3_0.conda#fb44f3dcee86e4aa1d6653b1608d666b +https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_0.conda#95591ca5671d2213f5b2d5aa7818420d +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.0-pyhcf101f3_0.conda#b76541e68fea4d511b1ac46a28dcd2c6 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 @@ -114,6 +114,6 @@ https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675f https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/win-64/harfbuzz-14.1.0-h5a1b470_0.conda#d261a3229a9cdded071fa5049c327944 -https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.0-pl5321hfcac499_3.conda#b53193a38f677045dae28f7039122035 -https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.0-py311he824864_1.conda#19b367dda0ee6f48f67d0d72a3fd1a12 +https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.0-pl5321hfcac499_4.conda#1aca2896ea9f0d1f0761a7b278f670a0 +https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.0-py311he824864_2.conda#30aa3757b558ffc51d662b73531dbb1f https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py311h1ea47a8_0.conda#64fe28aa2486e41918239d385336e88e diff --git a/build_tools/github/ubuntu_atlas_lock.txt b/build_tools/github/ubuntu_atlas_lock.txt index d4d097e2b51fa..477f214473f08 100644 --- a/build_tools/github/ubuntu_atlas_lock.txt +++ b/build_tools/github/ubuntu_atlas_lock.txt @@ -12,13 +12,13 @@ iniconfig==2.3.0 # via pytest joblib==1.3.0 # via -r build_tools/github/ubuntu_atlas_requirements.txt -meson==1.10.2 +meson==1.11.0 # via meson-python meson-python==0.19.0 # via -r build_tools/github/ubuntu_atlas_requirements.txt ninja==1.13.0 # via -r build_tools/github/ubuntu_atlas_requirements.txt -packaging==26.0 +packaging==26.1 # via # meson-python # pyproject-metadata From dfdda0464ec5a45db877493b99bf5e4408c504a8 Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Thu, 23 Apr 2026 17:15:51 +0200 Subject: [PATCH 393/462] Fix `check_array(..., dtype='numeric')` to raise `ValueError` on `pandas.StringDType` inputs (#33491) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.utils/33491.fix.rst | 6 ++++ sklearn/utils/tests/test_validation.py | 34 +++++++++++++++++++ sklearn/utils/validation.py | 27 ++++++++++++--- 3 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/33491.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/33491.fix.rst b/doc/whats_new/upcoming_changes/sklearn.utils/33491.fix.rst new file mode 100644 index 0000000000000..d40f0fc8ac63d --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.utils/33491.fix.rst @@ -0,0 +1,6 @@ +- :func:`utils.validation.check_array` now correctly rejects pandas + ``StringDtype`` columns when ``dtype="numeric"`` is requested. In pandas 3, + string columns use ``StringDtype`` instead of ``object`` dtype, which caused + ``check_array`` to silently accept string data instead of raising a + ``ValueError``. + By :user:`Olivier Grisel <ogrisel>`. diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 0065d3a84bc35..42ba52407d151 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -503,6 +503,40 @@ def test_check_array_numeric_error(X): check_array(X, dtype="numeric") +def test_check_array_pandas_string_dtype_numeric_error(): + """check_array raises an error for pandas StringDtype with dtype='numeric'. + + Non-regression test for pandas 3 where string columns use StringDtype + instead of object dtype. check_array should reject string data when + dtype='numeric' is requested. + """ + pd = pytest.importorskip("pandas") + + # DataFrame with all string columns + df_str = pd.DataFrame({"a": ["x", "y", "z"], "b": ["1", "2", "3"]}) + with pytest.raises(ValueError): + check_array(df_str, dtype="numeric") + + # DataFrame with mixed string/numeric columns + df_mixed = pd.DataFrame({"a": [1.0, 2.0, 3.0], "b": ["x", "y", "z"]}) + with pytest.raises(ValueError): + check_array(df_mixed, dtype="numeric") + + # Series with string dtype + s_str = pd.Series(["a", "b", "c"]) + with pytest.raises(ValueError): + check_array(s_str, dtype="numeric", ensure_2d=False) + + # String data with dtype=None should still work + result = check_array(df_str, dtype=None) + assert result.dtype == np.object_ + assert_array_equal(result, df_str.values) + + result = check_array(s_str, dtype=None, ensure_2d=False) + assert result.dtype == np.object_ + assert_array_equal(result, s_str.values) + + @pytest.mark.parametrize( "pd_dtype", ["Int8", "Int16", "UInt8", "UInt16", "Float32", "Float64"] ) diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index ae6ed38a3e16f..40f609ae6869b 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -724,6 +724,16 @@ def _pandas_dtype_needs_early_conversion(pd_dtype): return False +def _is_pandas_string_dtype(dtype): + """Return True if dtype is a pandas StringDtype.""" + try: + from pandas import StringDtype + + return isinstance(dtype, StringDtype) + except ImportError: + return False + + def _is_extension_array_dtype(array): # Pandas extension arrays have a dtype with an na_value return hasattr(array, "dtype") and hasattr(array.dtype, "na_value") @@ -901,8 +911,12 @@ def is_sparse(dtype): pandas_requires_conversion = any( _pandas_dtype_needs_early_conversion(i) for i in dtypes_orig ) + has_pandas_string = any(_is_pandas_string_dtype(d) for d in dtypes_orig) if all(isinstance(dtype_iter, np.dtype) for dtype_iter in dtypes_orig): dtype_orig = np.result_type(*dtypes_orig) + elif has_pandas_string: + # Force object if any of the dtypes is a StringDtype. + dtype_orig = object elif pandas_requires_conversion and any(d == object for d in dtypes_orig): # Force object if any of the dtypes is an object dtype_orig = object @@ -910,20 +924,23 @@ def is_sparse(dtype): elif (_is_extension_array_dtype(array) or hasattr(array, "iloc")) and hasattr( array, "dtype" ): - # array is a pandas series + # array is a pandas series or a pandas array. type_if_series = type(array) pandas_requires_conversion = _pandas_dtype_needs_early_conversion(array.dtype) if isinstance(array.dtype, np.dtype): dtype_orig = array.dtype + elif _is_pandas_string_dtype(array.dtype): + # pandas 3 uses StringDtype for string columns instead of object. + # Treat as object so that dtype_numeric detection works correctly. + dtype_orig = object else: # Set to None to let array.astype work out the best dtype dtype_orig = None if dtype_numeric: - if ( - dtype_orig is not None - and hasattr(dtype_orig, "kind") - and dtype_orig.kind == "O" + if dtype_orig is not None and ( + (hasattr(dtype_orig, "kind") and dtype_orig.kind == "O") + or dtype_orig == object ): # if input is object, convert to float. dtype = xp.float64 From 7cc2bee643f0179a10007ec6a80a5165ec555e86 Mon Sep 17 00:00:00 2001 From: Riya Jha <riya2311jha@gmail.com> Date: Thu, 23 Apr 2026 21:13:50 +0530 Subject: [PATCH 394/462] DOC Update DOI badge in README.rst (#33841) --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index dda307f8248a6..b34f4e90a1ae3 100644 --- a/README.rst +++ b/README.rst @@ -24,7 +24,7 @@ .. |PyPI| image:: https://img.shields.io/pypi/v/scikit-learn :target: https://pypi.org/project/scikit-learn -.. |DOI| image:: https://zenodo.org/badge/21369/scikit-learn/scikit-learn.svg +.. |DOI| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.17880109.svg :target: https://zenodo.org/badge/latestdoi/21369/scikit-learn/scikit-learn .. |Benchmark| image:: https://img.shields.io/badge/Benchmarked%20by-asv-blue From aaa103d16cf3e06e586ba36c07d986d85474a231 Mon Sep 17 00:00:00 2001 From: Dmitry Kobak <dmitry.kobak@uni-tuebingen.de> Date: Thu, 23 Apr 2026 17:58:49 +0200 Subject: [PATCH 395/462] EFF improve the eigsh call in spectral embedding (#33262) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: antoinebaker <antoinebaker@users.noreply.github.com> Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.manifold/33262.efficiency.rst | 4 + sklearn/cluster/tests/test_spectral.py | 4 +- sklearn/manifold/_spectral_embedding.py | 75 +++++++++++-------- .../manifold/tests/test_spectral_embedding.py | 72 +++++++++++++++--- 4 files changed, 110 insertions(+), 45 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.manifold/33262.efficiency.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.manifold/33262.efficiency.rst b/doc/whats_new/upcoming_changes/sklearn.manifold/33262.efficiency.rst new file mode 100644 index 0000000000000..a1e405482e738 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.manifold/33262.efficiency.rst @@ -0,0 +1,4 @@ +- The way ARPACK eigensolver is called in :class:`manifold.SpectralEmbedding` + and :class:`cluster.SpectralClustering` was improved, resulting in faster + runtimes. + By :user:`Dmitry Kobak <dkobak>` diff --git a/sklearn/cluster/tests/test_spectral.py b/sklearn/cluster/tests/test_spectral.py index 8aa17be33c590..436c12e5653a7 100644 --- a/sklearn/cluster/tests/test_spectral.py +++ b/sklearn/cluster/tests/test_spectral.py @@ -107,11 +107,11 @@ def test_precomputed_nearest_neighbors_filtering(global_random_seed): X, y = make_blobs( n_samples=300, random_state=global_random_seed, - centers=[[1, 1, 1], [-1, -1, -1]], + centers=[[5, 5, 5], [-5, -5, -5]], cluster_std=0.01, ) - n_neighbors = 2 + n_neighbors = 10 results = [] for additional_neighbors in [0, 10]: nn = NearestNeighbors(n_neighbors=n_neighbors + additional_neighbors).fit(X) diff --git a/sklearn/manifold/_spectral_embedding.py b/sklearn/manifold/_spectral_embedding.py index e4faf7213ec2f..ef8e3c6b1bd94 100644 --- a/sklearn/manifold/_spectral_embedding.py +++ b/sklearn/manifold/_spectral_embedding.py @@ -329,60 +329,70 @@ def _spectral_embedding( laplacian, dd = csgraph_laplacian( adjacency, normed=norm_laplacian, return_diag=True ) - if eigen_solver == "arpack" or ( - eigen_solver != "lobpcg" - and (not sparse.issparse(laplacian) or n_nodes < 5 * n_components) - ): - # lobpcg used with eigen_solver='amg' has bugs for low number of nodes + + if eigen_solver == "amg" and n_nodes < 5 * n_components: + # LOBPCG used with eigen_solver='amg' has bugs for low number of nodes # for details see the source code in scipy: # https://github.com/scipy/scipy/blob/v0.11.0/scipy/sparse/linalg/eigen # /lobpcg/lobpcg.py#L237 # or matlab: # https://www.mathworks.com/matlabcentral/fileexchange/48-lobpcg-m + warnings.warn( + "AMG solver does not work well with small graphs, using ARPACK instead.", + RuntimeWarning, + ) + eigen_solver = "arpack" + + if eigen_solver == "amg" and not sparse.issparse(laplacian): + warnings.warn( + "AMG solver does not work well with dense matrices, using ARPACK instead.", + RuntimeWarning, + ) + eigen_solver = "arpack" + + if eigen_solver == "arpack": laplacian = _set_diag(laplacian, 1, norm_laplacian) # Here we'll use shift-invert mode for fast eigenvalues - # (see https://docs.scipy.org/doc/scipy/reference/tutorial/arpack.html - # for a short explanation of what this means) - # Because the normalized Laplacian has eigenvalues between 0 and 2, - # I - L has eigenvalues between -1 and 1. ARPACK is most efficient - # when finding eigenvalues of largest magnitude (keyword which='LM') - # and when these eigenvalues are very large compared to the rest. - # For very large, very sparse graphs, I - L can have many, many - # eigenvalues very near 1.0. This leads to slow convergence. So - # instead, we'll use ARPACK's shift-invert mode, asking for the - # eigenvalues near 1.0. This effectively spreads-out the spectrum - # near 1.0 and leads to much faster convergence: potentially an - # orders-of-magnitude speedup over simply using keyword which='LA' - # in standard mode. + # (see https://docs.scipy.org/doc/scipy/tutorial/arpack.html + # for a short explanation of what this means) + # Laplacian (normalized or not) has non-negative eigenvalues + # and we need to find the smallest ones, i.e. closest to 0. + # The efficient way to do it, according to the scipy docs, + # is to use which="LM" and sigma=0. + # Andrew Kniazev recommends to set small negative sigma + # (see https://github.com/scikit-learn/scikit-learn/ + # pull/14647#issuecomment-521304431) because a Laplacian + # has exact at least one exact zero eigenvalue, so sigma=0 + # can lead to problems. try: - # We are computing the opposite of the laplacian inplace so as - # to spare a memory allocation of a possibly very large array tol = 0 if eigen_tol == "auto" else eigen_tol - laplacian *= -1 + v0 = _init_arpack_v0(laplacian.shape[0], random_state) laplacian = check_array( laplacian, accept_sparse="csr", accept_large_sparse=False ) _, diffusion_map = eigsh( - laplacian, k=n_components, sigma=1.0, which="LM", tol=tol, v0=v0 + laplacian, k=n_components, sigma=-1e-5, which="LM", tol=tol, v0=v0 ) - embedding = diffusion_map.T[n_components::-1] + embedding = diffusion_map.T[:n_components] if norm_laplacian: # recover u = D^-1/2 x from the eigenvector output x embedding = embedding / dd - except RuntimeError: - # When submatrices are exactly singular, an LU decomposition - # in arpack fails. We fallback to lobpcg + except RuntimeError: # pragma: no cover + # When submatrices are exactly singular, the LU decomposition + # in ARPACK can fail. In this case, we fallback to LOBPCG. + # Note: this should actually never happen with sigma < 0, + # so the entire `try ... except` structure could be removed. + # There is no unit test for this (hence `pragma: no cover`) + # because it is unclear how to trigger this RuntimeError. + # (https://github.com/scikit-learn/scikit-learn/pull/33262) + warnings.warn("ARPACK has failed, falling back to LOBPCG.", RuntimeWarning) eigen_solver = "lobpcg" - # Revert the laplacian to its opposite to have lobpcg work - laplacian *= -1 elif eigen_solver == "amg": # Use AMG to get a preconditioner and speed up the eigenvalue # problem. - if not sparse.issparse(laplacian): - warnings.warn("AMG works better for sparse matrices") laplacian = check_array( laplacian, dtype=[np.float64, np.float32], accept_sparse=True ) @@ -430,9 +440,8 @@ def _spectral_embedding( laplacian, dtype=[np.float64, np.float32], accept_sparse=True ) if n_nodes < 5 * n_components + 1: - # see note above under arpack why lobpcg has problems with small - # number of nodes - # lobpcg will fallback to eigh, so we short circuit it + # See note above why lobpcg has problems with small number of nodes. + # lobpcg will fallback to eigh, so we short-circuit it if sparse.issparse(laplacian): laplacian = laplacian.toarray() _, diffusion_map = eigh(laplacian, check_finite=False) diff --git a/sklearn/manifold/tests/test_spectral_embedding.py b/sklearn/manifold/tests/test_spectral_embedding.py index 612f5829a9d72..e55d001c2a3d1 100644 --- a/sklearn/manifold/tests/test_spectral_embedding.py +++ b/sklearn/manifold/tests/test_spectral_embedding.py @@ -40,7 +40,7 @@ not pyamg_available, reason="PyAMG is required for the tests in this function." ) -# non centered, sparse centers to check the +# non centered, sparse centers centers = np.array( [ [0.0, 5.0, 0.0, 0.0, 0.0], @@ -48,7 +48,7 @@ [1.0, 0.0, 0.0, 5.0, 1.0], ] ) -n_samples = 1000 +n_samples = 100 n_clusters, n_features = centers.shape S, true_labels = make_blobs( n_samples=n_samples, centers=centers, cluster_std=1.0, random_state=42 @@ -106,6 +106,25 @@ def test_sparse_graph_connected_component(coo_container): assert_array_equal(component_1, component_2) +@pytest.mark.skipif( + not pyamg_available, reason="PyAMG is required for the tests in this function." +) +def test_fallback_amg(): + random_state = np.random.RandomState(36) + data = random_state.randn(10, 30) + sims = rbf_kernel(data) + + # eigen_solver='amg' should raise a warning and fallback to 'arpack' + # when the Laplacian is dense. + with pytest.warns(RuntimeWarning, match="dense matrices"): + _ = spectral_embedding(sims, eigen_solver="amg", n_components=1) + + # eigen_solver='amg' should raise a warning and fallback to 'arpack' + # when the graph is very small (n_nodes < 5 * n_components + 1). + with pytest.warns(RuntimeWarning, match="small graphs"): + _ = spectral_embedding(sims, eigen_solver="amg", n_components=5) + + # TODO: investigate why this test is seed-sensitive on 32-bit Python # runtimes. Is this revealing a numerical stability problem ? Or is it # expected from the test numerical design ? In the latter case the test @@ -201,11 +220,11 @@ def test_spectral_embedding_precomputed_affinity( def test_precomputed_nearest_neighbors_filtering(): # Test precomputed graph filtering when containing too many neighbors - n_neighbors = 2 + n_neighbors = 10 results = [] for additional_neighbors in [0, 10]: nn = NearestNeighbors(n_neighbors=n_neighbors + additional_neighbors).fit(S) - graph = nn.kneighbors_graph(S, mode="connectivity") + graph = nn.kneighbors_graph(S, mode="distance") embedding = ( SpectralEmbedding( random_state=0, @@ -247,24 +266,53 @@ def test_spectral_embedding_callable_affinity(sparse_container, seed=36): _assert_equal_with_sign_flipping(embed_rbf, embed_callable, 0.05) +@pytest.mark.parametrize("dtype", (np.float32, np.float64)) +def test_spectral_embedding_lobpcg_solver(dtype, global_random_seed): + # Tests that the results are the same when using arpack + # and lobpcg solvers. Note that we use RBF kernel here + # to make the graph connected, so that eigenvectors + # are non-trivial and eigenvalues are non-repeated. + se_lobpcg = SpectralEmbedding( + n_components=2, + affinity="rbf", + eigen_solver="lobpcg", + eigen_tol=1e-5, + random_state=np.random.RandomState(global_random_seed), + ) + se_arpack = SpectralEmbedding( + n_components=2, + affinity="rbf", + eigen_solver="arpack", + eigen_tol=0, + random_state=np.random.RandomState(global_random_seed), + ) + embed_lobpcg = se_lobpcg.fit_transform(S.astype(dtype)) + embed_arpack = se_arpack.fit_transform(S.astype(dtype)) + _assert_equal_with_sign_flipping(embed_lobpcg, embed_arpack, 1e-5) + + @pytest.mark.skipif( not pyamg_available, reason="PyAMG is required for the tests in this function." ) @pytest.mark.parametrize("dtype", (np.float32, np.float64)) @pytest.mark.parametrize("coo_container", COO_CONTAINERS) def test_spectral_embedding_amg_solver(dtype, coo_container, seed=36): + # Tests that the results are the same when using arpack + # and amg solvers. Note that we use RBF kernel here + # to make the graph connected, so that eigenvectors + # are non-trivial and eigenvalues are non-repeated. se_amg = SpectralEmbedding( n_components=2, - affinity="nearest_neighbors", + affinity="rbf", eigen_solver="amg", - n_neighbors=5, + eigen_tol=1e-5, random_state=np.random.RandomState(seed), ) se_arpack = SpectralEmbedding( n_components=2, - affinity="nearest_neighbors", + affinity="rbf", eigen_solver="arpack", - n_neighbors=5, + eigen_tol=0, random_state=np.random.RandomState(seed), ) embed_amg = se_amg.fit_transform(S.astype(dtype)) @@ -331,12 +379,16 @@ def test_spectral_embedding_amg_solver_failure(dtype, seed=36): def test_pipeline_spectral_clustering(seed=36): # Test using pipeline to do spectral clustering + # Note that SpectralEmbedding drops the first eigenvector, + # contrary to SpectralClustering. So here for n_clusters + # we will use n_components = n_clusters - 1 + # eigenvectors (since the first one is dropped). random_state = np.random.RandomState(seed) se_rbf = SpectralEmbedding( - n_components=n_clusters, affinity="rbf", random_state=random_state + n_components=n_clusters - 1, affinity="rbf", random_state=random_state ) se_knn = SpectralEmbedding( - n_components=n_clusters, + n_components=n_clusters - 1, affinity="nearest_neighbors", n_neighbors=5, random_state=random_state, From 8ad241439ea37ab0840adef25320a2e9e86e9891 Mon Sep 17 00:00:00 2001 From: Anvay <anvaybarhate@gmail.com> Date: Thu, 23 Apr 2026 22:14:13 +0530 Subject: [PATCH 396/462] DOC fix DecisionBoundaryDisplay color consistency in plot_sgd_iris example (#33719) --- examples/linear_model/plot_sgd_iris.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/linear_model/plot_sgd_iris.py b/examples/linear_model/plot_sgd_iris.py index e8aaf3a2e13a2..3e8b51e056a11 100644 --- a/examples/linear_model/plot_sgd_iris.py +++ b/examples/linear_model/plot_sgd_iris.py @@ -26,7 +26,7 @@ # avoid this ugly slicing by using a two-dim dataset X = iris.data[:, :2] y = iris.target -colors = "bry" +colors = "byr" # shuffle idx = np.arange(X.shape[0]) @@ -45,7 +45,6 @@ DecisionBoundaryDisplay.from_estimator( clf, X, - cmap=plt.cm.Paired, ax=ax, response_method="predict", xlabel=iris.feature_names[0], From fd183c70f4f3026bb5d4849dc0819f18d2f0587b Mon Sep 17 00:00:00 2001 From: Christian Veenhuis <124370897+ChVeen@users.noreply.github.com> Date: Thu, 23 Apr 2026 23:17:07 +0200 Subject: [PATCH 397/462] DOC FIX annoying blue underscores in `README.rst` (#33834) --- README.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.rst b/README.rst index b34f4e90a1ae3..bfd5bf71da8d3 100644 --- a/README.rst +++ b/README.rst @@ -3,7 +3,7 @@ |GitHubActions| |Codecov| |CircleCI| |Nightly wheels| |Ruff| |PythonVersion| |PyPI| |DOI| |Benchmark| -.. |GitHubActions| image:: https://github.com/scikit-learn/scikit-learn/actions/workflows/unit-tests.yml/badge.svg +.. |GitHubActions| image:: https://github.com/scikit-learn/scikit-learn/actions/workflows/unit-tests.yml/badge.svg? :target: https://github.com/scikit-learn/scikit-learn/actions/workflows/unit-tests.yml?query=branch%3Amain .. |CircleCI| image:: https://circleci.com/gh/scikit-learn/scikit-learn/tree/main.svg?style=shield @@ -15,16 +15,16 @@ .. |Nightly wheels| image:: https://github.com/scikit-learn/scikit-learn/actions/workflows/wheels.yml/badge.svg?event=schedule :target: https://github.com/scikit-learn/scikit-learn/actions?query=workflow%3A%22Wheel+builder%22+event%3Aschedule -.. |Ruff| image:: https://img.shields.io/badge/code%20style-ruff-000000.svg +.. |Ruff| image:: https://img.shields.io/badge/code%20style-ruff-000000.svg? :target: https://github.com/astral-sh/ruff -.. |PythonVersion| image:: https://img.shields.io/pypi/pyversions/scikit-learn.svg +.. |PythonVersion| image:: https://img.shields.io/pypi/pyversions/scikit-learn.svg? :target: https://pypi.org/project/scikit-learn/ .. |PyPI| image:: https://img.shields.io/pypi/v/scikit-learn :target: https://pypi.org/project/scikit-learn -.. |DOI| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.17880109.svg +.. |DOI| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.17880109.svg? :target: https://zenodo.org/badge/latestdoi/21369/scikit-learn/scikit-learn .. |Benchmark| image:: https://img.shields.io/badge/Benchmarked%20by-asv-blue From 9db12f00a6da119e7d500d0c643ace6c81c5b0ec Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Fri, 24 Apr 2026 17:25:02 +0200 Subject: [PATCH 398/462] DOC Use DecisionBoundaryDisplay colors for scatter in Nearest Neighbors Classification example (#33849) --- examples/neighbors/plot_classification.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/neighbors/plot_classification.py b/examples/neighbors/plot_classification.py index 1754869943ac7..676fed4d32bc9 100644 --- a/examples/neighbors/plot_classification.py +++ b/examples/neighbors/plot_classification.py @@ -53,6 +53,7 @@ # Now, we fit two classifiers with different values of the parameter # `weights`. We plot the decision boundary of each classifier as well as the original # dataset to observe the difference. +import matplotlib as mpl import matplotlib.pyplot as plt from sklearn.inspection import DecisionBoundaryDisplay @@ -72,11 +73,14 @@ alpha=0.5, ax=ax, ) - scatter = disp.ax_.scatter(X.iloc[:, 0], X.iloc[:, 1], c=y, edgecolors="k") + cmap = mpl.colors.ListedColormap(disp.multiclass_colors_) + scatter = disp.ax_.scatter( + X.iloc[:, 0], X.iloc[:, 1], c=y, cmap=cmap, edgecolors="k" + ) disp.ax_.legend( scatter.legend_elements()[0], iris.target_names, - loc="lower left", + loc="lower right", title="Classes", ) _ = disp.ax_.set_title( From 35bf8c6653ce8221a04a75f7a4ff49c25629a5f5 Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Sat, 25 Apr 2026 11:03:15 +1000 Subject: [PATCH 399/462] TST Add common test for mixed namespace/device array inputs to estimators (#33525) Co-authored-by: Omar Salman <omar.salman@arbisoft.com> --- sklearn/linear_model/_base.py | 17 +- sklearn/linear_model/_logistic.py | 3 +- sklearn/linear_model/_ridge.py | 4 +- sklearn/utils/_array_api.py | 5 +- .../utils/_test_common/instance_generator.py | 17 +- sklearn/utils/estimator_checks.py | 255 ++++++++++++++---- sklearn/utils/tests/test_estimator_checks.py | 4 + sklearn/utils/validation.py | 2 +- 8 files changed, 237 insertions(+), 70 deletions(-) diff --git a/sklearn/linear_model/_base.py b/sklearn/linear_model/_base.py index 2c5fa660df74e..829f0543f0b69 100644 --- a/sklearn/linear_model/_base.py +++ b/sklearn/linear_model/_base.py @@ -26,7 +26,6 @@ _asarray_with_order, _average, _expit, - _is_numpy_namespace, check_same_namespace, get_namespace, get_namespace_and_device, @@ -408,21 +407,21 @@ def predict(self, X): Vector containing the class labels for each sample. """ check_same_namespace(X, self, attribute="coef_", method="predict") - xp, _ = get_namespace(X) + xp, _, device_ = get_namespace_and_device(X) scores = self.decision_function(X) if len(scores.shape) == 1: indices = xp.astype(scores > 0, indexing_dtype(xp)) else: indices = xp.argmax(scores, axis=1) - # If `y` consists of strings during fitting then `self.classes_` will - # also contain strings and we handle such a scenario by returning the - # predictions according to the namespace of `self.classes_` i.e. numpy. - xp_classes, _ = get_namespace(self.classes_) - if _is_numpy_namespace(xp_classes): - indices = move_to(indices, xp=np, device="cpu") + xp_classes, _, device_classes = get_namespace_and_device(self.classes_) + indices = move_to(indices, xp=xp_classes, device=device_classes) - return xp_classes.take(self.classes_, indices, axis=0) + y_pred = xp_classes.take(self.classes_, indices, axis=0) + if isinstance(y_pred[0], str): + return y_pred + else: + return move_to(y_pred, xp=xp, device=device_) def _predict_proba_lr(self, X): """Probability estimation for OvR logistic regression. diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index a11861448f3c7..779a76265eac5 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -312,7 +312,7 @@ def _logistic_regression_path( n_features + int(fit_intercept), dtype=_matching_numpy_dtype(X, xp=xp) ) # classes[1] is the "positive label" - mask = xp.asarray(y == classes[1], device=device_) + mask = move_to(y == classes[1], xp=xp, device=device_) y_bin = xp.ones(y.shape, dtype=X.dtype, device=device_) if solver == "liblinear": y_bin[~mask] = -1.0 @@ -1246,6 +1246,7 @@ def fit(self, X, y, sample_weight=None): raise ValueError("l1_ratio must be specified when penalty is elasticnet.") xp, _, device_ = get_namespace_and_device(X) + sample_weight = move_to(sample_weight, xp=xp, device=device_) xp_y, _ = get_namespace(y) if self.penalty is None: diff --git a/sklearn/linear_model/_ridge.py b/sklearn/linear_model/_ridge.py index 5dbdcb5af2404..77bb47f0e82ce 100644 --- a/sklearn/linear_model/_ridge.py +++ b/sklearn/linear_model/_ridge.py @@ -1258,7 +1258,9 @@ def fit(self, X, y, sample_weight=None): Fitted estimator. """ _accept_sparse = _get_valid_accept_sparse(sparse.issparse(X), self.solver) - xp, _ = get_namespace(X, y, sample_weight) + xp, _, device_ = get_namespace_and_device(X) + y, sample_weight = move_to(y, sample_weight, xp=xp, device=device_) + X, y = validate_data( self, X, diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 634364553a1d1..1431e0dba68de 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -32,6 +32,8 @@ tuple, ) +NamespaceAndDevice = namedtuple("NamespaceAndDevice", ["xp", "device"]) + def yield_namespaces(include_numpy_namespaces=True): """Yield supported namespace. @@ -123,9 +125,6 @@ def yield_mixed_namespace_input_permutations(): * array-api-strict to non-NumPy (this pair also has no special hardware requirements to allow for local testing) """ - - NamespaceAndDevice = namedtuple("NamespaceAndDevice", ["xp", "device"]) - yield ( NamespaceAndDevice("cupy", None), NamespaceAndDevice("torch", "cuda"), diff --git a/sklearn/utils/_test_common/instance_generator.py b/sklearn/utils/_test_common/instance_generator.py index bf77a4514aa9e..a1a6cc975a60d 100644 --- a/sklearn/utils/_test_common/instance_generator.py +++ b/sklearn/utils/_test_common/instance_generator.py @@ -951,6 +951,9 @@ def _yield_instances_for_check(check, estimator_orig): "sample_weight is not equivalent to removing/repeating samples." ), }, + CalibratedClassifierCV: { + "check_array_api_mixed_inputs": "mixed array API input support not added yet", + }, ColumnTransformer: { "check_estimators_empty_data_messages": "FIXME", "check_estimators_nan_inf": "FIXME", @@ -984,7 +987,11 @@ def _yield_instances_for_check(check, estimator_orig): "sample_weight is not equivalent to removing/repeating samples." ), }, + GaussianMixture: { + "check_array_api_mixed_inputs": "mixed array API input support not added yet", + }, GaussianNB: { + "check_array_api_mixed_inputs": "mixed array API input support not added yet", "check_array_api_same_namespace": "check_same_namespace not yet added", }, GradientBoostingClassifier: { @@ -1010,6 +1017,7 @@ def _yield_instances_for_check(check, estimator_orig): "check_requires_y_none": "Doesn't fail gracefully", }, HalvingGridSearchCV: { + "check_array_api_mixed_inputs": "mixed array API input support not added yet", "check_fit2d_1sample": ( "Fail during parameter check since min/max resources requires more samples" ), @@ -1020,6 +1028,7 @@ def _yield_instances_for_check(check, estimator_orig): "check_requires_y_none": "Doesn't fail gracefully", }, HalvingRandomSearchCV: { + "check_array_api_mixed_inputs": "mixed array API input support not added yet", "check_fit2d_1sample": ( "Fail during parameter check since min/max resources requires more samples" ), @@ -1076,6 +1085,9 @@ def _yield_instances_for_check(check, estimator_orig): KNeighborsTransformer: { "check_methods_sample_order_invariance": "check is not applicable." }, + LinearDiscriminantAnalysis: { + "check_array_api_mixed_inputs": "mixed array API input support not added yet", + }, LabelEncoder: { "check_array_api_same_namespace": "check_same_namespace not yet added", }, @@ -1164,6 +1176,7 @@ def _yield_instances_for_check(check, estimator_orig): ), }, PCA: { + "check_array_api_mixed_inputs": "mixed array API input support not added yet", # TODO: see gh-33205 for details "check_array_api_input": "`linalg.inv` fails because input is singular", "check_array_api_same_namespace": "check_same_namespace not yet added", @@ -1188,6 +1201,7 @@ def _yield_instances_for_check(check, estimator_orig): ), }, PoissonRegressor: { + "check_array_api_mixed_inputs": "mixed array API input support not added yet", "check_array_api_same_namespace": "check_same_namespace not yet added", }, PolynomialFeatures: { @@ -1249,9 +1263,10 @@ def _yield_instances_for_check(check, estimator_orig): ) }, RidgeClassifier: { + "check_array_api_mixed_inputs": "mixed array API input support not added yet", "check_non_transformer_estimators_n_iter": ( "n_iter_ cannot be easily accessed." - ) + ), }, SelfTrainingClassifier: { "check_non_transformer_estimators_n_iter": "n_iter_ can be 0." diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index a9dcbf16abe77..b3cc04c111d86 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -61,9 +61,12 @@ from sklearn.preprocessing import StandardScaler, scale from sklearn.utils import _safe_indexing, shuffle from sklearn.utils._array_api import ( + NamespaceAndDevice, _atol_for_type, + _max_precision_float_dtype, get_namespace, move_to, + yield_mixed_namespace_input_permutations, yield_namespace_device_dtype_combinations, ) from sklearn.utils._array_api import device as array_device @@ -341,18 +344,20 @@ def _yield_outliers_checks(estimator): def _yield_array_api_checks(estimator, only_numpy=False): + # Note all tests run with array API dispatch enabled if only_numpy: - # Enabling array API dispatch and using NumPy inputs should not - # change results, even if the estimator does not explicitly support - # array API. + # For estimators without explicit array API support; check that enabling + # array API dispatch and using NumPy inputs does not change results. + # Output checks are looser (expect_only_array_outputs=False). yield partial( check_array_api_input, array_namespace="numpy", expect_only_array_outputs=False, ) else: - # These extended checks should pass for all estimators that declare - # array API support in their tags. + # 1. All inputs from the same namespace and device. + # Extended output checks should pass for all + # estimators that declare array API support in their tags. for ( array_namespace, device_name, @@ -364,9 +369,24 @@ def _yield_array_api_checks(estimator, only_numpy=False): device_name=device_name, dtype_name=dtype_name, ) + # 2. Mixed namespace/device inputs: X uses one namespace/device + # y and sample_weight use another. + # We intend for all estimators that support array API to also support + # mixed namespace/device inputs. Some are in the process of adding mixed + # input support and are listed in PER_ESTIMATOR_XFAIL_CHECKS. + for ( + other_ns_and_device, + X_ns_and_device, + _, + ) in yield_mixed_namespace_input_permutations(): + yield partial( + check_array_api_mixed_inputs, + other_ns_and_device=other_ns_and_device, + X_ns_and_device=X_ns_and_device, + ) + # 3. Namespace/device consistency between fit and predict/transform # Only test with one namespace to keep costs down - # There should be no dependency on the exact - # namespace used. + # There should be no dependency on the exact namespace used. yield partial( check_array_api_same_namespace, array_namespace="array_api_strict", @@ -1063,36 +1083,27 @@ def check_supervised_y_no_nan(name, estimator_orig): estimator.fit(X, y) -def check_array_api_input( - name, +def _check_array_api_core( estimator_orig, - array_namespace, - device_name=None, - dtype_name="float64", + X_ns_and_device, + other_ns_and_device, + dtype_name=None, check_values=False, check_sample_weight=False, expect_only_array_outputs=True, ): - """Check that the estimator can work consistently with the Array API - - By default, this just checks that the types and shapes of the arrays are - consistent with calling the same estimator with numpy arrays. - - When check_values is True, it also checks that calling the estimator on the - array_api Array gives the same results as ndarrays. - - When check_sample_weight is True, dummy sample weights are passed to the - fit call. - - When expect_only_array_outputs is False, the check is looser: in particular - it accepts non-array outputs such as sparse data structures. This is - useful to test that enabling array API dispatch does not change the - behavior of any estimator fed with NumPy inputs, even for estimators that - do not support array API. - """ - xp, device = _array_api_for_tests(array_namespace, device_name) + """Helper to check estimator attributes and method outputs.""" + xp_X, device_X = _array_api_for_tests(X_ns_and_device.xp, X_ns_and_device.device) + xp_other, device_other = _array_api_for_tests( + other_ns_and_device.xp, other_ns_and_device.device + ) X, y = make_classification(n_samples=30, n_features=10, random_state=42) + if dtype_name is None: + max_float_dtype = _max_precision_float_dtype(xp_X, device_X) + # Convert to string, so it is accepted by NumPy (`X` is NumPy array) + dtype_name = "float32" if max_float_dtype == xp_X.float32 else "float64" + X = X.astype(dtype_name, copy=False) X = _enforce_estimator_tags_X(estimator_orig, X) @@ -1101,40 +1112,46 @@ def check_array_api_input( est = clone(estimator_orig) set_random_state(est) - X_xp = xp.asarray(X, device=device) - y_xp = xp.asarray(y, device=device) + X_xp = xp_X.asarray(X, device=device_X) + y_xp = xp_other.asarray(y, device=device_other) + fit_kwargs = {} fit_kwargs_xp = {} - if check_sample_weight: - fit_kwargs["sample_weight"] = np.ones(X.shape[0], dtype=X.dtype) - fit_kwargs_xp["sample_weight"] = xp.asarray( - fit_kwargs["sample_weight"], device=device + if check_sample_weight and has_fit_parameter(estimator_orig, "sample_weight"): + max_dtype_other = _max_precision_float_dtype(xp_other, device_other) + dtype_other = "float32" if max_dtype_other == xp_other.float32 else "float64" + fit_kwargs["sample_weight"] = np.ones(X.shape[0], dtype=dtype_other) + fit_kwargs_xp["sample_weight"] = xp_other.asarray( + fit_kwargs["sample_weight"], device=device_other ) est.fit(X, y, **fit_kwargs) - array_attributes = { - key: value for key, value in vars(est).items() if isinstance(value, np.ndarray) - } - est_xp = clone(est) with config_context(array_api_dispatch=True): est_xp.fit(X_xp, y_xp, **fit_kwargs_xp) - input_ns = get_namespace(X_xp)[0].__name__ - # Fitted attributes which are arrays must have the same - # namespace as the one of the training data. + X_ns = xp_X.__name__ + + array_attributes = { + key: value for key, value in vars(est).items() if isinstance(value, np.ndarray) + } + + # Fitted attributes which are arrays must have the same namespace as `X`, + # except `classes_`, to allow it to be string when `y` is string. for key, attribute in array_attributes.items(): est_xp_param = getattr(est_xp, key) with config_context(array_api_dispatch=True): attribute_ns = get_namespace(est_xp_param)[0].__name__ - assert attribute_ns == input_ns, ( - f"'{key}' attribute is in wrong namespace, expected {input_ns} " - f"got {attribute_ns}" - ) + if key != "classes_": + assert attribute_ns == X_ns, ( + f"'{key}' attribute is in wrong namespace, expected {X_ns} " + f"got {attribute_ns}" + ) with config_context(array_api_dispatch=True): - assert array_device(est_xp_param) == array_device(X_xp) + if key != "classes_": + assert array_device(est_xp_param) == array_device(X_xp) est_xp_param_np = move_to(est_xp_param, xp=np, device="cpu") if check_values: @@ -1146,7 +1163,9 @@ def check_array_api_input( ) else: assert attribute.shape == est_xp_param_np.shape - if device == "mps" and np.issubdtype(est_xp_param_np.dtype, np.floating): + if X_ns_and_device.device == "mps" and np.issubdtype( + est_xp_param_np.dtype, np.floating + ): # for mps devices the maximum supported floating dtype is float32 assert est_xp_param_np.dtype == np.float32 else: @@ -1173,7 +1192,7 @@ def check_array_api_input( # all the array API libraries (PyTorch, jax, CuPy) accept indexing with a # numpy array. This is probably not worth doing anything about for # now since array-api-strict seems a bit too strict ... - numpy_asarray_works = xp.__name__ != "array_api_strict" + numpy_asarray_works = xp_X.__name__ != "array_api_strict" except (TypeError, RuntimeError, ValueError): # PyTorch with CUDA device and CuPy raise TypeError consistently. @@ -1220,8 +1239,8 @@ def check_array_api_input( with config_context(array_api_dispatch=True): result_ns = get_namespace(result_xp)[0].__name__ - assert result_ns == input_ns, ( - f"'{method}' output is in wrong namespace, expected {input_ns}, " + assert result_ns == X_ns, ( + f"'{method}' output is in wrong namespace, expected {X_ns}, " f"got {result_ns}." ) @@ -1249,9 +1268,9 @@ def check_array_api_input( if expect_only_array_outputs: with config_context(array_api_dispatch=True): inverse_result_ns = get_namespace(inverse_result_xp)[0].__name__ - assert inverse_result_ns == input_ns, ( + assert inverse_result_ns == X_ns, ( "'inverse_transform' output is in wrong namespace, expected" - f" {input_ns}, got {inverse_result_ns}." + f" {X_ns}, got {inverse_result_ns}." ) with config_context(array_api_dispatch=True): assert array_device(result_xp) == array_device(X_xp) @@ -1269,6 +1288,70 @@ def check_array_api_input( assert inverse_result.dtype == inverse_result_xp_np.dtype +def check_array_api_input( + name, + estimator_orig, + array_namespace, + device_name=None, + dtype_name=None, + check_values=False, + check_sample_weight=False, + expect_only_array_outputs=True, +): + """Check that the estimator can work consistently with the Array API. + + All inputs are of the same namespace/device. See `check_array_api_mixed_inputs` + for testing of inputs from different namespaces/devices. + + By default, this just checks that the types and shapes of the arrays are + consistent with calling the same estimator with numpy arrays. + + Parameters + ---------- + name : str + The name of the estimator. Used in error messages but ignored here. + + estimator_orig : estimator + Original (uncloned) estimator instance. + + array_namespace : str + The name of the Array API namespace of all estimator inputs. + + device_name : str, default=None + The name of the device on which to allocate the estimator input arrays. + + dtype_name : str, default=None + The name of the data type to use for arrays. If `None`, + `_max_precision_float_dtype` of namespace and device of + `X_ns_and_device` used. + + check_values : bool, default=False + Whether to check the values of attributes, method outputs (including + `inverse_transform`) obtained with array API inputs match that of all-NumPy + inputs. If `False` only the namespace, device, shape and dtype of attributes + and method outputs are checked. + + check_sample_weight : bool, default=False + Whether to pass dummy weights to the fit call. + + expect_only_array_outputs : bool, default=True + Whether to expect non-array outputs such as sparse data structures and lists. + If `False` the checks are looser; device, shape and dtype checks for method + outputs are skipped and only a smoke test is performed for `inverse_transform`. + """ + X_ns_and_device = NamespaceAndDevice(array_namespace, device_name) + _check_array_api_core( + estimator_orig, + X_ns_and_device=X_ns_and_device, + # Make all array inputs of the same namespace/device + other_ns_and_device=X_ns_and_device, + dtype_name=dtype_name, + check_values=check_values, + check_sample_weight=check_sample_weight, + expect_only_array_outputs=expect_only_array_outputs, + ) + + def check_array_api_input_and_values( name, estimator_orig, @@ -1288,6 +1371,70 @@ def check_array_api_input_and_values( ) +def check_array_api_mixed_inputs( + name, + estimator_orig, + X_ns_and_device, + other_ns_and_device, + check_values=False, + check_sample_weight=True, + expect_only_array_outputs=True, +): + """Check `estimator_orig` works with mixed namespace/device array API inputs. + + For this check the input `X` uses one namespace/device, and the other inputs + (`y` and `sample_weight`) use another namespace/device. The tested namespace + combinations are generated by `yield_mixed_namespace_input_permutations`. + The goal of the check is to make sure estimators move `y` and `sample_weight` + to the namespace/device of `X` when needed. + + See `check_array_api_input` for testing of inputs from the same + namespaces/devices. + + Note that the default of `check_sample_weight` is `True`, unlike + `check_array_api_input`. + + Parameters + ---------- + name : str + The name of the estimator. Used in error messages but ignored here. + + estimator_orig : estimator + Original (uncloned) estimator instance. + + X_ns_and_device : NamedTuple + Namespace and device of reference array API input: `X` as "everything + follows X". + + other_ns_and_device : NamedTuple + Namespace and device of other array API inputs. Used for `y` and + `sample_weight`. + + check_values : bool, default=False + Whether to check the values of attributes, method outputs (including + `inverse_transform`) obtained with array API inputs match that of all-NumPy + inputs. If `False` only the namespace, device, shape and dtype of attributes + and method outputs are checked. + + check_sample_weight : bool, default=True + Whether to pass dummy weights to the fit call. + + expect_only_array_outputs : bool, default=True + Whether to expect non-array outputs such as sparse data structures and lists. + If `False` the checks are looser; device, shape and dtype checks for method + outputs are skipped and only a smoke test is performed for `inverse_transform`. + """ + _check_array_api_core( + estimator_orig, + X_ns_and_device=X_ns_and_device, + other_ns_and_device=other_ns_and_device, + dtype_name=None, + check_values=check_values, + check_sample_weight=check_sample_weight, + expect_only_array_outputs=expect_only_array_outputs, + ) + + def check_array_api_same_namespace( name, estimator_orig, array_namespace, device_name=None ): diff --git a/sklearn/utils/tests/test_estimator_checks.py b/sklearn/utils/tests/test_estimator_checks.py index f94432c79a2db..0b7a5c2d2f633 100644 --- a/sklearn/utils/tests/test_estimator_checks.py +++ b/sklearn/utils/tests/test_estimator_checks.py @@ -1738,6 +1738,10 @@ def test_estimator_with_set_output(): "this check is expected to fail because pandas and polars" " are not compatible with the array api." ), + "check_array_api_mixed_inputs": ( + "this check is expected to fail because pandas and polars" + " are not compatible with the array api." + ), "check_array_api_same_namespace": ( "this check is expected to fail because pandas and polars" " are not compatible with the array api." diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index 40f609ae6869b..f232c60e0dd41 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -2181,7 +2181,7 @@ def _check_sample_weight( if force_float_dtype and dtype is None: dtype = float_dtypes if is_array_api and ensure_same_device: - sample_weight = xp.asarray(sample_weight, device=device) + sample_weight = move_to(sample_weight, xp=xp, device=device) sample_weight = check_array( sample_weight, accept_sparse=False, From c2310ba55a9c0c23fd0af38013395485a81b2c58 Mon Sep 17 00:00:00 2001 From: Dhruv Sharma <dhruv7477@gmail.com> Date: Sat, 25 Apr 2026 16:37:17 +0530 Subject: [PATCH 400/462] DOC improve safe_sparse_dot docstring and remove stale ignore entry (#33853) --- sklearn/tests/test_docstring_parameters.py | 1 - sklearn/utils/extmath.py | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sklearn/tests/test_docstring_parameters.py b/sklearn/tests/test_docstring_parameters.py index d8b6fa0361ffd..250cb938c581e 100644 --- a/sklearn/tests/test_docstring_parameters.py +++ b/sklearn/tests/test_docstring_parameters.py @@ -55,7 +55,6 @@ "sklearn.utils.deprecation.load_mlcomp", "sklearn.pipeline.make_pipeline", "sklearn.pipeline.make_union", - "sklearn.utils.extmath.safe_sparse_dot", "HalfBinomialLoss", ] diff --git a/sklearn/utils/extmath.py b/sklearn/utils/extmath.py index 4fddf5c03a801..c0569f60d6f0b 100644 --- a/sklearn/utils/extmath.py +++ b/sklearn/utils/extmath.py @@ -169,7 +169,9 @@ def safe_sparse_dot(a, b, *, dense_output=False): Parameters ---------- a : {ndarray, sparse matrix} + First operand of the dot product. b : {ndarray, sparse matrix} + Second operand of the dot product. dense_output : bool, default=False When False, ``a`` and ``b`` both being sparse will yield sparse output. When True, output will always be a dense array. From 037ff5b6ec229d84cf8fee5942cce28c3fea4858 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 27 Apr 2026 04:10:53 -0400 Subject: [PATCH 401/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33863) Co-authored-by: Lock file bot <noreply@github.com> --- ...a_forge_cuda_array-api_linux-64_conda.lock | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 35a2773d5f4eb..ecadfdcf2f988 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -8,12 +8,12 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.26.0-ha770c72_0.conda#cb93c6e226a7bed5557601846555153d -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_10.conda#590b5a14299d67b9669fe5eb1fdd4d3b https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 +https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_11.conda#4a1793b78e4309bbdb99bd033226f0d2 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/noarch/cuda-cccl_linux-64-12.9.27-ha770c72_0.conda#87ff6381e33b76e5b9b179a2cdd005ec https://conda.anaconda.org/conda-forge/noarch/cuda-crt-dev_linux-64-12.9.86-ha770c72_2.conda#79d280de61e18010df5997daea4743df https://conda.anaconda.org/conda-forge/linux-64/cuda-crt-tools-12.9.86-ha770c72_2.conda#503a94e20d2690d534d676a764a1852c @@ -24,7 +24,8 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/noarch/libnvptxcompiler-dev_linux-64-12.9.86-ha770c72_2.conda#a66a909acf08924aced622903832a937 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.3-h4922eb0_0.conda#f7781cb22afa62ef27fd0b3300c53c86 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.4-h4922eb0_0.conda#fa2c5c7f8d5319ab9c9fcbbd04022abf +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_11.conda#c0004c583be9ac82ad2115bc08f3d77d https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_linux-64-12.9.79-h3f2d84a_0.conda#86e40eb67d83f1a58bdafdd44e5a77c6 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -109,7 +110,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libudev1-260.1-h6569c3e_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 -https://conda.anaconda.org/conda-forge/linux-64/nccl-2.29.7.1-h8b5a6f3_0.conda#b093fe1438c5e5a1fd38850df59cf699 +https://conda.anaconda.org/conda-forge/linux-64/nccl-2.30.3.1-h4d09622_0.conda#4f76723fe649e2b91d4b913e8c591bb7 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 @@ -140,7 +141,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.co https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 https://conda.anaconda.org/rapidsai/linux-64/librmm-26.04.00-cuda12_260408_48b36cc6.conda#815e224bae37f1bf6491fe3145adbda2 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 -https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef +https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h7d032f7_2.conda#b6e326fbe1e3948da50ec29cee0380db https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 @@ -159,7 +160,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.con https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 https://conda.anaconda.org/conda-forge/linux-64/libcublas-dev-12.9.1.4-h676940d_1.conda#f90f4ff087ac29005c6989ea0fb2735a https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.conda#a178a1f3642521f104ecceeefa138d01 https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_1.conda#c5b8ea827c65e5811d61aa49cd0bae9a @@ -201,19 +202,19 @@ https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928 https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.49.00-cuda12_260408_8d47a9ff.conda#b8ddfc6e13aa7b755392fe8cb6f9250a https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.595.45-pyhd8ed1ab_1.conda#dc8587ae654e96031728802016e8258c https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -242,12 +243,12 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.6-py314h7ea930b_0.conda#a8841fd311da95db72916f58eff3f5a6 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_1.conda#80daec8cf93185515ac7b5d359e3f929 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 @@ -267,7 +268,7 @@ https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.co https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 @@ -275,47 +276,47 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3. https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-24.0.0-ha7f89c6_0_cpu.conda#8aeb79715524b48267068fb0fd185956 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_9_cpu.conda#b3ba3597c481a636fc161185819cf6b1 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-24.0.0-h53684a4_0_cpu.conda#73e0aeaa603ff40128e75435a3c5ac77 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_9_cpu.conda#2dccf1b6cf9dba8857050740dbc0497e +https://conda.anaconda.org/conda-forge/linux-64/libparquet-24.0.0-h7376487_0_cpu.conda#c828cca50cd3a7c53d12ce8f0872c6ec https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.7.0-cuda12_py314h6985919_0.conda#ec0ac10cf8ea10e2ca9437a1feebbfc6 https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py314hf9e62a7_0.conda#4fe7bd0212d2f7788765875755f67684 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-24.0.0-h635bf11_0_cpu.conda#178d7e3f5c392e606ccd0aaff4331019 https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_mkl_hd6d2a1f_303.conda#5b8a8672aca66f3871aab4d0d1a8f796 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py314hb4ffadd_0.conda#41ee6fe2a848876bc9f524c5a500b85b -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py314h969be7f_0_cpu.conda#97c21b0d5952f4e0f80bb790df1a5c88 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-24.0.0-py314h969be7f_0_cpu.conda#b066370d80ec7fca3c1d4028dc09164f https://conda.anaconda.org/rapidsai/linux-64/rmm-26.04.00-cuda12_cp311_abi3_260408_48b36cc6.conda#347f02e4a94831af80076fd6157776ac https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py314hf07bd8e_2.conda#ee95e8bb52e35c3267a53d3ee1347cc4 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py314h3d8d815_0.conda#5045e5051a4d781d41d63e4acc264944 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_9_cpu.conda#9c5282b7aaf2261d3dbe5a61d24d5337 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-24.0.0-h635bf11_0_cpu.conda#dc226b80ae51753ce2bd8193dcc42a88 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.9-py314h1194b4b_0.conda#11a821746ad11e642fcc615c3d66aa44 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_mkl_py314_h624cae8_303.conda#fa04d9a4d7fd7a9bd49deabc4b1a8b4f https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.49.00-cuda12_cp311_abi3_260408_8d47a9ff.conda#4e44176d2cfc7f9941dc3089df22c9dc -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_9_cpu.conda#d5338f154126253750e8ccc539386b92 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-24.0.0-hb4dd7c2_0_cpu.conda#cb5a9557a2ffa1b18b4e05621354c6bd https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.04.00-cuda12_260408_b01e3028.conda#413e57142e096269834e8a95b4905d09 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.9-py314hdafbbf9_0.conda#2046de06d7f4149a29c5d0e2cc26d6dd https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_mkl_h0d04637_303.conda#1050dc8cf80cd0a9e63f361c12ee0e82 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-headers-26.04.00-cuda12_260408_60b19a0f.conda#c3216f4b246d2016b1f1a9d719dc94ad https://conda.anaconda.org/rapidsai/linux-64/libraft-26.04.00-cuda12_260408_b01e3028.conda#04014b08138ccd053a8352d879f1cb1e -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py314hdafbbf9_0.conda#860f29e99f5b5f15b0d6a21166588bab +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-24.0.0-py314hdafbbf9_0.conda#6629041b133a9d65d68c4f2269432378 https://conda.anaconda.org/rapidsai/linux-64/libcuvs-26.04.00-cuda12_260408_60b19a0f.conda#2b9d59fc5a9ee033d42f68ef6cd451aa https://conda.anaconda.org/rapidsai/linux-64/pylibraft-26.04.00-cuda12_cp311_abi3_260408_b01e3028.conda#45e40019a250657411b7b42182c33dfd https://conda.anaconda.org/rapidsai/linux-64/cuvs-26.04.00-cuda12_cp311_abi3_260408_.conda#a1a9e67d1b2f9134c41cb4a4063c7497 From 5e15766f01adbe20bbbfba41a2f0145ce5eece15 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 27 Apr 2026 04:11:15 -0400 Subject: [PATCH 402/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33861) Co-authored-by: Lock file bot <noreply@github.com> --- .../github/pylatest_free_threaded_linux-64_conda.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index 7c45329bf72db..6465ff0631727 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -4,7 +4,7 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#3251796e09870c978e0f69fa05e38fb6 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de @@ -39,8 +39,8 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.con https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 From 2c5567bb7936e7b5c75a8ad527528e64f11756da Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Mon, 27 Apr 2026 12:45:05 +0200 Subject: [PATCH 403/462] FIX use the correct base URL for openml.org API calls (#33868) --- .../upcoming_changes/sklearn.datasets/33868.fix.rst | 5 +++++ sklearn/datasets/_openml.py | 8 ++++---- sklearn/datasets/tests/test_openml.py | 6 +++--- 3 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.datasets/33868.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.datasets/33868.fix.rst b/doc/whats_new/upcoming_changes/sklearn.datasets/33868.fix.rst new file mode 100644 index 0000000000000..0c5f423a0e7e0 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.datasets/33868.fix.rst @@ -0,0 +1,5 @@ +- Fixed :func:`datasets.fetch_openml` to issue OpenML API calls to + ``https://www.openml.org/api/v1/`` instead of + ``https://api.openml.org/api/v1/``, which no longer resolves or redirects + correctly. + By :user:`Olivier Grisel <ogrisel>`. diff --git a/sklearn/datasets/_openml.py b/sklearn/datasets/_openml.py index 7ca17cf1ad0a9..b707797c99859 100644 --- a/sklearn/datasets/_openml.py +++ b/sklearn/datasets/_openml.py @@ -33,10 +33,10 @@ __all__ = ["fetch_openml"] -_SEARCH_NAME = "https://api.openml.org/api/v1/json/data/list/data_name/{}/limit/2" -_DATA_INFO = "https://api.openml.org/api/v1/json/data/{}" -_DATA_FEATURES = "https://api.openml.org/api/v1/json/data/features/{}" -_DATA_QUALITIES = "https://api.openml.org/api/v1/json/data/qualities/{}" +_SEARCH_NAME = "https://www.openml.org/api/v1/json/data/list/data_name/{}/limit/2" +_DATA_INFO = "https://www.openml.org/api/v1/json/data/{}" +_DATA_FEATURES = "https://www.openml.org/api/v1/json/data/features/{}" +_DATA_QUALITIES = "https://www.openml.org/api/v1/json/data/qualities/{}" OpenmlQualitiesType = List[Dict[str, str]] OpenmlFeaturesType = List[Dict[str, str]] diff --git a/sklearn/datasets/tests/test_openml.py b/sklearn/datasets/tests/test_openml.py index eb551814bc6e1..7639558652137 100644 --- a/sklearn/datasets/tests/test_openml.py +++ b/sklearn/datasets/tests/test_openml.py @@ -72,10 +72,10 @@ def _monkey_patch_webbased_functions(context, data_id, gzip_response): # monkey patches the urlopen function. Important note: Do NOT use this # in combination with a regular cache directory, as the files that are # stored as cache should not be mixed up with real openml datasets - url_prefix_data_description = "https://api.openml.org/api/v1/json/data/" - url_prefix_data_features = "https://api.openml.org/api/v1/json/data/features/" + url_prefix_data_description = "https://www.openml.org/api/v1/json/data/" + url_prefix_data_features = "https://www.openml.org/api/v1/json/data/features/" url_prefix_download_data = "https://www.openml.org/data/v1/download" - url_prefix_data_list = "https://api.openml.org/api/v1/json/data/list/" + url_prefix_data_list = "https://www.openml.org/api/v1/json/data/list/" path_suffix = ".gz" read_fn = gzip.open From 172bf7a3fda10af5ebb15c8550d1cf245de2603a Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Mon, 27 Apr 2026 18:14:39 +0200 Subject: [PATCH 404/462] CI Update deprecated `auto-activate-base` in `setup-miniconda` action (#33866) --- .github/workflows/unit-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 0af5c5ee92676..948065cddbc16 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -248,7 +248,7 @@ jobs: if: ${{ startsWith(env.DISTRIB, 'conda') }} with: miniforge-version: latest - auto-activate-base: true + auto-activate: true activate-environment: "" - name: Build scikit-learn @@ -378,7 +378,7 @@ jobs: if: ${{ startsWith(env.DISTRIB, 'conda') }} with: miniforge-version: latest - auto-activate-base: true + auto-activate: true activate-environment: "" # Enable global random seed randomization to discover seed-sensitive tests From b85702918af7e0711e07e52c4737b4ece447550e Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Mon, 27 Apr 2026 18:40:49 +0200 Subject: [PATCH 405/462] ENH add array API support for _newton_cg (#33765) --- sklearn/utils/optimize.py | 130 +++++++++++++++++++++------ sklearn/utils/tests/test_optimize.py | 41 ++++++++- 2 files changed, 140 insertions(+), 31 deletions(-) diff --git a/sklearn/utils/optimize.py b/sklearn/utils/optimize.py index 6eee5d4616bd5..2eb5d8d81dcc5 100644 --- a/sklearn/utils/optimize.py +++ b/sklearn/utils/optimize.py @@ -17,19 +17,79 @@ import warnings -import numpy as np import scipy -from scipy.optimize._linesearch import line_search_wolfe1, line_search_wolfe2 +from scipy.optimize._linesearch import ( + line_search_wolfe2, + scalar_search_wolfe1, +) from sklearn.exceptions import ConvergenceWarning +from sklearn.utils._array_api import get_namespace_and_device, size class _LineSearchError(RuntimeError): pass +# Copied from scipy +# https://github.com/scipy/scipy/blob/7a7fbca0b9baa1b709e4a5e0afaf9f94bd34941c/scipy/optimize/_linesearch.py#L37 +# Modified for array API compliance: np.dot(a, b) -> a @ b +# TODO: use the `line_search_wolfe1` from `scipy` when it is array API compliant. +# Reference: https://github.com/scipy/scipy/pull/25022 +def _line_search_wolfe1( + f, + fprime, + xk, + pk, + gfk=None, + old_fval=None, + old_old_fval=None, + args=(), + c1=1e-4, + c2=0.9, + amax=50, + amin=1e-8, + xtol=1e-14, +): + """ + Same as `scalar_search_wolfe1` but do a line search to direction `pk` + """ + if gfk is None: + gfk = fprime(xk, *args) + + gval = [gfk] + gc = [0] + fc = [0] + + def phi(s): + fc[0] += 1 + return f(xk + s * pk, *args) + + def derphi(s): + gval[0] = fprime(xk + s * pk, *args) + gc[0] += 1 + return gval[0] @ pk + + derphi0 = gfk @ pk + + stp, fval, old_fval = scalar_search_wolfe1( + phi, + derphi, + old_fval, + old_old_fval, + derphi0, + c1=c1, + c2=c2, + amax=amax, + amin=amin, + xtol=xtol, + ) + + return stp, fc[0], gc[0], fval, old_fval, gval[0] + + def _line_search_wolfe12( - f, fprime, xk, pk, gfk, old_fval, old_old_fval, verbose=0, **kwargs + f, fprime, xk, pk, gfk, old_fval, old_old_fval, xp, device, verbose=0, **kwargs ): """ Same as line_search_wolfe1, but fall back to line_search_wolfe2 if @@ -43,13 +103,13 @@ def _line_search_wolfe12( """ is_verbose = verbose >= 2 - eps = 16 * np.finfo(np.asarray(old_fval).dtype).eps + eps = 16 * xp.finfo(xk.dtype).eps if is_verbose: print(" Line Search") print(f" eps=16 * finfo.eps={eps}") print(" try line search wolfe1") - ret = line_search_wolfe1(f, fprime, xk, pk, gfk, old_fval, old_old_fval, **kwargs) + ret = _line_search_wolfe1(f, fprime, xk, pk, gfk, old_fval, old_old_fval, **kwargs) if is_verbose: _not_ = "not " if ret[0] is None else "" @@ -61,13 +121,13 @@ def _line_search_wolfe12( # Deal with relative loss differences around machine precision. args = kwargs.get("args", tuple()) fval = f(xk + pk, *args) - tiny_loss = np.abs(old_fval * eps) + tiny_loss = xp.abs(old_fval * eps) loss_improvement = fval - old_fval - check = np.abs(loss_improvement) <= tiny_loss + check = xp.abs(loss_improvement) <= tiny_loss if is_verbose: print( " check loss |improvement| <= eps * |loss_old|:" - f" {np.abs(loss_improvement)} <= {tiny_loss} {check}" + f" {xp.abs(loss_improvement)} <= {tiny_loss} {check}" ) if check: # 2.1 Check sum of absolute gradients as alternative condition. @@ -110,7 +170,7 @@ def _line_search_wolfe12( return ret -def _cg(fhess_p, fgrad, maxiter, tol, verbose=0): +def _cg(fhess_p, fgrad, maxiter, tol, xp, device, verbose=0): """ Solve iteratively the linear system 'fhess_p . xsupi = fgrad' with a conjugate gradient descent. @@ -135,28 +195,28 @@ def _cg(fhess_p, fgrad, maxiter, tol, verbose=0): xsupi : ndarray of shape (n_features,) or (n_features + 1,) Estimated solution. """ - eps = 16 * np.finfo(np.float64).eps - xsupi = np.zeros(len(fgrad), dtype=fgrad.dtype) - ri = np.copy(fgrad) # residual = fgrad - fhess_p @ xsupi + eps = 16 * xp.finfo(fgrad.dtype).eps + xsupi = xp.zeros(size(fgrad), dtype=fgrad.dtype, device=device) + ri = xp.asarray(fgrad, copy=True) # residual = fgrad - fhess_p @ xsupi psupi = -ri i = 0 - dri0 = np.dot(ri, ri) + dri0 = ri @ ri # We also keep track of |p_i|^2. psupi_norm2 = dri0 is_verbose = verbose >= 2 while i <= maxiter: - if np.sum(np.abs(ri)) <= tol: + if (norm1_re := xp.sum(xp.abs(ri))) <= tol: if is_verbose: print( f" Inner CG solver iteration {i} stopped with\n" - f" sum(|residuals|) <= tol: {np.sum(np.abs(ri))} <= {tol}" + f" sum(|residuals|) <= tol: {norm1_re} <= {tol}" ) break Ap = fhess_p(psupi) # check curvature - curv = np.dot(psupi, Ap) + curv = psupi @ Ap if 0 <= curv <= eps * psupi_norm2: # See https://arxiv.org/abs/1803.02924, Algo 1 Capped Conjugate Gradient. if is_verbose: @@ -184,17 +244,17 @@ def _cg(fhess_p, fgrad, maxiter, tol, verbose=0): alphai = dri0 / curv xsupi += alphai * psupi ri += alphai * Ap - dri1 = np.dot(ri, ri) + dri1 = ri @ ri betai = dri1 / dri0 psupi = -ri + betai * psupi # We use |p_i|^2 = |r_i|^2 + beta_i^2 |p_{i-1}|^2 psupi_norm2 = dri1 + betai**2 * psupi_norm2 i = i + 1 - dri0 = dri1 # update np.dot(ri,ri) for next time. + dri0 = dri1 # update ri @ri for next time. if is_verbose and i > maxiter: print( f" Inner CG solver stopped reaching maxiter={i - 1} with " - f"sum(|residuals|) = {np.sum(np.abs(ri))}" + f"sum(|residuals|) = {xp.sum(xp.abs(ri))}" ) return xsupi @@ -229,7 +289,7 @@ def _newton_cg( Should return the function value and the gradient. This is used by the linesearch functions. - x0 : array of float + x0 : array-like of float Initial guess. args : tuple, default=() @@ -254,11 +314,15 @@ def _newton_cg( Returns ------- - xk : ndarray of float + xk : array-like of float Estimated minimum. """ - x0 = np.asarray(x0).flatten() - xk = np.copy(x0) + xp, _, device = get_namespace_and_device(x0) + x0 = xp.asarray(x0, device=device) + if x0.ndim != 1: + msg = f"x0 must be 1-dimensional; got {x0.ndim=}" + raise ValueError(msg) + xk = xp.asarray(x0, copy=True) # np.copy(x0) k = 0 if line_search: @@ -275,8 +339,8 @@ def _newton_cg( # del2 f(xk) p = - fgrad f(xk) starting from 0. fgrad, fhess_p = grad_hess(xk, *args) - absgrad = np.abs(fgrad) - max_absgrad = np.max(absgrad) + absgrad = xp.abs(fgrad) + max_absgrad = xp.max(absgrad) check = max_absgrad <= tol if is_verbose: print(f"Newton-CG iter = {k}") @@ -285,13 +349,21 @@ def _newton_cg( if check: break - maggrad = np.sum(absgrad) - eta = min([0.5, np.sqrt(maggrad)]) + maggrad = xp.sum(absgrad) + eta = min([0.5, xp.sqrt(maggrad)]) termcond = eta * maggrad # Inner loop: solve the Newton update by conjugate gradient, to # avoid inverting the Hessian - xsupi = _cg(fhess_p, fgrad, maxiter=maxinner, tol=termcond, verbose=verbose) + xsupi = _cg( + fhess_p, + fgrad, + maxiter=maxinner, + tol=termcond, + xp=xp, + device=device, + verbose=verbose, + ) alphak = 1.0 @@ -305,6 +377,8 @@ def _newton_cg( fgrad, old_fval, old_old_fval, + xp=xp, + device=device, verbose=verbose, args=args, ) diff --git a/sklearn/utils/tests/test_optimize.py b/sklearn/utils/tests/test_optimize.py index f99f3a9131808..87ce6ec751e09 100644 --- a/sklearn/utils/tests/test_optimize.py +++ b/sklearn/utils/tests/test_optimize.py @@ -4,9 +4,11 @@ import pytest from scipy.optimize import fmin_ncg +from sklearn import config_context from sklearn.exceptions import ConvergenceWarning +from sklearn.utils._array_api import move_to, yield_namespace_device_dtype_combinations from sklearn.utils._bunch import Bunch -from sklearn.utils._testing import assert_allclose +from sklearn.utils._testing import _array_api_for_tests, assert_allclose from sklearn.utils.optimize import _check_optimize_result, _newton_cg @@ -40,6 +42,39 @@ def grad_hess(x): ) +@pytest.mark.parametrize( + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), +) +def test_newton_cg_array_api_compliance(array_namespace, device_name, dtype_name): + """Test that newton_cg works with Array API input.""" + xp, device = _array_api_for_tests(array_namespace, device_name) + A = xp.asarray(np.array([[3, -1], [-1, 1]]).astype(dtype_name), device=device) + y = xp.asarray(np.arange(2).astype(dtype_name), device=device) + x0 = xp.asarray(np.ones(2).astype(dtype_name), device=device) + + def func(x): + return 0.5 * (y - A @ x) @ (y - A @ x) + + def grad(x): + return A.T @ (A @ x - y) + + def hess(x, p): + return A.T @ (A @ p) + + def grad_hess(x): + return grad(x), lambda p: hess(x, p) + + with config_context(array_api_dispatch=True): + res = _newton_cg(grad_hess, func, grad, x0, tol=1e-10) + + assert_allclose( + move_to(res[0], xp=np, device="cpu"), + [1 / 2, 3 / 2], + atol=1e-10, + ) + + @pytest.mark.parametrize("verbose", [0, 1, 2]) def test_newton_cg_verbosity(capsys, verbose): """Test the std output of verbose newton_cg solver.""" @@ -85,7 +120,7 @@ def test_newton_cg_verbosity(capsys, verbose): b = np.array([1.0, 2.0]) # Note that scipy.optimize._linesearch LineSearchWarning inherits from # RuntimeWarning, but we do not want to import from non public APIs. - with pytest.warns(RuntimeWarning): + with pytest.warns((RuntimeWarning, UserWarning)): _newton_cg( grad_hess=lambda x: (A @ x - b, lambda z: A @ z), func=lambda x: 0.5 * x @ A @ x - b @ x, @@ -128,7 +163,7 @@ def test_newton_cg_verbosity(capsys, verbose): # curvature", but that is very hard to trigger. A = np.eye(2) b = np.array([-2.0, 1]) - with pytest.warns(RuntimeWarning): + with pytest.warns((RuntimeWarning, UserWarning)): _newton_cg( # Note the wrong sign in the hessian product. grad_hess=lambda x: (A @ x - b, lambda z: -A @ z), From b032031a8390b8b0369bd4e3715a88b18c900287 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 27 Apr 2026 12:42:49 -0400 Subject: [PATCH 406/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33862) Co-authored-by: Lock file bot <noreply@github.com> Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> --- .../github/pylatest_pip_scipy_dev_linux-64_conda.lock | 10 +++++----- sklearn/utils/tests/test_validation.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index b9b5abee1cdc2..0960c209b5802 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -4,7 +4,7 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de @@ -31,18 +31,18 @@ https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 -# pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa +# pip certifi @ https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl#sha256=3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a # pip charset-normalizer @ https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e # pip coverage @ https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec -# pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea +# pip idna @ https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl#sha256=892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # pip imagesize @ https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl#sha256=5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip markupsafe @ https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 -# pip meson @ https://files.pythonhosted.org/packages/08/84/1ae2022a3562ac011c80c090e387a07e189d077b01fe58a266759b8fc2ff/meson-1.11.0-py3-none-any.whl#sha256=9774eb62bbf2cb8043aa3feb771c09b510d112c0c382221e29aea7453ecce753 +# pip meson @ https://files.pythonhosted.org/packages/5e/cd/f3a881ff5e601d6bbeff63b38ee2362e1167c47d9cde03eddf8d71a4ffb0/meson-1.11.1-py3-none-any.whl#sha256=9b3a023657e393dbc5335b95c561337d49b7a458f5541e47ec44f2cc566e0d80 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa -# pip packaging @ https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl#sha256=5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f +# pip packaging @ https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl#sha256=5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e # pip platformdirs @ https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl#sha256=e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl#sha256=81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 42ba52407d151..a847489eb2db4 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -2062,9 +2062,9 @@ def test_get_feature_names_numpy(): "names, dtypes", [ (["a", 1], "['int', 'str']"), - (["pizza", ["a", "b"]], "['list', 'str']"), + (["pizza", ("a", "b")], "['str', 'tuple']"), ], - ids=["int-str", "list-str"], + ids=["str-int", "str-tuple"], ) def test_get_feature_names_invalid_dtypes(names, dtypes): """Get feature names errors when the feature names have mixed dtypes""" From fa63c604ae9701eb14e0d9fe023a089f4a244a41 Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Tue, 28 Apr 2026 17:40:54 +1000 Subject: [PATCH 407/462] Update to/from to y_pred/other in array API metric test (#33878) --- sklearn/metrics/tests/test_common.py | 32 +++++++++++++++------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 3caf897099b0e..4b37dea49cf32 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -2535,7 +2535,7 @@ def _check_output(out_np, out_xp, xp_to, y2_xp): @pytest.mark.parametrize( - "from_ns_and_device, to_ns_and_device", + "other_ns_and_device, y_pred_ns_and_device", [ pytest.param(*args[:2], id=args[2]) for args in yield_mixed_namespace_input_permutations() @@ -2543,7 +2543,7 @@ def _check_output(out_np, out_xp, xp_to, y2_xp): ) @pytest.mark.parametrize("metric_name", sorted(METRICS_SUPPORTING_MIXED_NAMESPACE)) def test_mixed_array_api_namespace_input_compliance( - metric_name, from_ns_and_device, to_ns_and_device + metric_name, other_ns_and_device, y_pred_ns_and_device ): """Check `y_true` and `sample_weight` follows `y_pred` for mixed namespace inputs. @@ -2551,15 +2551,15 @@ def test_mixed_array_api_namespace_input_compliance( If the output is a float, checks that both all-numpy and mixed-type inputs return a float. If output is an array, checks it is of the same namespace and device as `y_pred` - (`to_ns_and_device`). + (`y_pred_ns_and_device`). If the output is a tuple, checks that each element, whether float or array, is correct, as detailed above. """ - xp_to, device_to = _array_api_for_tests( - to_ns_and_device.xp, device_name=to_ns_and_device.device + xp_y_pred, device_y_pred = _array_api_for_tests( + y_pred_ns_and_device.xp, device_name=y_pred_ns_and_device.device ) - xp_from, device_from = _array_api_for_tests( - from_ns_and_device.xp, device_name=from_ns_and_device.device + xp_other, device_other = _array_api_for_tests( + other_ns_and_device.xp, device_name=other_ns_and_device.device ) metric = ALL_METRICS[metric_name] @@ -2599,28 +2599,30 @@ def _get_dtype(data, xp, device): for data_case in data_cases: y1, y2 = data_all[data_case] - dtype = _get_dtype(y1, xp_from, device_from) - y1_xp = xp_from.asarray(y1, device=device_from, dtype=dtype) + dtype = _get_dtype(y1, xp_other, device_other) + y1_xp = xp_other.asarray(y1, device=device_other, dtype=dtype) metric_kwargs_xp = metric_kwargs_np = {} if metric_name not in METRICS_WITHOUT_SAMPLE_WEIGHT: - # use `from_ns_and_device` for `sample_weight` as well + # use `other_ns_and_device` for `sample_weight` as well sample_weight_np = np.array(sample_weight) metric_kwargs_np = {"sample_weight": sample_weight_np} - sample_weight_xp = xp_from.asarray(sample_weight_np, device=device_from) + sample_weight_xp = xp_other.asarray( + sample_weight_np, device=device_other + ) metric_kwargs_xp = {"sample_weight": sample_weight_xp} - dtype = _get_dtype(y2, xp_to, device_to) - y2_xp = xp_to.asarray(y2, device=device_to, dtype=dtype) + dtype = _get_dtype(y2, xp_y_pred, device_y_pred) + y2_xp = xp_y_pred.asarray(y2, device=device_y_pred, dtype=dtype) metric_xp = metric(y1_xp, y2_xp, **metric_kwargs_xp) metric_np = metric(y1, y2, **metric_kwargs_np) if isinstance(metric_np, Tuple): for out_np, out_xp in zip(metric_np, metric_xp): - _check_output(out_np, out_xp, xp_to, y2_xp) + _check_output(out_np, out_xp, xp_y_pred, y2_xp) else: - _check_output(metric_np, metric_xp, xp_to, y2_xp) + _check_output(metric_np, metric_xp, xp_y_pred, y2_xp) # Check thresholded classification metrics, minus multilabel ranking metrics From 14a4af72a72e728a5bc1200ab7f52c39979cf3d7 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Tue, 28 Apr 2026 11:01:29 +0200 Subject: [PATCH 408/462] DOC Fix colors in Neighborhood Components Analysis example (#33869) --- examples/neighbors/plot_nca_classification.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/examples/neighbors/plot_nca_classification.py b/examples/neighbors/plot_nca_classification.py index b8d69b82fec42..b8f60d2600628 100644 --- a/examples/neighbors/plot_nca_classification.py +++ b/examples/neighbors/plot_nca_classification.py @@ -4,7 +4,7 @@ ============================================================================= An example comparing nearest neighbors classification with and without -Neighborhood Components Analysis. +:ref:`nca`. It will plot the class decision boundaries given by a Nearest Neighbors classifier when using the Euclidean distance on the original features, versus @@ -41,11 +41,6 @@ X, y, stratify=y, test_size=0.7, random_state=42 ) -h = 0.05 # step size in the mesh - -# Create color maps -cmap_light = ListedColormap(["#FFAAAA", "#AAFFAA", "#AAAAFF"]) -cmap_bold = ListedColormap(["#FF0000", "#00FF00", "#0000FF"]) names = ["KNN", "NCA, KNN"] @@ -70,11 +65,10 @@ score = clf.score(X_test, y_test) _, ax = plt.subplots() - DecisionBoundaryDisplay.from_estimator( + disp = DecisionBoundaryDisplay.from_estimator( clf, X, - cmap=cmap_light, - alpha=0.8, + alpha=0.5, ax=ax, response_method="predict", plot_method="pcolormesh", @@ -82,12 +76,13 @@ ) # Plot also the training and testing points - plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold, edgecolor="k", s=20) - plt.title("{} (k = {})".format(name, n_neighbors)) + cmap = ListedColormap(disp.multiclass_colors_) + plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap, edgecolor="k", s=20) + plt.title(f"{name} (k = {n_neighbors})") plt.text( 0.9, 0.1, - "{:.2f}".format(score), + f"{score:.2f}", size=15, ha="center", va="center", From 09cf5ad7be14a348d9a4915e6c61cdeee1733259 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Tue, 28 Apr 2026 11:25:12 +0200 Subject: [PATCH 409/462] DOC Update examples for `DecisionBoundaryDisplay` (#33805) --- sklearn/inspection/_plot/decision_boundary.py | 97 ++++++++++++++----- 1 file changed, 74 insertions(+), 23 deletions(-) diff --git a/sklearn/inspection/_plot/decision_boundary.py b/sklearn/inspection/_plot/decision_boundary.py index 3c0ca7468dd9f..c44ec72ae1a2c 100644 --- a/sklearn/inspection/_plot/decision_boundary.py +++ b/sklearn/inspection/_plot/decision_boundary.py @@ -235,33 +235,45 @@ class DecisionBoundaryDisplay: Examples -------- - >>> import matplotlib as mpl >>> import matplotlib.pyplot as plt + >>> import matplotlib as mpl >>> import numpy as np - >>> from sklearn.datasets import load_iris + >>> from sklearn.linear_model import LogisticRegression >>> from sklearn.inspection import DecisionBoundaryDisplay - >>> from sklearn.tree import DecisionTreeClassifier - >>> iris = load_iris() - >>> feature_1, feature_2 = np.meshgrid( - ... np.linspace(iris.data[:, 0].min(), iris.data[:, 0].max()), - ... np.linspace(iris.data[:, 1].min(), iris.data[:, 1].max()) - ... ) - >>> grid = np.vstack([feature_1.ravel(), feature_2.ravel()]).T - >>> tree = DecisionTreeClassifier().fit(iris.data[:, :2], iris.target) - >>> y_pred = np.reshape(tree.predict(grid), feature_1.shape) - >>> display = DecisionBoundaryDisplay( - ... xx0=feature_1, xx1=feature_2, n_classes=len(tree.classes_), response=y_pred + >>> data = np.array([[0, 0], [1, 1], [2, 1], [2, 2], [3, 2], [3, 3]]) + >>> target = np.arange(data.shape[0]) + >>> clf = LogisticRegression().fit(data, target) + >>> plot_methods = ["contourf", "contour", "pcolormesh"] + >>> response_methods = ["predict_proba", "decision_function", "predict"] + >>> _, axes = plt.subplots( + ... nrows=3, + ... ncols=3, + ... figsize=(12, 12), + ... constrained_layout=True ... ) - >>> display.plot() - <...> - >>> display.ax_.scatter( - ... iris.data[:, 0], - ... iris.data[:, 1], - ... c=iris.target, - ... cmap=mpl.colors.ListedColormap(display.multiclass_colors_), - ... edgecolor="black" - ... ) - <...> + >>> for plot_method_idx, plot_method in enumerate(plot_methods): + ... for response_method_idx, response_method in enumerate(response_methods): + ... ax = axes[plot_method_idx, response_method_idx] + ... display = DecisionBoundaryDisplay.from_estimator( + ... clf, + ... data, + ... grid_resolution=300, + ... response_method=response_method, + ... plot_method=plot_method, + ... ax=ax, + ... alpha=0.5, + ... ) + ... cmap = mpl.colors.ListedColormap(display.multiclass_colors_) + ... ax.scatter( + ... data[:, 0], + ... data[:, 1], + ... c=target.astype(int), + ... edgecolors="black", + ... cmap=cmap, + ... ) + ... ax.set_title( + ... f"plot_method={plot_method}\\nresponse_method={response_method}" + ... ) >>> plt.show() """ @@ -318,6 +330,45 @@ def plot(self, plot_method="contourf", ax=None, xlabel=None, ylabel=None, **kwar ------- display: :class:`~sklearn.inspection.DecisionBoundaryDisplay` Object that stores computed values. + + See Also + -------- + DecisionBoundaryDisplay.from_estimator : Plot decision boundary given an + estimator. + + Examples + -------- + >>> import matplotlib as mpl + >>> import matplotlib.pyplot as plt + >>> import numpy as np + >>> from sklearn.datasets import load_iris + >>> from sklearn.inspection import DecisionBoundaryDisplay + >>> from sklearn.tree import DecisionTreeClassifier + >>> iris = load_iris() + >>> feature_1, feature_2 = np.meshgrid( + ... np.linspace(iris.data[:, 0].min(), iris.data[:, 0].max()), + ... np.linspace(iris.data[:, 1].min(), iris.data[:, 1].max()) + ... ) + >>> grid = np.vstack([feature_1.ravel(), feature_2.ravel()]).T + >>> tree = DecisionTreeClassifier().fit(iris.data[:, :2], iris.target) + >>> y_pred = np.reshape(tree.predict(grid), feature_1.shape) + >>> display = DecisionBoundaryDisplay( + ... xx0=feature_1, + ... xx1=feature_2, + ... n_classes=len(tree.classes_), + ... response=y_pred + ... ) + >>> display.plot() + <...> + >>> display.ax_.scatter( + ... iris.data[:, 0], + ... iris.data[:, 1], + ... c=iris.target, + ... cmap=mpl.colors.ListedColormap(display.multiclass_colors_), + ... edgecolor="black" + ... ) + <...> + >>> plt.show() """ check_matplotlib_support("DecisionBoundaryDisplay.plot") import matplotlib as mpl From 340032f593611708ad24f115eb5982deb2059a2a Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Tue, 28 Apr 2026 19:26:19 +1000 Subject: [PATCH 410/462] DOC Update parameter docstring to array-like in ranking metrics (#33881) --- sklearn/metrics/_ranking.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index 7183a58634a95..d032412801e35 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -331,11 +331,11 @@ def det_curve( Parameters ---------- - y_true : ndarray of shape (n_samples,) + y_true : array-like of shape (n_samples,) True binary labels. If labels are not either {-1, 1} or {0, 1}, then pos_label should be explicitly given. - y_score : ndarray of shape of (n_samples,) + y_score : array-like of shape of (n_samples,) Target scores, can either be probability estimates of the positive class or non-thresholded decision values (as returned by :term:`decision_function` on some classifiers). @@ -942,10 +942,10 @@ def confusion_matrix_at_thresholds( Parameters ---------- - y_true : ndarray of shape (n_samples,) + y_true : array-like of shape (n_samples,) True targets of binary classification. - y_score : ndarray of shape (n_samples,) + y_score : array-like of shape (n_samples,) Estimated probabilities or output of a decision function. pos_label : int, float, bool or str, default=None From 9ce4875b220cc72cf055f7ad021ef2100355c349 Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Tue, 28 Apr 2026 19:26:48 +1000 Subject: [PATCH 411/462] DOC Remove dtype specification in clustering metric docstrings (#33880) --- sklearn/metrics/cluster/_supervised.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sklearn/metrics/cluster/_supervised.py b/sklearn/metrics/cluster/_supervised.py index e815f81de5ac6..7a064f0ffaa2a 100644 --- a/sklearn/metrics/cluster/_supervised.py +++ b/sklearn/metrics/cluster/_supervised.py @@ -209,10 +209,10 @@ def pair_confusion_matrix(labels_true, labels_pred): Parameters ---------- - labels_true : array-like of shape (n_samples,), dtype=integral + labels_true : array-like of shape (n_samples,) Ground truth class labels to be used as a reference. - labels_pred : array-like of shape (n_samples,), dtype=integral + labels_pred : array-like of shape (n_samples,) Cluster labels to evaluate. Returns @@ -295,10 +295,10 @@ def rand_score(labels_true, labels_pred): Parameters ---------- - labels_true : array-like of shape (n_samples,), dtype=integral + labels_true : array-like of shape (n_samples,) Ground truth class labels to be used as a reference. - labels_pred : array-like of shape (n_samples,), dtype=integral + labels_pred : array-like of shape (n_samples,) Cluster labels to evaluate. Returns @@ -384,10 +384,10 @@ def adjusted_rand_score(labels_true, labels_pred): Parameters ---------- - labels_true : array-like of shape (n_samples,), dtype=int + labels_true : array-like of shape (n_samples,) Ground truth class labels to be used as a reference. - labels_pred : array-like of shape (n_samples,), dtype=int + labels_pred : array-like of shape (n_samples,) Cluster labels to evaluate. Returns @@ -855,11 +855,11 @@ def mutual_info_score(labels_true, labels_pred, *, contingency=None): Parameters ---------- - labels_true : array-like of shape (n_samples,), dtype=integral + labels_true : array-like of shape (n_samples,) A clustering of the data into disjoint subsets, called :math:`U` in the above formula. - labels_pred : array-like of shape (n_samples,), dtype=integral + labels_pred : array-like of shape (n_samples,) A clustering of the data into disjoint subsets, called :math:`V` in the above formula. @@ -1217,10 +1217,10 @@ def fowlkes_mallows_score(labels_true, labels_pred): Parameters ---------- - labels_true : array-like of shape (n_samples,), dtype=int + labels_true : array-like of shape (n_samples,) A clustering of the data into disjoint subsets. - labels_pred : array-like of shape (n_samples,), dtype=int + labels_pred : array-like of shape (n_samples,) A clustering of the data into disjoint subsets. Returns @@ -1273,7 +1273,7 @@ def _entropy(labels): Parameters ---------- - labels : array-like of shape (n_samples,), dtype=int + labels : array-like of shape (n_samples,) The labels. Returns @@ -1311,7 +1311,7 @@ def entropy(labels): Parameters ---------- - labels : array-like of shape (n_samples,), dtype=int + labels : array-like of shape (n_samples,) The labels. Returns From edbf20be15d89210c75ef059a0f7bb470cda195b Mon Sep 17 00:00:00 2001 From: Sophia Houhamdi <151393783+shouhamdi@users.noreply.github.com> Date: Tue, 28 Apr 2026 17:13:15 +0200 Subject: [PATCH 412/462] DOC: Note alpha_per_target incompatibility with cv in RidgeCV (#33819) --- sklearn/linear_model/_ridge.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sklearn/linear_model/_ridge.py b/sklearn/linear_model/_ridge.py index 77bb47f0e82ce..d50beba5f8fc7 100644 --- a/sklearn/linear_model/_ridge.py +++ b/sklearn/linear_model/_ridge.py @@ -2752,6 +2752,8 @@ class RidgeCV(MultiOutputMixin, RegressorMixin, _BaseRidgeCV): settings: multiple prediction targets). When set to `True`, after fitting, the `alpha_` attribute will contain a value for each target. When set to `False`, a single alpha is used for all targets. + This flag is only compatible with ``cv=None`` (i.e. using + Leave-One-Out Cross-Validation). .. versionadded:: 0.24 From f1cc4e79929384a8ab53984452bf683ac3315bfa Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Wed, 29 Apr 2026 16:56:40 +0200 Subject: [PATCH 413/462] Register `dpnp` as a new array API namespace to test against (#32460) Co-authored-by: Tim Head <betatim@gmail.com> --- sklearn/metrics/pairwise.py | 2 +- sklearn/utils/_array_api.py | 41 +++++++++++++++++++++++++++++-------- sklearn/utils/_testing.py | 11 ++++++++++ 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/sklearn/metrics/pairwise.py b/sklearn/metrics/pairwise.py index e4d98a9f8616a..959519483eb8c 100644 --- a/sklearn/metrics/pairwise.py +++ b/sklearn/metrics/pairwise.py @@ -2043,7 +2043,7 @@ def _get_slice(array, index): else: # Calculate all cells - out = xp.empty((X.shape[0], Y.shape[0]), dtype=dtype_float) + out = xp.empty((X.shape[0], Y.shape[0]), dtype=dtype_float, device=device) iterator = itertools.product(range(X.shape[0]), range(Y.shape[0])) for i, j in iterator: x = _get_slice(X, i) diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 1431e0dba68de..5675a1cdb4c4e 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -60,6 +60,7 @@ def yield_namespaces(include_numpy_namespaces=True): "array_api_strict", "cupy", "torch", + "dpnp", ]: if not include_numpy_namespaces and array_namespace in _NUMPY_NAMESPACE_NAMES: continue @@ -101,6 +102,13 @@ def yield_namespace_device_dtype_combinations(include_numpy_namespaces=True): yield array_namespace, device_name, dtype yield array_namespace, "mps", "float32" + elif array_namespace == "dpnp": # pragma: nocover + # XXX: add "accelerator" device type? + for device_name, dtype in itertools.product( + ("cpu", "gpu"), ("float64", "float32") + ): + yield array_namespace, device_name, dtype + elif array_namespace == "array_api_strict": # Always yield strings for consistent parametrization; _array_api_for_tests # creates Device objects when needed. @@ -548,6 +556,12 @@ def move_to(*arrays, xp, device): Tuple of arrays with the same namespace and device as reference. Single array returned if only one `arrays` input. """ + if isinstance(device, str) and device == "xpu": # pragma: nocover + # XXX: Workaround for PyTorch XPU bug for `from_dlpack` calls with + # device strings that do not include any device number suffix. + # https://github.com/pytorch/pytorch/issues/181140 + device += ":0" + sparse_mask = [sp.issparse(array) for array in arrays] none_mask = [array is None for array in arrays] if any(sparse_mask) and not _is_numpy_namespace(xp): @@ -739,14 +753,23 @@ def _is_xp_namespace(xp, name): def _max_precision_float_dtype(xp, device): - """Return the float dtype with the highest precision supported by the device.""" - # TODO: Update to use `__array_namespace__info__()` from array-api v2023.12 - # when/if that becomes more widespread. - if _is_xp_namespace(xp, "torch") and str(device).startswith( - "mps" - ): # pragma: no cover - return xp.float32 - return xp.float64 + """Return the float dtype with the highest precision supported by the device. + + Note that scikit-learn only considers float32 and float64 as suitable + floating point dtypes. + """ + if _is_numpy_namespace(xp): + # Special case NumPy for backward compat with older versions that do + # not implement __array_namespace_info__. + return xp.float64 + + floating_dtypes = xp.__array_namespace_info__().dtypes( + kind="real floating", device=device + ) + if "float64" in floating_dtypes: + return xp.float64 + + return xp.float32 def _find_matching_floating_dtype(*arrays, xp): @@ -1000,6 +1023,8 @@ def _convert_to_numpy(array, xp): return array.get() elif _is_xp_namespace(xp, "array_api_strict"): return numpy.asarray(xp.asarray(array, device=xp.Device("CPU_DEVICE"))) + elif _is_xp_namespace(xp, "dpnp"): # pragma: nocover + return array.asnumpy() return numpy.asarray(array) diff --git a/sklearn/utils/_testing.py b/sklearn/utils/_testing.py index dcd4fbdb9825a..66b04723c1673 100644 --- a/sklearn/utils/_testing.py +++ b/sklearn/utils/_testing.py @@ -1345,6 +1345,17 @@ def _array_api_for_tests(array_namespace, device_name=None): and not xp.backends.cuda.is_built() ): raise SkipTest("PyTorch test requires cuda, which is not available") + elif array_namespace == "dpnp": # pragma: nocover + dpctl = pytest.importorskip("dpctl") + if device_name is None: + available_devices = dpctl.get_devices() + if not available_devices: + raise SkipTest("Skipping dpnp test because no SYCL devices found") + else: + device = available_devices[0] + elif not dpctl.get_devices(device_type=device_name): + raise SkipTest(f"Skipping dpnp test because no {device_name} device found") + elif array_namespace == "torch" and device_name == "mps": if os.getenv("PYTORCH_ENABLE_MPS_FALLBACK") != "1": # For now we need PYTORCH_ENABLE_MPS_FALLBACK=1 for all estimators to work From e7b663d0ff112f1ae17698830ef1e948ada99ef8 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Thu, 30 Apr 2026 15:15:21 +0500 Subject: [PATCH 414/462] Fix spurious dtype warnings in `pairwise_distances` with Array API inputs (#33873) Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ogrisel <89061+ogrisel@users.noreply.github.com> Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> --- .../upcoming_changes/array-api/33873.fix.rst | 4 ++++ sklearn/metrics/tests/test_pairwise.py | 18 ++++++++++++++++++ sklearn/utils/extmath.py | 4 ++-- 3 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/array-api/33873.fix.rst diff --git a/doc/whats_new/upcoming_changes/array-api/33873.fix.rst b/doc/whats_new/upcoming_changes/array-api/33873.fix.rst new file mode 100644 index 0000000000000..be187769fafa5 --- /dev/null +++ b/doc/whats_new/upcoming_changes/array-api/33873.fix.rst @@ -0,0 +1,4 @@ +- :func:`metrics.pairwise_distances` no longer emits spurious cross-library + dtype comparison warnings when called with Array API inputs under + ``config_context(array_api_dispatch=True)``. + By :user:`Olivier Grisel <ogrisel>`. diff --git a/sklearn/metrics/tests/test_pairwise.py b/sklearn/metrics/tests/test_pairwise.py index 256bee66d22af..d42328b101e6b 100644 --- a/sklearn/metrics/tests/test_pairwise.py +++ b/sklearn/metrics/tests/test_pairwise.py @@ -188,6 +188,24 @@ def test_pairwise_distances_array_api(array_namespace, device_name, dtype_name, assert_allclose(D_xp_np, D_np) +def test_pairwise_distances_array_api_no_warnings(): + # Regression test for https://github.com/scikit-learn/scikit-learn/issues/33829 + # pairwise_distances should not emit cross-library dtype comparison warnings + # when called with Array API inputs under array_api_dispatch=True. + xp, device = _array_api_for_tests("array_api_strict") + + rng = np.random.RandomState(0) + X_np = rng.random_sample((5, 4)) + Y_np = rng.random_sample((3, 4)) + X_xp = xp.asarray(X_np, device=device) + Y_xp = xp.asarray(Y_np, device=device) + + with config_context(array_api_dispatch=True): + with warnings.catch_warnings(): + warnings.simplefilter("error") + pairwise_distances(X_xp, Y_xp, metric="euclidean") + + @pytest.mark.parametrize("coo_container", COO_CONTAINERS) @pytest.mark.parametrize("csc_container", CSC_CONTAINERS) @pytest.mark.parametrize("bsr_container", BSR_CONTAINERS) diff --git a/sklearn/utils/extmath.py b/sklearn/utils/extmath.py index c0569f60d6f0b..3e0979fc6f2da 100644 --- a/sklearn/utils/extmath.py +++ b/sklearn/utils/extmath.py @@ -218,10 +218,10 @@ def safe_sparse_dot(a, b, *, dense_output=False): dense_output and a.ndim == 2 and b.ndim == 2 - and a.dtype in (np.float32, np.float64) - and b.dtype in (np.float32, np.float64) and (sparse.issparse(a) and a.format in ("csc", "csr")) and (sparse.issparse(b) and b.format in ("csc", "csr")) + and a.dtype in (np.float32, np.float64) + and b.dtype in (np.float32, np.float64) ): # Use dedicated fast method for dense_C = sparse_A @ sparse_B return sparse_matmul_to_dense(a, b) From 4fd35ca21add0a9fb2ce0e51c412cdf13f59c147 Mon Sep 17 00:00:00 2001 From: Arthur Lacote <arthur.lcte@gmail.com> Date: Thu, 30 Apr 2026 12:27:49 +0200 Subject: [PATCH 415/462] TST: Array API: Skip float64 tests for any float32-limited device (#33895) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> --- sklearn/_loss/tests/test_link.py | 2 +- sklearn/_loss/tests/test_loss.py | 4 +- sklearn/decomposition/tests/test_pca.py | 4 +- sklearn/linear_model/_glm/tests/test_glm.py | 4 +- sklearn/linear_model/tests/test_logistic.py | 4 +- sklearn/linear_model/tests/test_ridge.py | 4 +- .../metrics/cluster/tests/test_supervised.py | 2 +- sklearn/metrics/tests/test_classification.py | 8 ++-- sklearn/metrics/tests/test_common.py | 4 +- sklearn/metrics/tests/test_pairwise.py | 6 +-- .../mixture/tests/test_gaussian_mixture.py | 2 +- sklearn/model_selection/tests/test_search.py | 2 +- sklearn/model_selection/tests/test_split.py | 2 +- .../model_selection/tests/test_validation.py | 2 +- sklearn/preprocessing/tests/test_data.py | 4 +- sklearn/preprocessing/tests/test_label.py | 6 +-- .../preprocessing/tests/test_polynomial.py | 4 +- sklearn/tests/test_calibration.py | 4 +- sklearn/tests/test_kernel_approximation.py | 2 +- sklearn/tests/test_naive_bayes.py | 2 +- sklearn/tests/test_pipeline.py | 2 +- sklearn/utils/_testing.py | 17 +++++++-- sklearn/utils/estimator_checks.py | 22 ++++++----- sklearn/utils/tests/test_array_api.py | 37 +++++++++++-------- sklearn/utils/tests/test_extmath.py | 6 +-- sklearn/utils/tests/test_indexing.py | 4 +- sklearn/utils/tests/test_multiclass.py | 2 +- sklearn/utils/tests/test_stats.py | 2 +- sklearn/utils/tests/test_validation.py | 8 ++-- 29 files changed, 97 insertions(+), 75 deletions(-) diff --git a/sklearn/_loss/tests/test_link.py b/sklearn/_loss/tests/test_link.py index 08e63ad7b1671..1cff37702e859 100644 --- a/sklearn/_loss/tests/test_link.py +++ b/sklearn/_loss/tests/test_link.py @@ -113,7 +113,7 @@ def test_link_inverse_array_api( else: raw_prediction = rng.uniform(low=-20, high=20, size=(n_samples)) - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) if dtype_name != "float64": raw_prediction *= 0.5 # avoid overflow rtol = 1e-3 if n_classes else 1e-4 diff --git a/sklearn/_loss/tests/test_loss.py b/sklearn/_loss/tests/test_loss.py index a8854195b0018..de4065dcc9a01 100644 --- a/sklearn/_loss/tests/test_loss.py +++ b/sklearn/_loss/tests/test_loss.py @@ -1412,7 +1412,7 @@ def _assert_array_api_result( assert result_xp.dtype == raw_prediction_xp.dtype assert array_api_device(result_xp) == array_api_device(raw_prediction_xp) - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) atol = _atol_for_type(dtype_name) rtol = 1e-6 if dtype_name == "float32" else 1e-11 random_seed = 42 @@ -1485,7 +1485,7 @@ def test_log1pexp(namespace, device_name, dtype_name): mpmath = pytest.importorskip("mpmath") mpmath.mp.prec = 100 # Significantly more precise reference than float64. values_to_test = np.linspace(-40, 40, 300) - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) for value in values_to_test: if dtype_name == "float32": x = xp.asarray(value, dtype=xp.float32, device=device) diff --git a/sklearn/decomposition/tests/test_pca.py b/sklearn/decomposition/tests/test_pca.py index 238c1b15b2ea4..4f1d5ddaf8bfd 100644 --- a/sklearn/decomposition/tests/test_pca.py +++ b/sklearn/decomposition/tests/test_pca.py @@ -938,7 +938,7 @@ def test_variance_correctness(copy): def check_array_api_get_precision( name, estimator, array_namespace, device_name, dtype_name ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) iris_np = iris.data.astype(dtype_name) iris_xp = xp.asarray(iris_np, device=device) @@ -1046,7 +1046,7 @@ def test_pca_mle_array_api_compliance( # Simpler variant of the generic check_array_api_input checker tailored for # the specific case of PCA with mle-trimmed components. - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X, y = make_classification(random_state=42) X = X.astype(dtype_name, copy=False) diff --git a/sklearn/linear_model/_glm/tests/test_glm.py b/sklearn/linear_model/_glm/tests/test_glm.py index f16a1f07f7e95..70bee38626e05 100644 --- a/sklearn/linear_model/_glm/tests/test_glm.py +++ b/sklearn/linear_model/_glm/tests/test_glm.py @@ -1163,7 +1163,7 @@ def test_poisson_regressor_array_api_compliance( device_name, dtype_name, ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X_np, y_np = make_regression( n_samples=107, n_features=20, n_informative=20, noise=0.5, random_state=2 ) @@ -1237,7 +1237,7 @@ def test_poisson_regressor_array_api_warm_start( X = rng.standard_normal((200, 5)).astype(dtype_name) y = np.abs(rng.standard_normal(200)) + 0.1 y = y.astype(dtype_name) - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X_xp = xp.asarray(X, device=device) y_xp = xp.asarray(y, device=device) with config_context(array_api_dispatch=True): diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index 7d8222e8fb3ba..9ca5f6c45f2a4 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -2702,7 +2702,7 @@ def test_logistic_regression_array_api_compliance( device_name, dtype_name, ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X_np = iris.data.astype(dtype_name, copy=True) n_samples, _ = X_np.shape X_xp = xp.asarray(X_np, device=device) @@ -2862,7 +2862,7 @@ def test_logistic_regression_array_api_warm_start( ): """Test that warm_start=True works with array API inputs across multiple fit calls for both binary and multiclass classification.""" - xp, device_ = _array_api_for_tests(array_namespace, device_name) + xp, device_ = _array_api_for_tests(array_namespace, device_name, dtype_name) X_np = iris.data.astype(dtype_name, copy=True) if binary: y_np = (iris.target > 0).astype(dtype_name) diff --git a/sklearn/linear_model/tests/test_ridge.py b/sklearn/linear_model/tests/test_ridge.py index af0ebfd978862..5ef8de3092d8f 100644 --- a/sklearn/linear_model/tests/test_ridge.py +++ b/sklearn/linear_model/tests/test_ridge.py @@ -1410,7 +1410,7 @@ def _test_tolerance(sparse_container): def check_array_api_attributes( name, estimator, array_namespace, device_name, dtype_name, rtol=None ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X_iris_np = X_iris.astype(dtype_name) y_iris_np = y_iris.astype(dtype_name) @@ -1489,7 +1489,7 @@ def test_ridge_array_api_compliance( def test_ridge_classifier_multilabel_array_api( estimator, array_namespace, device_name, dtype_name ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X, y = make_multilabel_classification(random_state=0) X_np = X.astype(dtype_name) y_np = y.astype(dtype_name) diff --git a/sklearn/metrics/cluster/tests/test_supervised.py b/sklearn/metrics/cluster/tests/test_supervised.py index 9bd5009ac4c1b..c62b21535d99c 100644 --- a/sklearn/metrics/cluster/tests/test_supervised.py +++ b/sklearn/metrics/cluster/tests/test_supervised.py @@ -287,7 +287,7 @@ def test_entropy(): yield_namespace_device_dtype_combinations(), ) def test_entropy_array_api(array_namespace, device_name, dtype_name): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) float_labels = xp.asarray(np.asarray([0, 0, 42.0], dtype=dtype_name), device=device) empty_int32_labels = xp.asarray([], dtype=xp.int32, device=device) int_labels = xp.asarray([1, 1, 1, 1], device=device) diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index c40c62411e646..d66043d2ccc6f 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -3711,7 +3711,7 @@ def test_d2_brier_score_warning_on_less_than_two_samples(): def test_confusion_matrix_array_api(array_namespace, device_name, dtype_name): """Test that `confusion_matrix` works for all array types when `labels` are passed such that the inner boolean `need_index_conversion` evaluates to `True`.""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) y_true = xp.asarray([1, 2, 3], device=device) y_pred = xp.asarray([4, 5, 6], device=device) @@ -3744,7 +3744,7 @@ def test_probabilistic_metrics_array_api( and :func:`d2_log_loss_score` work correctly with the array API for binary and multi-class inputs. """ - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) sample_weight = np.array([1, 2, 3, 1]) if use_sample_weight else None # binary case @@ -3816,7 +3816,7 @@ def test_probabilistic_metrics_multilabel_array_api( and :func:`d2_log_loss_score` work correctly with the array API for multi-label inputs. """ - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) sample_weight = np.array([1, 2, 3, 1]) if use_sample_weight else None y_true_np = np.array( [ @@ -3856,7 +3856,7 @@ def test_pos_label_in_brier_score_metrics_array_api( """Check `pos_label` handled correctly when labels not in {-1, 1} or {0, 1}.""" # For 'brier_score' metrics, when `pos_label=None` and labels are not strings, # `pos_label` defaults to the largest label. - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) y_true_pos_1 = xp.asarray(np.array([1, 0, 1, 0]), device=device) # Result should be the same when we use 2's for the label instead of 1's y_true_pos_2 = xp.asarray(np.array([2, 0, 2, 0]), device=device) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 4b37dea49cf32..cf85a43051332 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -2028,7 +2028,7 @@ def test_metrics_pos_label_error_str(metric, y_pred_threshold, dtype_y_str): def check_array_api_metric( metric, array_namespace, device_name, dtype_name, a_np, b_np, **metric_kwargs ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) a_xp = xp.asarray(a_np, device=device) b_xp = xp.asarray(b_np, device=device) @@ -2688,7 +2688,7 @@ def test_array_api_classification_mixed_string_numeric_input( a mix of string and numeric inputs (numeric input should be able to be of any supported namespace/device), with array API dispatch enabled. """ - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) metric = ALL_METRICS[metric_name] # Binary diff --git a/sklearn/metrics/tests/test_pairwise.py b/sklearn/metrics/tests/test_pairwise.py index d42328b101e6b..29eebc207892f 100644 --- a/sklearn/metrics/tests/test_pairwise.py +++ b/sklearn/metrics/tests/test_pairwise.py @@ -157,7 +157,7 @@ def test_pairwise_distances_for_dense_data(global_dtype): @pytest.mark.parametrize("metric", ["cosine", "euclidean", "manhattan"]) def test_pairwise_distances_array_api(array_namespace, device_name, dtype_name, metric): # Test array API support in pairwise_distances. - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) rng = np.random.RandomState(0) # Euclidean distance should be equivalent to calling the function. @@ -422,7 +422,7 @@ def test_pairwise_parallel(func, metric, kwds, dtype): def test_pairwise_parallel_array_api( func, metric, kwds, array_namespace, device_name, dtype_name ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) rng = np.random.RandomState(0) X_np = np.array(5 * rng.random_sample((5, 4)), dtype=dtype_name) Y_np = np.array(5 * rng.random_sample((3, 4)), dtype=dtype_name) @@ -506,7 +506,7 @@ def test_pairwise_kernels(metric, csr_container): ) def test_pairwise_kernels_array_api(metric, array_namespace, device_name, dtype_name): # Test array API support in pairwise_kernels. - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) rng = np.random.RandomState(0) X_np = 10 * rng.random_sample((5, 4)) diff --git a/sklearn/mixture/tests/test_gaussian_mixture.py b/sklearn/mixture/tests/test_gaussian_mixture.py index f0da500478917..e6dac3f96e37c 100644 --- a/sklearn/mixture/tests/test_gaussian_mixture.py +++ b/sklearn/mixture/tests/test_gaussian_mixture.py @@ -1500,7 +1500,7 @@ def test_gaussian_mixture_array_api_compliance( use_gmm_array_constructor_arguments, ): """Test that array api works in GaussianMixture.fit().""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) rng = np.random.RandomState(0) rand_data = RandomData(rng) diff --git a/sklearn/model_selection/tests/test_search.py b/sklearn/model_selection/tests/test_search.py index 256cb5b9e057f..451c3596e2c46 100644 --- a/sklearn/model_selection/tests/test_search.py +++ b/sklearn/model_selection/tests/test_search.py @@ -2869,7 +2869,7 @@ def test_cv_results_multi_size_array(): def test_array_api_search_cv_classifier( SearchCV, array_namespace, device_name, dtype_name ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X = np.arange(100).reshape((10, 10)) X_np = X.astype(dtype_name) diff --git a/sklearn/model_selection/tests/test_split.py b/sklearn/model_selection/tests/test_split.py index c75c15361fbfc..afaf979019f1c 100644 --- a/sklearn/model_selection/tests/test_split.py +++ b/sklearn/model_selection/tests/test_split.py @@ -1356,7 +1356,7 @@ def test_train_test_split_default_test_size(train_size, exp_train, exp_test): def test_array_api_train_test_split( shuffle, stratify, array_namespace, device_name, dtype_name ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X = np.arange(100).reshape((10, 10)) y = np.arange(10) diff --git a/sklearn/model_selection/tests/test_validation.py b/sklearn/model_selection/tests/test_validation.py index 26a82d510365b..bd3cf604b0cdd 100644 --- a/sklearn/model_selection/tests/test_validation.py +++ b/sklearn/model_selection/tests/test_validation.py @@ -2721,7 +2721,7 @@ def test_cross_val_predict_array_api_compliance( """Test that `cross_val_predict` functions correctly with the array API with both a classifier and a regressor.""" - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) if is_classifier(estimator): X, y = make_classification( n_samples=1000, n_features=5, n_classes=3, n_informative=3, random_state=42 diff --git a/sklearn/preprocessing/tests/test_data.py b/sklearn/preprocessing/tests/test_data.py index de16e4973c1cb..12d45eed7cff7 100644 --- a/sklearn/preprocessing/tests/test_data.py +++ b/sklearn/preprocessing/tests/test_data.py @@ -177,7 +177,7 @@ def test_standard_scaler_sample_weight_array_api( ): # N.B. The sample statistics for Xw w/ sample_weight should match # the statistics of X w/ uniform sample_weight. - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) X = np.array(X).astype(dtype_name, copy=False) y = np.ones(X.shape[0]).astype(dtype_name, copy=False) @@ -2114,7 +2114,7 @@ def test_binarizer(constructor): ) def test_binarizer_array_api_int(array_namespace, device_name, dtype_name): # Checks that Binarizer works with integer elements and float threshold - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) for dtype_name_ in [dtype_name, "int32", "int64"]: X_np = np.reshape(np.asarray([0, 1, 2, 3, 4], dtype=dtype_name_), (-1, 1)) X_xp = xp.asarray(X_np, device=device) diff --git a/sklearn/preprocessing/tests/test_label.py b/sklearn/preprocessing/tests/test_label.py index 6bb6e3e42d7c1..cf8b2857830ce 100644 --- a/sklearn/preprocessing/tests/test_label.py +++ b/sklearn/preprocessing/tests/test_label.py @@ -248,7 +248,7 @@ def test_label_binarizer_array_api_compliance( """Test that :class:`LabelBinarizer` works correctly with the Array API for binary and multi-class inputs for numerical labels and non-sparse outputs. """ - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) y_np = np.asarray(y) @@ -778,7 +778,7 @@ def test_label_binarize_array_api_compliance( """Test that :func:`label_binarize` works correctly with the Array API for binary and multi-class inputs for numerical labels and non-sparse outputs. """ - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) xp_is_numpy = _is_numpy_namespace(xp) numeric_dtype = np.issubdtype(np.asarray(y).dtype, np.integer) and np.issubdtype( np.asarray(classes).dtype, np.integer @@ -858,7 +858,7 @@ def test_label_encoders_do_not_have_set_output(encoder): def test_label_encoder_array_api_compliance( y, array_namespace, device_name, dtype_name ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) xp_y = xp.asarray(y, device=device) with config_context(array_api_dispatch=True): xp_label = LabelEncoder() diff --git a/sklearn/preprocessing/tests/test_polynomial.py b/sklearn/preprocessing/tests/test_polynomial.py index 5b0de52d8a7ea..f0bba4e2cf109 100644 --- a/sklearn/preprocessing/tests/test_polynomial.py +++ b/sklearn/preprocessing/tests/test_polynomial.py @@ -1349,7 +1349,7 @@ def test_polynomial_features_array_api_compliance( dtype_name, ): """Test array API compliance for PolynomialFeatures on 2 features up to degree 3.""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X, _ = two_features_degree3 X_np = X.astype(dtype_name) X_xp = xp.asarray(X_np, device=device) @@ -1378,7 +1378,7 @@ def test_polynomial_features_array_api_raises_on_order_F( ): """Test that PolynomialFeatures with order='F' raises ValueError on array API namespaces other than numpy.""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X = np.arange(6).reshape((3, 2)).astype(dtype_name) X_xp = xp.asarray(X, device=device) msg = "PolynomialFeatures does not support order='F' for non-numpy arrays" diff --git a/sklearn/tests/test_calibration.py b/sklearn/tests/test_calibration.py index f64d026b48ebb..6ae1a28408eda 100644 --- a/sklearn/tests/test_calibration.py +++ b/sklearn/tests/test_calibration.py @@ -1231,7 +1231,7 @@ def test_temperature_scaling_array_api_compliance( """Check that `CalibratedClassifierCV` with temperature scaling is compatible with the array API""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X, y = make_classification( n_samples=1000, n_features=10, @@ -1307,7 +1307,7 @@ def test_temperature_scaling_array_api_with_str_y_estimator_not_prefit( # the array API when `y` is an ndarray of strings and we fit # `LinearDiscriminantAnalysis` beforehand. In this regard # `LinearDiscriminantAnalysis` will also need modifications. - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X, y = make_classification( n_samples=500, n_features=10, diff --git a/sklearn/tests/test_kernel_approximation.py b/sklearn/tests/test_kernel_approximation.py index d37314a31bee1..79ffa7079e302 100644 --- a/sklearn/tests/test_kernel_approximation.py +++ b/sklearn/tests/test_kernel_approximation.py @@ -360,7 +360,7 @@ def test_nystroem_approximation(): def test_nystroem_approximation_array_api( array_namespace, device_name, dtype_name, kernel, n_components ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) rnd = np.random.RandomState(0) n_samples = 10 # Ensure full-rank linear kernel to limit the impact of device-specific diff --git a/sklearn/tests/test_naive_bayes.py b/sklearn/tests/test_naive_bayes.py index 83c7913d907d9..3f310d911c8d6 100644 --- a/sklearn/tests/test_naive_bayes.py +++ b/sklearn/tests/test_naive_bayes.py @@ -1003,7 +1003,7 @@ def test_gnb_array_api_compliance( use_str_y, use_sample_weight, array_namespace, device_name, dtype_name ): """Tests that :class:`GaussianNB` works correctly with array API inputs.""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) X_np = X.astype(dtype_name) X_xp = xp.asarray(X_np, device=device) if use_str_y: diff --git a/sklearn/tests/test_pipeline.py b/sklearn/tests/test_pipeline.py index 6d7c3b4c23fa1..37f1416369d47 100644 --- a/sklearn/tests/test_pipeline.py +++ b/sklearn/tests/test_pipeline.py @@ -1966,7 +1966,7 @@ def test_feature_union_1d_output(): ) def test_feature_union_array_api_compliance(array_namespace, device_name, dtype_name): """Test that FeatureUnion with Array API-compatible transformers works.""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) rnd = np.random.RandomState(0) n_samples, n_features = 20, 10 X_np = rnd.uniform(size=(n_samples, n_features)).astype(dtype_name) diff --git a/sklearn/utils/_testing.py b/sklearn/utils/_testing.py index 66b04723c1673..79d92be534a81 100644 --- a/sklearn/utils/_testing.py +++ b/sklearn/utils/_testing.py @@ -45,7 +45,10 @@ TargetTags, TransformerTags, ) -from sklearn.utils._array_api import _check_array_api_dispatch +from sklearn.utils._array_api import ( + _check_array_api_dispatch, + _max_precision_float_dtype, +) from sklearn.utils.fixes import ( _IS_32BIT, VisibleDeprecationWarning, @@ -1302,7 +1305,7 @@ def __sklearn_tags__(self): ) -def _array_api_for_tests(array_namespace, device_name=None): +def _array_api_for_tests(array_namespace, device_name=None, dtype_name=None): """Return (xp, device) for array API testing. Parameters @@ -1395,7 +1398,15 @@ def _array_api_for_tests(array_namespace, device_name=None): # object. For all other libraries we return a string or `None`. # This works because strings are accepted as arguments to # xp.asarray(..., device=) in those libraries. - return xp, device_name if device is None else device + device = device_name if device is None else device + + if ( + dtype_name == "float64" and _max_precision_float_dtype(xp, device) != xp.float64 + ): # pragma: nocover + skip_msg = f"{array_namespace} does not support float64 on device {device}" + raise SkipTest(skip_msg) + + return xp, device def _get_warnings_filters_info_list(): diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index b3cc04c111d86..1c18fc628ce20 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -1093,7 +1093,9 @@ def _check_array_api_core( expect_only_array_outputs=True, ): """Helper to check estimator attributes and method outputs.""" - xp_X, device_X = _array_api_for_tests(X_ns_and_device.xp, X_ns_and_device.device) + xp_X, device_X = _array_api_for_tests( + X_ns_and_device.xp, X_ns_and_device.device, dtype_name + ) xp_other, device_other = _array_api_for_tests( other_ns_and_device.xp, other_ns_and_device.device ) @@ -1163,13 +1165,15 @@ def _check_array_api_core( ) else: assert attribute.shape == est_xp_param_np.shape - if X_ns_and_device.device == "mps" and np.issubdtype( - est_xp_param_np.dtype, np.floating - ): - # for mps devices the maximum supported floating dtype is float32 - assert est_xp_param_np.dtype == np.float32 - else: - assert est_xp_param_np.dtype == attribute.dtype + expected_dtype = attribute.dtype + if np.issubdtype(attribute.dtype, np.floating): + max_float_dtype = _max_precision_float_dtype( + xp_X, device=X_ns_and_device.device + ) + # for some devices the maximum supported floating dtype is float32 + if max_float_dtype == xp_X.float32: + expected_dtype = np.float32 + assert est_xp_param_np.dtype == expected_dtype # Check estimator methods, if supported, give the same results methods = ( @@ -1445,7 +1449,7 @@ def check_array_api_same_namespace( input arrays are from the same namespace and device as the fitted attributes. """ - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, "float64") X, y = make_classification(n_samples=30, n_features=10, random_state=42) X = X.astype("float64", copy=False) diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index 2cafe7cea175d..480b35896a3ef 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -242,7 +242,7 @@ def test_asarray_with_order(array_api): def test_average( array_namespace, device_name, dtype_name, weights, axis, normalize, expected ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) array_in = numpy.asarray([[1, 2, 3], [4, 5, 6]], dtype=dtype_name) array_in = xp.asarray(array_in, device=device) if weights is not None: @@ -266,7 +266,7 @@ def test_average( yield_namespace_device_dtype_combinations(include_numpy_namespaces=False), ) def test_average_raises_with_wrong_dtype(array_namespace, device_name, dtype_name): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) array_in = numpy.asarray([2, 0], dtype=dtype_name) + 1j * numpy.asarray( [4, 3], dtype=dtype_name @@ -318,7 +318,7 @@ def test_average_raises_with_wrong_dtype(array_namespace, device_name, dtype_nam def test_average_raises_with_invalid_parameters( array_namespace, device_name, dtype_name, axis, weights, error, error_msg ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) array_in = numpy.asarray([[1, 2, 3], [4, 5, 6]], dtype=dtype_name) array_in = xp.asarray(array_in, device=device) @@ -449,7 +449,7 @@ def test_nan_reductions(library, X, reduction, expected): yield_namespace_device_dtype_combinations(), ) def test_ravel(namespace, device_name, dtype_name): - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) array = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] array_xp = xp.asarray(array, device=device) @@ -614,7 +614,7 @@ def test_check_fitted_attribute(): yield_namespace_device_dtype_combinations(), ) def test_indexing_dtype(namespace, device_name, dtype_name): - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) if _IS_32BIT: assert indexing_dtype(xp) == xp.int32 @@ -628,7 +628,14 @@ def test_indexing_dtype(namespace, device_name, dtype_name): ) def test_max_precision_float_dtype(namespace, device_name, dtype_name): xp, device = _array_api_for_tests(namespace, device_name) - expected_dtype = xp.float32 if device_name == "mps" else xp.float64 + try: + xp.asarray([0.0], dtype=xp.float64, device=device) + expected_dtype = xp.float64 + except Exception: + # Some devices, such as MPS devices, PyTorch XPU devices and some Intel + # GPUs with dpnp, do not support float64. + expected_dtype = xp.float32 + assert _max_precision_float_dtype(xp, device) == expected_dtype @@ -649,7 +656,7 @@ def test_isin( element_size, int_dtype, ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) r = element_size // 2 element = 2 * numpy.arange(element_size).reshape((r, 2)).astype(int_dtype) test_elements = numpy.array(numpy.arange(14), dtype=int_dtype) @@ -720,7 +727,7 @@ def test_count_nonzero( ): from sklearn.utils.sparsefuncs import count_nonzero as sparse_count_nonzero - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) array = numpy.array([[0, 3, 0], [2, -1, 0], [0, 0, 0], [9, 8, 7], [4, 0, 5]]) if sample_weight_type == "int": sample_weight = numpy.asarray([1, 2, 2, 3, 1]) @@ -808,7 +815,7 @@ def test_fill_and_add_to_diagonal(c_contiguity, function): ) def test_fill_diagonal(array, array_namespace, device_name, dtype_name): """Check array API `_fill_diagonal` consistent with `numpy._fill_diagonal`.""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) array_np = numpy.zeros((4, 5), dtype=dtype_name) if array == "transposed": @@ -833,7 +840,7 @@ def test_fill_diagonal(array, array_namespace, device_name, dtype_name): ) def test_add_to_diagonal(array_namespace, device_name, dtype_name): """Check `_add_to_diagonal` consistent between array API xp and numpy namespace.""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) np_xp, _ = _array_api_for_tests("numpy", device_name=None) array_np = numpy.zeros((3, 4), dtype=dtype_name) @@ -874,7 +881,7 @@ def test_median(namespace, device_name, dtype_name, axis): # will test for median computation with and without interpolation to check # that array API namespaces yield consistent results even when the median is # not mathematically uniquely defined. - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) rng = numpy.random.RandomState(0) X_np = rng.uniform(low=0.0, high=1.0, size=(5, 4)).astype(dtype_name) @@ -898,7 +905,7 @@ def test_median(namespace, device_name, dtype_name, axis): ) def test_expit_logit(namespace, device_name, dtype_name): rtol = 1e-6 if "float32" in str(dtype_name) else 1e-12 - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) with config_context(array_api_dispatch=True): x_np = numpy.linspace(-20, 20, 1000).astype(dtype_name) @@ -924,7 +931,7 @@ def test_expit_logit(namespace, device_name, dtype_name): ) @pytest.mark.parametrize("axis", [0, 1, None]) def test_logsumexp_like_scipy_logsumexp(array_namespace, device_name, dtype_name, axis): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) array_np = numpy.asarray( [ [0, 3, 1000], @@ -1006,7 +1013,7 @@ def test_half_multinomial_loss(use_sample_weight, namespace, device_name, dtype_ rng = numpy.random.RandomState(42) y = rng.randint(0, n_classes, n_samples).astype(dtype_name) pred = rng.rand(n_samples, n_classes).astype(dtype_name) - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) y_xp = xp.asarray(y, device=device) pred_xp = xp.asarray(pred, device=device) if use_sample_weight: @@ -1032,7 +1039,7 @@ def test_half_multinomial_loss(use_sample_weight, namespace, device_name, dtype_ yield_namespace_device_dtype_combinations(), ) def test_matching_numpy_dtype(namespace, device_name, dtype_name): - xp, device = _array_api_for_tests(namespace, device_name) + xp, device = _array_api_for_tests(namespace, device_name, dtype_name) X_np = numpy.arange(1000).astype(dtype_name) X_xp = xp.asarray(X_np, device=device) ret_dtype = _matching_numpy_dtype(X_xp, xp=xp) diff --git a/sklearn/utils/tests/test_extmath.py b/sklearn/utils/tests/test_extmath.py index 3e9e27e50c589..228587a66d66e 100644 --- a/sklearn/utils/tests/test_extmath.py +++ b/sklearn/utils/tests/test_extmath.py @@ -708,7 +708,7 @@ def test_incremental_weighted_mean_and_variance_simple(dtype, as_list): def test_incremental_weighted_mean_and_variance_array_api( array_namespace, device_name, dtype_name ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) rng = np.random.RandomState(42) mult = 10 X = rng.rand(1000, 20).astype(dtype_name) * mult @@ -1106,7 +1106,7 @@ def test_approximate_mode(): yield_namespace_device_dtype_combinations(), ) def test_randomized_svd_array_api_compliance(array_namespace, device_name, dtype_name): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) rng = np.random.RandomState(0) X = rng.normal(size=(30, 10)).astype(dtype_name) @@ -1134,7 +1134,7 @@ def test_randomized_svd_array_api_compliance(array_namespace, device_name, dtype def test_randomized_range_finder_array_api_compliance( array_namespace, device_name, dtype_name ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) rng = np.random.RandomState(0) X = rng.normal(size=(30, 10)).astype(dtype_name) diff --git a/sklearn/utils/tests/test_indexing.py b/sklearn/utils/tests/test_indexing.py index 9dbb71d1ff4bc..088b37956a9e9 100644 --- a/sklearn/utils/tests/test_indexing.py +++ b/sklearn/utils/tests/test_indexing.py @@ -116,7 +116,7 @@ def test_determine_key_type_slice_error(): yield_namespace_device_dtype_combinations(), ) def test_determine_key_type_array_api(array_namespace, device_name, dtype_name): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) with sklearn.config_context(array_api_dispatch=True): int_array_key = xp.asarray([1, 2, 3], device=device) @@ -157,7 +157,7 @@ def test_determine_key_type_array_api(array_namespace, device_name, dtype_name): def test_safe_indexing_array_api_support( array_namespace, device_name, dtype_name, indexing_key, axis ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) array_to_index_np = np.arange(16).reshape(4, 4) expected_result = _safe_indexing(array_to_index_np, indexing_key, axis=axis) diff --git a/sklearn/utils/tests/test_multiclass.py b/sklearn/utils/tests/test_multiclass.py index 1c1ae4bab5f3e..98902ef01c546 100644 --- a/sklearn/utils/tests/test_multiclass.py +++ b/sklearn/utils/tests/test_multiclass.py @@ -407,7 +407,7 @@ def test_is_multilabel(): yield_namespace_device_dtype_combinations(), ) def test_is_multilabel_array_api_compliance(array_namespace, device_name, dtype_name): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) for group, group_examples in ARRAY_API_EXAMPLES.items(): dense_exp = group == "multilabel-indicator" diff --git a/sklearn/utils/tests/test_stats.py b/sklearn/utils/tests/test_stats.py index fff0d196a7107..24df6fc1aed72 100644 --- a/sklearn/utils/tests/test_stats.py +++ b/sklearn/utils/tests/test_stats.py @@ -299,7 +299,7 @@ def test_weighted_percentile_array_api_consistency( percentile, ): """Check `_weighted_percentile` gives consistent results with array API.""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) # Skip test for percentile=0 edge case (#20528) on namespace/device where # xp.nextafter is broken. This is the case for torch with MPS device: diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index a847489eb2db4..90edc6deda155 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -1075,7 +1075,7 @@ def test_check_consistent_length(): ) def test_check_consistent_length_array_api(array_namespace, device_name, dtype_name): """Test that check_consistent_length works with different array types.""" - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) with config_context(array_api_dispatch=True): check_consistent_length( @@ -1699,7 +1699,7 @@ def test_check_sample_weight(): yield_namespace_device_dtype_combinations(), ) def test_check_sample_weight_array_api(array_namespace, device_name, dtype_name): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) with config_context(array_api_dispatch=True): # check array order sample_weight = xp.ones(10)[::2] @@ -1725,7 +1725,7 @@ def test_check_pos_label_consistency(y_true): def test_check_pos_label_consistency_array_api( array_namespace, device_name, dtype_name, y_true ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) with config_context(array_api_dispatch=True): arr = xp.asarray(y_true, device=device) assert _check_pos_label_consistency(None, arr) == 1 @@ -1747,7 +1747,7 @@ def test_check_pos_label_consistency_invalid(y_true): def test_check_pos_label_consistency_invalid_array_api( array_namespace, device_name, dtype_name, y_true ): - xp, device = _array_api_for_tests(array_namespace, device_name) + xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) with config_context(array_api_dispatch=True): arr = xp.asarray(y_true, device=device) with pytest.raises(ValueError, match="y_true takes value in"): From fca90c1fc24bea7f68243eb5b958cc2a469d980b Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Fri, 1 May 2026 09:48:51 +0200 Subject: [PATCH 416/462] DOC Fix colors in decision tree example (#33909) --- examples/tree/plot_iris_dtc.py | 37 ++++++++++++++++------------------ 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/examples/tree/plot_iris_dtc.py b/examples/tree/plot_iris_dtc.py index 8b865651572c9..c21871383151b 100644 --- a/examples/tree/plot_iris_dtc.py +++ b/examples/tree/plot_iris_dtc.py @@ -28,17 +28,11 @@ # %% # Display the decision functions of trees trained on all pairs of features. import matplotlib.pyplot as plt -import numpy as np +from matplotlib.colors import ListedColormap from sklearn.inspection import DecisionBoundaryDisplay from sklearn.tree import DecisionTreeClassifier -# Parameters -n_classes = 3 -plot_colors = "ryb" -plot_step = 0.02 - - for pairidx, pair in enumerate([[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]): # We only take the two corresponding features X = iris.data[:, pair] @@ -50,30 +44,33 @@ # Plot the decision boundary ax = plt.subplot(2, 3, pairidx + 1) plt.tight_layout(h_pad=0.5, w_pad=0.5, pad=2.5) - DecisionBoundaryDisplay.from_estimator( + disp = DecisionBoundaryDisplay.from_estimator( clf, X, - cmap=plt.cm.RdYlBu, response_method="predict", ax=ax, xlabel=iris.feature_names[pair[0]], ylabel=iris.feature_names[pair[1]], + alpha=0.5, ) # Plot the training points - for i, color in zip(range(n_classes), plot_colors): - idx = np.asarray(y == i).nonzero() - plt.scatter( - X[idx, 0], - X[idx, 1], - c=color, - label=iris.target_names[i], - edgecolor="black", - s=15, - ) + scatter = disp.ax_.scatter( + X[:, 0], + X[:, 1], + c=y, + cmap=ListedColormap(disp.multiclass_colors_), + edgecolor="black", + s=15, + ) plt.suptitle("Decision surface of decision trees trained on pairs of features") -plt.legend(loc="lower right", borderpad=0, handletextpad=0) +plt.figlegend( + scatter.legend_elements()[0], + iris.target_names, + loc="lower center", + ncols=len(iris.target_names), +) _ = plt.axis("tight") # %% From 0f49acc1a5cf36b3eee129bd73ca5abc9b3b89f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon-Martin=20Schr=C3=B6der?= <martin.schroeder@nerdluecht.de> Date: Fri, 1 May 2026 12:14:48 +0200 Subject: [PATCH 417/462] Fix color conversion to rgb hexstring (#33845) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Maximilian Nöthe <maximilian.noethe@tu-dortmund.de> --- .../upcoming_changes/sklearn.tree/33845.fix.rst | 4 ++++ sklearn/tree/_export.py | 7 ++++++- sklearn/tree/tests/test_export.py | 12 ++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/33845.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/33845.fix.rst b/doc/whats_new/upcoming_changes/sklearn.tree/33845.fix.rst new file mode 100644 index 0000000000000..934a7edf042ec --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.tree/33845.fix.rst @@ -0,0 +1,4 @@ +- Fixed color conversion in tree export so RGB values with zero channels are + correctly converted to two-digit hexadecimal components (for example, + ``(0, 255, 0)`` now yields ``#00ff00``). + By :user:`Simon-Martin Schröder <moi90>`. \ No newline at end of file diff --git a/sklearn/tree/_export.py b/sklearn/tree/_export.py index a971fe151697c..999c775da8f8a 100644 --- a/sklearn/tree/_export.py +++ b/sklearn/tree/_export.py @@ -28,6 +28,11 @@ from sklearn.utils.validation import check_array, check_is_fitted +def _rgb_to_hexstring(rgb): + """Convert 8bit integer rgb color to html hexstring""" + return "#%02x%02x%02x" % tuple(rgb) + + def _color_brew(n): """Generate n colors with equally spaced hues. @@ -261,7 +266,7 @@ def get_color(self, value): # compute the color as alpha against white color = [int(round(alpha * c + (1 - alpha) * 255, 0)) for c in color] # Return html color code in #RRGGBB format - return "#%2x%2x%2x" % tuple(color) + return _rgb_to_hexstring(color) def get_fill_color(self, tree, node_id): # Fetch appropriate color for node diff --git a/sklearn/tree/tests/test_export.py b/sklearn/tree/tests/test_export.py index f3d0a8e2e3817..433e387906333 100644 --- a/sklearn/tree/tests/test_export.py +++ b/sklearn/tree/tests/test_export.py @@ -19,6 +19,7 @@ export_text, plot_tree, ) +from sklearn.tree._export import _rgb_to_hexstring CLF_CRITERIONS = ("gini", "log_loss") REG_CRITERIONS = ("squared_error", "absolute_error", "poisson") @@ -31,6 +32,17 @@ y_degraded = [1, 1, 1, 1, 1, 1] +def test_rgb_to_hexstring(): + """ + Test that _rgb_to_hexstring correctly converts an RGB tuple to a hex color string. + + A previous bug caused incorrect hex color string generation for zero values + in the RGB tuple. + """ + + assert _rgb_to_hexstring((0, 255, 0)) == "#00ff00" + + def test_graphviz_toy(): # Check correctness of export_graphviz clf = DecisionTreeClassifier( From 78d18857e4cfb0ec790a36ae276606725af0bb0c Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Sat, 2 May 2026 03:48:24 +1000 Subject: [PATCH 418/462] FIX Improve checking for string and multilabel inputs for classification metrics (#33086) --- .../sklearn.metrics/33086.fix.rst | 10 +++ .../sklearn.utils/33086.api.rst | 3 + sklearn/metrics/_classification.py | 68 +++++++++---------- sklearn/metrics/tests/test_classification.py | 5 +- sklearn/metrics/tests/test_common.py | 19 ++++-- sklearn/utils/_array_api.py | 11 --- sklearn/utils/multiclass.py | 31 ++++++--- sklearn/utils/tests/test_multiclass.py | 58 +++++++++++++++- 8 files changed, 135 insertions(+), 70 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/33086.fix.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.utils/33086.api.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/33086.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/33086.fix.rst new file mode 100644 index 0000000000000..5126f17c961a3 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.metrics/33086.fix.rst @@ -0,0 +1,10 @@ +- :func:`metrics.accuracy_score`, :func:`metrics.hamming_loss` + :func:`metrics.zero_one_loss`, :func:`metrics.matthews_corrcoef` and + :func:`metrics.confusion_matrix` (when `labels` is not `None`) now + raise an error when `y_true` is string and `y_pred` is numeric, for + all array-like inputs. Previously, lists and numpy arrays not of `object` dtype + did not raise an error for this mixed input case. + The above metrics will also raise an error for :term:`label indicator matrix` inputs + of inconsistent size, except for :func:`metrics.confusion_matrix` which does not + accept label indicator matrix inputs. + By :user:`Lucy Liu <lucyleeow>`. diff --git a/doc/whats_new/upcoming_changes/sklearn.utils/33086.api.rst b/doc/whats_new/upcoming_changes/sklearn.utils/33086.api.rst new file mode 100644 index 0000000000000..24d6a4fd10c3a --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.utils/33086.api.rst @@ -0,0 +1,3 @@ +- :func:`utils.multiclass.unique_labels` now accepts `ys_types` parameter, + which allows avoiding duplicate calls to `type_of_target`. + By :user:`Lucy Liu <lucyleeow>`. diff --git a/sklearn/metrics/_classification.py b/sklearn/metrics/_classification.py index 88ff99adca3a3..83d3a91581b5b 100644 --- a/sklearn/metrics/_classification.py +++ b/sklearn/metrics/_classification.py @@ -38,7 +38,6 @@ _is_xp_namespace, _isin, _max_precision_float_dtype, - _union1d, _xlogy, get_namespace, get_namespace_and_device, @@ -76,9 +75,14 @@ def _check_targets(y_true, y_pred, sample_weight=None): """Check that y_true and y_pred belong to the same classification task. This converts multiclass or binary types to a common shape, and raises a - ValueError for a mix of multilabel and multiclass targets, a mix of - multilabel formats, for the presence of continuous-valued or multioutput - targets, or for targets of different lengths. + ValueError for: + + - targets of different lengths, + - a mix of multilabel and multiclass targets, + - a mix of multilabel target and anything else + (because there are no explicit labels), + - the presence of continuous-valued or multioutput (or 'unknown') targets, + - mix of string and integer labels. Column vectors are squeezed to 1d, while multilabel formats are returned as CSR sparse label indicators. @@ -97,6 +101,10 @@ def _check_targets(y_true, y_pred, sample_weight=None): The type of the true target data, as output by ``utils.multiclass.type_of_target``. + unique_labels : array + An ordered array of unique labels occurring either in `y_true`, `y_pred` or + both. + y_true : array or indicator matrix y_pred : array or indicator matrix @@ -129,7 +137,7 @@ def _check_targets(y_true, y_pred, sample_weight=None): ) ) - # We can't have more than one value on y_type => The set is no more needed + # We can't have more than one value in y_type => The set is no more needed y_type = y_type.pop() # No metrics support "multiclass-multioutput" format @@ -148,25 +156,12 @@ def _check_targets(y_true, y_pred, sample_weight=None): else: raise - xp, _ = get_namespace(y_true, y_pred) - if y_type == "binary": - try: - unique_values = _union1d(y_true, y_pred, xp) - except TypeError as e: - # We expect y_true and y_pred to be of the same data type. - # If `y_true` was provided to the classifier as strings, - # `y_pred` given by the classifier will also be encoded with - # strings. So we raise a meaningful error - raise TypeError( - "Labels in y_true and y_pred should be of the same type. " - f"Got y_true={xp.unique(y_true)} and " - f"y_pred={xp.unique(y_pred)}. Make sure that the " - "predictions provided by the classifier coincides with " - "the true labels." - ) from e - if unique_values.shape[0] > 2: - y_type = "multiclass" + unique_labels_ = unique_labels(y_true, y_pred, ys_types={y_type}) + if y_type == "binary": + if unique_labels_.shape[0] > 2: + y_type = "multiclass" + xp, _ = get_namespace(y_true, y_pred) if y_type.startswith("multilabel"): if _is_numpy_namespace(xp): # XXX: do we really want to sparse-encode multilabel indicators when @@ -177,7 +172,7 @@ def _check_targets(y_true, y_pred, sample_weight=None): y_pred = _align_api_if_sparse(csr_array(y_pred)) y_type = "multilabel-indicator" - return y_type, y_true, y_pred, sample_weight + return y_type, unique_labels_, y_true, y_pred, sample_weight def _one_hot_encoding_multiclass_target(y_true, labels, target_xp, target_device): @@ -407,7 +402,7 @@ def accuracy_score(y_true, y_pred, *, normalize=True, sample_weight=None): y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device) # Compute accuracy for each possible representation y_true, y_pred = attach_unique(y_true, y_pred) - y_type, y_true, y_pred, sample_weight = _check_targets( + y_type, _, y_true, y_pred, sample_weight = _check_targets( y_true, y_pred, sample_weight ) @@ -545,7 +540,7 @@ def confusion_matrix( sample_weight = move_to(sample_weight, xp=np, device="cpu") if len(sample_weight) > 0: - y_type, y_true, y_pred, sample_weight = _check_targets( + y_type, unique_labels, y_true, y_pred, sample_weight = _check_targets( y_true, y_pred, sample_weight ) else: @@ -554,14 +549,14 @@ def confusion_matrix( # In this case we don't pass sample_weight to _check_targets that would # check that sample_weight is not empty and we don't reuse the returned # sample_weight - y_type, y_true, y_pred, _ = _check_targets(y_true, y_pred) + y_type, unique_labels, y_true, y_pred, _ = _check_targets(y_true, y_pred) y_true, y_pred = attach_unique(y_true, y_pred) if y_type not in ("binary", "multiclass"): raise ValueError("%s is not supported" % y_type) if labels is None: - labels = unique_labels(y_true, y_pred) + labels = unique_labels else: labels = move_to(labels, xp=np, device="cpu") n_labels = labels.size @@ -741,16 +736,16 @@ def multilabel_confusion_matrix( [1, 2]]]) """ y_true, y_pred = attach_unique(y_true, y_pred) + xp, _, device_ = get_namespace_and_device(y_pred) y_true, sample_weight = move_to(y_true, sample_weight, xp=xp, device=device_) - y_type, y_true, y_pred, sample_weight = _check_targets( + y_type, present_labels, y_true, y_pred, sample_weight = _check_targets( y_true, y_pred, sample_weight ) if y_type not in ("binary", "multiclass", "multilabel-indicator"): raise ValueError("%s is not supported" % y_type) - present_labels = unique_labels(y_true, y_pred) if labels is None: labels = present_labels n_labels = None @@ -1318,7 +1313,7 @@ def matthews_corrcoef(y_true, y_pred, *, sample_weight=None): -0.33 """ y_true, y_pred = attach_unique(y_true, y_pred) - y_type, y_true, y_pred, sample_weight = _check_targets( + y_type, _, y_true, y_pred, sample_weight = _check_targets( y_true, y_pred, sample_weight ) if y_type not in {"binary", "multiclass"}: @@ -1912,8 +1907,7 @@ def _check_set_wise_labels(y_true, y_pred, average, labels, pos_label): raise ValueError("average has to be one of " + str(average_options)) y_true, y_pred = attach_unique(y_true, y_pred) - y_type, y_true, y_pred, _ = _check_targets(y_true, y_pred) - present_labels = unique_labels(y_true, y_pred) + y_type, present_labels, y_true, y_pred, _ = _check_targets(y_true, y_pred) if average == "binary": if y_type == "binary": if pos_label not in present_labels: @@ -2366,7 +2360,7 @@ class are present in `y_true`): both likelihood ratios are undefined. (1.5, 0.75) """ y_true, y_pred = attach_unique(y_true, y_pred) - y_type, y_true, y_pred, sample_weight = _check_targets( + y_type, _, y_true, y_pred, sample_weight = _check_targets( y_true, y_pred, sample_weight ) if y_type != "binary": @@ -3091,12 +3085,12 @@ class 2 1.00 0.67 0.80 3 """ y_true, y_pred = attach_unique(y_true, y_pred) - y_type, y_true, y_pred, sample_weight = _check_targets( + y_type, unique_labels_, y_true, y_pred, sample_weight = _check_targets( y_true, y_pred, sample_weight ) if labels is None: - labels = unique_labels(y_true, y_pred) + labels = unique_labels_ labels_given = False else: labels = np.asarray(labels) @@ -3286,7 +3280,7 @@ def hamming_loss(y_true, y_pred, *, sample_weight=None): 0.75 """ y_true, y_pred = attach_unique(y_true, y_pred) - y_type, y_true, y_pred, sample_weight = _check_targets( + y_type, _, y_true, y_pred, sample_weight = _check_targets( y_true, y_pred, sample_weight ) diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index d66043d2ccc6f..e13ac345fc66b 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -2507,7 +2507,6 @@ def test__check_targets(): MCN = "continuous-multioutput" # all of length 3 EXAMPLES = [ - (IND, np.array([[0, 1, 1], [1, 0, 0], [0, 0, 1]])), # must not be considered binary (IND, np.array([[0, 1], [1, 0], [1, 1]])), (MC, [2, 3, 1]), @@ -2570,7 +2569,7 @@ def test__check_targets(): _check_targets(y1, y2) else: - merged_type, y1out, y2out, _ = _check_targets(y1, y2) + merged_type, _, y1out, y2out, _ = _check_targets(y1, y2) assert merged_type == expected if merged_type.startswith("multilabel"): assert y1out.format == "csr" @@ -2624,7 +2623,7 @@ def test__check_targets_sparse_inputs(y, target_type): _check_targets(y, y) else: # This should not raise an error - y_type, y_true_out, y_pred_out, _ = _check_targets(y, y) + y_type, _, y_true_out, y_pred_out, _ = _check_targets(y, y) assert y_type == "multilabel-indicator" assert y_true_out.format == "csr" diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index cf85a43051332..34a18c254a09f 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -1971,16 +1971,25 @@ def test_continuous_metric_permutation_invariance(name): assert_almost_equal(score, current_score) +@pytest.mark.parametrize( + "y1", + [ + np.array(["spam"] * 3 + ["eggs"] * 2, dtype=object), # str object + np.array(["spam"] * 3 + ["eggs"] * 2), # fixed width str + np.array(["spam"] * 3 + ["eggs"] * 2), # list + ], +) @pytest.mark.parametrize("metric_name", CLASSIFICATION_METRICS) -def test_metrics_consistent_type_error(metric_name): +def test_metrics_consistent_type_error(y1, metric_name): # check that an understable message is raised when the type between y_true # and y_pred mismatch rng = np.random.RandomState(42) - y1 = np.array(["spam"] * 3 + ["eggs"] * 2, dtype=object) - y2 = rng.randint(0, 2, size=y1.size) + n_samples = 5 + + y2 = rng.randint(0, 2, size=n_samples) - err_msg = "Labels in y_true and y_pred should be of the same type." - with pytest.raises(TypeError, match=err_msg): + err_msg = r"Mix of label input types \(string and number\)" + with pytest.raises(ValueError, match=err_msg): CLASSIFICATION_METRICS[metric_name](y1, y2) diff --git a/sklearn/utils/_array_api.py b/sklearn/utils/_array_api.py index 5675a1cdb4c4e..0d79f84bf6e66 100644 --- a/sklearn/utils/_array_api.py +++ b/sklearn/utils/_array_api.py @@ -269,17 +269,6 @@ def _is_numpy_namespace(xp): return xp.__name__ in _NUMPY_NAMESPACE_NAMES -def _union1d(a, b, xp): - if _is_numpy_namespace(xp): - # avoid circular import - from sklearn.utils._unique import cached_unique - - a_unique, b_unique = cached_unique(a, b, xp=xp) - return xp.asarray(numpy.union1d(a_unique, b_unique)) - assert a.ndim == b.ndim == 1 - return xp.unique_values(xp.concat([xp.unique_values(a), xp.unique_values(b)])) - - def supported_float_dtypes(xp, device=None): """Supported floating point types for the namespace. diff --git a/sklearn/utils/multiclass.py b/sklearn/utils/multiclass.py index 0a5b173d3c9f2..966d8875852b7 100644 --- a/sklearn/utils/multiclass.py +++ b/sklearn/utils/multiclass.py @@ -10,7 +10,7 @@ import numpy as np from scipy.sparse import issparse -from sklearn.utils._array_api import get_namespace +from sklearn.utils._array_api import _is_numpy_namespace, get_namespace from sklearn.utils._unique import attach_unique, cached_unique from sklearn.utils.fixes import VisibleDeprecationWarning from sklearn.utils.validation import _assert_all_finite, _num_samples, check_array @@ -38,13 +38,13 @@ def _unique_indicator(y, xp=None): } -def unique_labels(*ys): +def unique_labels(*ys, ys_types=None): """Extract an ordered array of unique labels. We don't allow: - mix of multilabel and multiclass (single label) targets - - mix of label indicator matrix and anything else, - because there are no explicit labels) + - mix of label indicator matrix and anything else + (because there are no explicit labels) - mix of label indicator matrices of different sizes - mix of string and integer labels @@ -55,6 +55,10 @@ def unique_labels(*ys): *ys : array-likes Label values. + ys_types : set, default=None + Set of target types of `ys` (as determined by `type_of_target`), + with `{"binary", "multiclass"}` being amended to `{"multiclass"}`. + Returns ------- out : ndarray of shape (n_unique_labels,) @@ -74,15 +78,17 @@ def unique_labels(*ys): xp, is_array_api_compliant = get_namespace(*ys) if len(ys) == 0: raise ValueError("No argument has been passed.") - # Check that we don't mix label format - ys_types = set(type_of_target(x) for x in ys) - if ys_types == {"binary", "multiclass"}: - ys_types = {"multiclass"} + if ys_types is None: + ys_types = set(type_of_target(x) for x in ys) + if ys_types == {"binary", "multiclass"}: + ys_types = {"multiclass"} + # Check that we don't mix label format if len(ys_types) > 1: raise ValueError("Mix type of y not allowed, got types %s" % ys_types) + # We can't have more than one value in y_type => The set is no more needed label_type = ys_types.pop() # Check consistency for the indicator format @@ -104,8 +110,8 @@ def unique_labels(*ys): if not _unique_labels: raise ValueError("Unknown label type: %s" % repr(ys)) - if is_array_api_compliant: - # array_api does not allow for mixed dtypes + if is_array_api_compliant and not _is_numpy_namespace(xp): + # non-NumPy array API inputs do not allow for mixed dtypes unique_ys = xp.concat([_unique_labels(y, xp=xp) for y in ys]) return xp.unique_values(unique_ys) @@ -114,7 +120,10 @@ def unique_labels(*ys): ) # Check that we don't mix string type with number type if len(set(isinstance(label, str) for label in ys_labels)) > 1: - raise ValueError("Mix of label input types (string and number)") + msg_details = ( + "Got " + " and ".join([f"{xp.unique_values(y)}" for y in ys]) + "." + ) + raise ValueError(f"Mix of label input types (string and number); {msg_details}") return xp.asarray(sorted(ys_labels)) diff --git a/sklearn/utils/tests/test_multiclass.py b/sklearn/utils/tests/test_multiclass.py index 98902ef01c546..09400610aa6b6 100644 --- a/sklearn/utils/tests/test_multiclass.py +++ b/sklearn/utils/tests/test_multiclass.py @@ -9,6 +9,8 @@ from sklearn.model_selection import ShuffleSplit from sklearn.svm import SVC from sklearn.utils._array_api import ( + _atol_for_type, + move_to, yield_namespace_device_dtype_combinations, ) from sklearn.utils._testing import ( @@ -17,6 +19,7 @@ assert_allclose, assert_array_almost_equal, assert_array_equal, + skip_if_array_api_compat_not_configured, ) from sklearn.utils.estimator_checks import _NotAnArray from sklearn.utils.fixes import ( @@ -266,7 +269,7 @@ def _generate_sparse( def test_unique_labels(): # Empty iterable - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="No argument has been passed"): unique_labels() # Multiclass problem @@ -286,13 +289,62 @@ def test_unique_labels(): assert_array_equal(unique_labels((0, 1, 2), (0,), (2, 1)), np.arange(3)) # Border line case with binary indicator matrix - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="Mix type of y not allowed"): unique_labels([4, 0, 2], np.ones((5, 5))) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="Multi-label binary indicator input with"): unique_labels(np.ones((5, 4)), np.ones((5, 5))) assert_array_equal(unique_labels(np.ones((4, 5)), np.ones((5, 5))), np.arange(5)) + # Mixed label input types + with pytest.raises( + ValueError, match=r"Mix of label input types \(string and number\)" + ): + unique_labels([4, 0, 2], ["a", "b", "c"]) + with pytest.raises( + ValueError, match=r"Mix of label input types \(string and number\)" + ): + # Note string array is NOT object dtype, but string 'U' + unique_labels(np.array([4, 0, 2]), np.array(["a", "b", "c"])) + + +@skip_if_array_api_compat_not_configured +def test_unique_labels_mixed_str_numerical_array_api(): + """Test error is raised for mixed string and numerical input and dispatch enabled. + + Mixed string and numerical NumPy input with array API dispatch enabled should raise + the correct error. + """ + y_string = np.array(["a", "b", "a", "a"]) + y_object = np.array(["a", "b", "a", "a"], dtype=object) + y_numerical = np.array([1, 0, 0, 1]) + + with config_context(array_api_dispatch=True): + with pytest.raises(ValueError, match="Mix of label input types"): + unique_labels(y_string, y_numerical) + with pytest.raises(ValueError, match="Mix of label input types"): + unique_labels(y_object, y_numerical) + + +@pytest.mark.parametrize( + "array_namespace, device, dtype_name", + yield_namespace_device_dtype_combinations(), +) +def test_unique_labels_array_api(array_namespace, device, dtype_name): + """Check `unique_labels` compliance for array API.""" + xp, device_ = _array_api_for_tests(array_namespace, device) + y1_np = np.array([1, 2, 3], dtype=dtype_name) + y2_np = np.array([2, 3, 4], dtype=dtype_name) + + y1_xp = xp.asarray(y1_np, device=device_) + y2_xp = xp.asarray(y2_np, device=device_) + + labels_np = unique_labels(y1_np, y2_np) + with config_context(array_api_dispatch=True): + labels_xp = unique_labels(y1_xp, y2_xp) + labels_xp_np = move_to(labels_xp, xp=np, device="cpu") + assert_allclose(labels_np, labels_xp_np, atol=_atol_for_type(dtype_name)) + def test_check_classification_targets_too_many_unique_classes(): """Check that we raise a warning when the number of unique classes is greater than From a3b0eea25ec5593105224d5efbb8fd6dcf31623b Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 4 May 2026 04:21:29 -0400 Subject: [PATCH 419/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33927) Co-authored-by: Lock file bot <noreply@github.com> --- ...da_forge_cuda_array-api_linux-64_conda.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index ecadfdcf2f988..05c2c6aac09ee 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -47,7 +47,7 @@ https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499cd8e2d4358986dbe3b30e8fe1bf6a https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -64,7 +64,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.co https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -110,19 +110,19 @@ https://conda.anaconda.org/conda-forge/linux-64/libudev1-260.1-h6569c3e_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 -https://conda.anaconda.org/conda-forge/linux-64/nccl-2.30.3.1-h4d09622_0.conda#4f76723fe649e2b91d4b913e8c591bb7 +https://conda.anaconda.org/conda-forge/linux-64/nccl-2.30.4.1-h4d09622_0.conda#5f6cad41cf88e7938996445f694d76c6 https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/rapidsai/linux-64/rapids-logger-0.2.3-h98325ef_0.conda#81257f29bfcc1e58f0405d7bc9feb309 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.1-h1cbb8d7_1.conda#9d978822b57bafe72ebd3f8b527bba71 +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.2-hc5a330e_1.conda#3f578c7d2b0bb52469340e4060d48d94 https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda#996583ea9c796e5b915f7d7580b51ea6 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-hc87160b_0.conda#dde6a3e4fe6bb2ecd2a7050dd1e701fb +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-h692f434_1.conda#14260392d0b491c537b5e26e9a506fff https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 @@ -135,7 +135,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.co https://conda.anaconda.org/conda-forge/linux-64/libcurand-dev-10.3.10.19-h676940d_1.conda#fc716aaff5af15b80ccbd28b3e67672c https://conda.anaconda.org/conda-forge/linux-64/libcusparse-12.5.10.65-hecca717_2.conda#890ebfaad48c887d3d82847ec9d6bc79 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h6705ce6_0.conda#42c424ab163c576c7fb5981f7fb379cf https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 @@ -166,7 +166,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.co https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_1.conda#c5b8ea827c65e5811d61aa49cd0bae9a https://conda.anaconda.org/conda-forge/linux-64/libcufile-1.14.1.1-hbc026e6_1.conda#cab1818eada3952ed09c8dcbb7c26af7 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda#c3cc2864f82a944bc90a7beb4d3b0e88 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-11.7.5.82-h676940d_2.conda#bb6e31a0daa64ede76fe8d3fff01c06f https://conda.anaconda.org/conda-forge/linux-64/libcusparse-dev-12.5.10.65-hecca717_2.conda#db94469fbd554c107acc3afd0af5d8ec https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c @@ -189,12 +189,12 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.3-pyhc364b38_0.conda#a6ec14cbc8d512bfd94404e0f8d7338f +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.4-pyhc364b38_0.conda#42d4610b52102122741f9bf68f2866ed https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.29.0-pyhd8ed1ab_0.conda#8fa8358d022a3a9bd101384a808044c6 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.4.0-pyhd8ed1ab_0.conda#2c11aa96ea85ced419de710c1c3a78ff https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-dev-11.7.5.82-h676940d_2.conda#0fe12e558abf507458bcec839e29778d From 3e0f36035d8d588e150e6574f965672deb4c65c6 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 4 May 2026 04:21:56 -0400 Subject: [PATCH 420/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33926) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/github/pylatest_free_threaded_linux-64_conda.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index 6465ff0631727..56effda9f149f 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -12,14 +12,14 @@ https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 From 1267a8e917f0f02992a8a3274baca54507fa17ad Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 4 May 2026 04:22:26 -0400 Subject: [PATCH 421/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33925) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index 0960c209b5802..cfaa37660d85d 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -12,13 +12,13 @@ https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 From 15e9684cd23f6a13f2f5bfa8515bc78c5f8a76eb Mon Sep 17 00:00:00 2001 From: danilo-silva-ufsc <41925985+danilo-silva-ufsc@users.noreply.github.com> Date: Mon, 4 May 2026 07:02:08 -0500 Subject: [PATCH 422/462] FIX BayesianRidge and ARDRegression predict to center X before computing std (#33918) --- .../sklearn.linear_model/33918.fix.rst | 3 +++ sklearn/linear_model/_bayes.py | 2 ++ sklearn/linear_model/tests/test_bayes.py | 15 +++++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33918.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33918.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33918.fix.rst new file mode 100644 index 0000000000000..985b44181980f --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33918.fix.rst @@ -0,0 +1,3 @@ +- :class:`linear_model.BayesianRidge` and :class:`linear_model.ARDRegression` now + center test features during :meth:`predict` to correctly compute predictive variance. + By :user:`Danilo Silva (danilo-silva-ufsc)`. diff --git a/sklearn/linear_model/_bayes.py b/sklearn/linear_model/_bayes.py index 966a8bf1cf39f..7ea22b05f1f5c 100644 --- a/sklearn/linear_model/_bayes.py +++ b/sklearn/linear_model/_bayes.py @@ -397,6 +397,7 @@ def predict(self, X, return_std=False): if not return_std: return y_mean else: + X = X - self.X_offset_ sigmas_squared_data = (np.dot(X, self.sigma_) * X).sum(axis=1) y_std = np.sqrt(sigmas_squared_data + (1.0 / self.alpha_)) return y_mean, y_std @@ -818,6 +819,7 @@ def predict(self, X, return_std=False): return y_mean else: col_index = self.lambda_ < self.threshold_lambda + X = X - self.X_offset_ X = _safe_indexing(X, indices=col_index, axis=1) sigmas_squared_data = (np.dot(X, self.sigma_) * X).sum(axis=1) y_std = np.sqrt(sigmas_squared_data + (1.0 / self.alpha_)) diff --git a/sklearn/linear_model/tests/test_bayes.py b/sklearn/linear_model/tests/test_bayes.py index e44d1ebf46027..abb21decb9484 100644 --- a/sklearn/linear_model/tests/test_bayes.py +++ b/sklearn/linear_model/tests/test_bayes.py @@ -185,6 +185,21 @@ def test_std_bayesian_ridge_ard_with_constant_input(global_random_seed): assert_array_less(y_std, expected_upper_boundary) +@pytest.mark.parametrize("Estimator", [BayesianRidge, ARDRegression]) +def test_std_bayesian_ridge_noncentered(Estimator, global_random_seed): + # Test BayesianRidge and ARDRegression std when data is not centered. + # The std should be smallest at the center of the data, not at the origin. + # Non-regression test for issue #33757 + rng = np.random.RandomState(global_random_seed) + n_samples = 4 + X_train = np.linspace(80, 100, n_samples).reshape(-1, 1) + y_train = X_train.reshape(-1) + 10 * rng.standard_normal(n_samples) + model = Estimator(fit_intercept=True).fit(X_train, y_train) + X = np.array([[0.0], [90.0]]) + _, y_std = model.predict(X, return_std=True) + assert y_std[1] < y_std[0] + + def test_update_of_sigma_in_ard(): # Checks that `sigma_` is updated correctly after the last iteration # of the ARDRegression algorithm. See issue #10128. From 88f8246239b09766905994f30dca810c618fc846 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos Orfanos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 4 May 2026 16:11:19 +0200 Subject: [PATCH 423/462] MNT Fix typos found by typos (#33916) --- asv_benchmarks/benchmarks/config.json | 2 +- doc/developers/contributing.rst | 2 +- doc/modules/classification_threshold.rst | 4 ++-- doc/modules/model_evaluation.rst | 4 ++-- .../calibration/plot_compare_calibration.py | 2 +- examples/ensemble/plot_hgbt_regression.py | 2 +- .../plot_display_object_visualization.py | 2 +- examples/neighbors/plot_classification.py | 2 +- examples/svm/plot_svm_scale_c.py | 6 +++--- sklearn/__init__.py | 2 +- sklearn/_loss/_loss.pyx.tp | 2 +- sklearn/_loss/meson.build | 2 +- sklearn/base.py | 2 +- sklearn/cluster/tests/test_hierarchical.py | 2 +- .../compose/tests/test_column_transformer.py | 6 +++--- sklearn/cross_decomposition/tests/test_pls.py | 2 +- sklearn/datasets/descr/wine_data.rst | 2 +- sklearn/datasets/tests/test_lfw.py | 4 ++-- sklearn/decomposition/tests/test_pca.py | 4 ++-- sklearn/ensemble/_gradient_boosting.pyx | 2 +- .../tests/test_gradient_boosting.py | 2 +- .../tests/test_grower.py | 2 +- .../ensemble/_hist_gradient_boosting/utils.py | 2 +- .../ensemble/tests/test_gradient_boosting.py | 6 +++--- sklearn/ensemble/tests/test_iforest.py | 4 ++-- sklearn/feature_extraction/tests/test_text.py | 2 +- sklearn/gaussian_process/_gpr.py | 2 +- sklearn/gaussian_process/tests/test_gpr.py | 2 +- sklearn/impute/_base.py | 2 +- .../tests/test_boundary_decision_display.py | 2 +- .../tests/test_plot_partial_dependence.py | 2 +- .../tests/test_permutation_importance.py | 6 +++--- sklearn/linear_model/_cd_fast.pyx | 4 ++-- sklearn/linear_model/_glm/tests/test_glm.py | 2 +- sklearn/linear_model/_passive_aggressive.py | 4 ++-- sklearn/linear_model/_ridge.py | 2 +- sklearn/linear_model/_sgd_fast.pyx.tp | 2 +- sklearn/linear_model/_stochastic_gradient.py | 4 ++-- sklearn/linear_model/meson.build | 2 +- sklearn/linear_model/tests/test_base.py | 8 ++++---- .../tests/test_coordinate_descent.py | 2 +- .../linear_model/tests/test_least_angle.py | 4 ++-- sklearn/linear_model/tests/test_logistic.py | 2 +- sklearn/linear_model/tests/test_sgd.py | 2 +- .../_pairwise_distances_reduction/meson.build | 14 ++++++------- .../tests/test_precision_recall_display.py | 2 +- sklearn/metrics/_ranking.py | 2 +- sklearn/metrics/meson.build | 2 +- sklearn/metrics/tests/test_classification.py | 2 +- sklearn/metrics/tests/test_common.py | 10 +++++----- sklearn/metrics/tests/test_pairwise.py | 2 +- sklearn/metrics/tests/test_ranking.py | 2 +- .../_classification_threshold.py | 2 +- sklearn/model_selection/tests/test_split.py | 4 ++-- sklearn/neighbors/_quad_tree.pyx | 2 +- sklearn/neighbors/meson.build | 2 +- .../preprocessing/_function_transformer.py | 2 +- sklearn/preprocessing/_label.py | 2 +- sklearn/preprocessing/tests/test_data.py | 4 ++-- sklearn/preprocessing/tests/test_encoders.py | 2 +- .../tests/test_function_transformer.py | 4 ++-- sklearn/tests/test_calibration.py | 6 +++--- sklearn/tests/test_min_dependencies_readme.py | 20 +++++++++---------- sklearn/tests/test_pipeline.py | 2 +- sklearn/tree/_classes.py | 4 ++-- sklearn/tree/_criterion.pyx | 2 +- sklearn/tree/_tree.pyx | 2 +- sklearn/tree/tests/test_reingold_tilford.py | 2 +- sklearn/tree/tests/test_tree.py | 4 ++-- sklearn/utils/_testing.py | 2 +- sklearn/utils/estimator_checks.py | 4 ++-- sklearn/utils/extmath.py | 2 +- sklearn/utils/meson.build | 2 +- sklearn/utils/tests/test_plotting.py | 2 +- sklearn/utils/validation.py | 4 ++-- 75 files changed, 123 insertions(+), 123 deletions(-) diff --git a/asv_benchmarks/benchmarks/config.json b/asv_benchmarks/benchmarks/config.json index b5a10b930e60b..49f74865546f1 100644 --- a/asv_benchmarks/benchmarks/config.json +++ b/asv_benchmarks/benchmarks/config.json @@ -1,5 +1,5 @@ { - // "regular": Bencharks are run on small to medium datasets. Each benchmark + // "regular": Benchmarks are run on small to medium datasets. Each benchmark // is run multiple times and averaged. // "fast": Benchmarks are run on small to medium datasets. Each benchmark // is run only once. May provide unstable benchmarks. diff --git a/doc/developers/contributing.rst b/doc/developers/contributing.rst index ac4fe5578ab9d..9ee2e9defaf27 100644 --- a/doc/developers/contributing.rst +++ b/doc/developers/contributing.rst @@ -833,7 +833,7 @@ additions in the following areas: using the `.. rubric:: Note` directive. * Add one or two **snippets** of code in "Example" section to show how it can - be used. The code should be runable as is, i.e. it should include all + be used. The code should be runnable as is, i.e. it should include all required imports. Keep this section as brief as possible. diff --git a/doc/modules/classification_threshold.rst b/doc/modules/classification_threshold.rst index fcc746e65eb7c..48f4d04c08f28 100644 --- a/doc/modules/classification_threshold.rst +++ b/doc/modules/classification_threshold.rst @@ -1,6 +1,6 @@ .. currentmodule:: sklearn.model_selection -.. _threshold_tunning: +.. _threshold_tuning: ================================================== Tuning the decision threshold for class prediction @@ -28,7 +28,7 @@ cut-off rules: a positive class is predicted when the conditional probability :math:`P(y|X)` is greater than 0.5 (obtained with :term:`predict_proba`) or if the decision score is greater than 0 (obtained with :term:`decision_function`). -Here, we show an example that illustrates the relatonship between conditional +Here, we show an example that illustrates the relationship between conditional probability estimates :math:`P(y|X)` and class labels:: >>> from sklearn.datasets import make_classification diff --git a/doc/modules/model_evaluation.rst b/doc/modules/model_evaluation.rst index 0ce03d8ce24bf..fa7829018248c 100644 --- a/doc/modules/model_evaluation.rst +++ b/doc/modules/model_evaluation.rst @@ -63,7 +63,7 @@ The most common decisions are done on binary classification tasks, where the res probability of rain a decision is made on how to act (whether to take mitigating measures like an umbrella or not). For classifiers, this is what :term:`predict` returns. -See also :ref:`threshold_tunning`. +See also :ref:`threshold_tuning`. There are many scoring functions which measure different aspects of such a decision, most of them are covered with or derived from the :func:`metrics.confusion_matrix`. @@ -3140,7 +3140,7 @@ expected value should be null and that their variance should be constant (homoschedasticity). If this is not the case, and in particular if the residuals plot show some -banana-shaped structure, this is a hint that the model is likely mis-specified +banana-shaped structure, this is a hint that the model is likely misspecified and that non-linear feature engineering or switching to a non-linear regression model might be useful. diff --git a/examples/calibration/plot_compare_calibration.py b/examples/calibration/plot_compare_calibration.py index b5a2794fc9e7e..bdccb5ef9eed3 100644 --- a/examples/calibration/plot_compare_calibration.py +++ b/examples/calibration/plot_compare_calibration.py @@ -186,7 +186,7 @@ def predict_proba(self, X): # sufficient to guarantee a well-calibrated model by itself: even with a very # large training set, logistic regression could still be poorly calibrated, if # it was too strongly regularized or if the choice and preprocessing of input -# features made this model mis-specified (e.g. if the true decision boundary of +# features made this model misspecified (e.g. if the true decision boundary of # the dataset is a highly non-linear function of the input features). # # In this example the training set was intentionally kept very small. In this diff --git a/examples/ensemble/plot_hgbt_regression.py b/examples/ensemble/plot_hgbt_regression.py index 777f6a2fa897e..e23c739e395cf 100644 --- a/examples/ensemble/plot_hgbt_regression.py +++ b/examples/ensemble/plot_hgbt_regression.py @@ -309,7 +309,7 @@ def generate_missing_values(X, missing_fraction): _ = ax.legend(loc="lower right") # %% -# We observe a tendence to over-estimate the energy transfer. This could be be +# We observe a tendency to over-estimate the energy transfer. This could be be # quantitatively confirmed by computing empirical coverage numbers as done in # the :ref:`calibration of confidence intervals section <calibration-section>`. # Keep in mind that those predicted percentiles are just estimations from a diff --git a/examples/miscellaneous/plot_display_object_visualization.py b/examples/miscellaneous/plot_display_object_visualization.py index ec54d909d1c37..4d1c03b83528a 100644 --- a/examples/miscellaneous/plot_display_object_visualization.py +++ b/examples/miscellaneous/plot_display_object_visualization.py @@ -79,7 +79,7 @@ # Combining the display objects into a single plot # ################################################ # The display objects store the computed values that were passed as arguments. -# This allows for the visualizations to be easliy combined using matplotlib's +# This allows for the visualizations to be easily combined using matplotlib's # API. In the following example, we place the displays next to each other in a # row. diff --git a/examples/neighbors/plot_classification.py b/examples/neighbors/plot_classification.py index 676fed4d32bc9..82ee3f481fa99 100644 --- a/examples/neighbors/plot_classification.py +++ b/examples/neighbors/plot_classification.py @@ -94,7 +94,7 @@ # ---------- # # We observe that the parameter `weights` has an impact on the decision boundary. When -# `weights="unifom"` all nearest neighbors will have the same impact on the decision. +# `weights="uniform"` all nearest neighbors will have the same impact on the decision. # Whereas when `weights="distance"` the weight given to each neighbor is proportional # to the inverse of the distance from that neighbor to the query point. # diff --git a/examples/svm/plot_svm_scale_c.py b/examples/svm/plot_svm_scale_c.py index 09cde25983ba1..30aa913a95511 100644 --- a/examples/svm/plot_svm_scale_c.py +++ b/examples/svm/plot_svm_scale_c.py @@ -28,7 +28,7 @@ between the main problem and the smaller problems within the folds of the cross validation. -Since the loss function dependens on the amount of samples, the latter +Since the loss function depends on the amount of samples, the latter influences the selected value of `C`. The question that arises is "How do we optimally adjust C to account for the different amount of training samples?" """ @@ -138,7 +138,7 @@ # # Using the default scale results in a somewhat stable optimal value of `C`, # whereas the transition out of the underfitting region depends on the number of -# training samples. The reparametrization leads to even more stable results. +# training samples. The reparameterization leads to even more stable results. # # See e.g. theorem 3 of :arxiv:`On the prediction performance of the Lasso # <1402.1700>` or :arxiv:`Simultaneous analysis of Lasso and Dantzig selector @@ -198,7 +198,7 @@ plt.show() # %% -# For the L2 penalty case, the reparametrization seems to have a smaller impact +# For the L2 penalty case, the reparameterization seems to have a smaller impact # on the stability of the optimal value for the regularization. The transition # out of the overfitting region occurs in a more spread range and the accuracy # does not seem to be degraded up to chance level. diff --git a/sklearn/__init__.py b/sklearn/__init__.py index 12d63dd8b6739..2c14dd82c0acc 100644 --- a/sklearn/__init__.py +++ b/sklearn/__init__.py @@ -49,7 +49,7 @@ # simultaneously. This can happen for instance when calling BLAS inside a # prange. Setting the following environment variable allows multiple OpenMP # libraries to be loaded. It should not degrade performances since we manually -# take care of potential over-subcription performance issues, in sections of +# take care of potential over-subscription performance issues, in sections of # the code where nested OpenMP loops can happen, by dynamically reconfiguring # the inner OpenMP runtime to temporarily disable it while under the scope of # the outer OpenMP parallel section. diff --git a/sklearn/_loss/_loss.pyx.tp b/sklearn/_loss/_loss.pyx.tp index 44d5acd530a7f..0b594f47d9f30 100644 --- a/sklearn/_loss/_loss.pyx.tp +++ b/sklearn/_loss/_loss.pyx.tp @@ -1185,7 +1185,7 @@ cdef class CyHalfMultinomialLoss(): Raw prediction values (in link space). sample_weight : double Sample weight. - gradient_out : array of shape (n_classs,) + gradient_out : array of shape (n_classes,) A location into which the gradient is stored. Returns diff --git a/sklearn/_loss/meson.build b/sklearn/_loss/meson.build index 7add6d48d231d..a5fefd793ca2e 100644 --- a/sklearn/_loss/meson.build +++ b/sklearn/_loss/meson.build @@ -12,7 +12,7 @@ _loss_pyx = custom_target( output: '_loss.pyx', input: '_loss.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: _loss_cython_tree, diff --git a/sklearn/base.py b/sklearn/base.py index 36026b9658ba3..7adf1401b7172 100644 --- a/sklearn/base.py +++ b/sklearn/base.py @@ -1219,7 +1219,7 @@ def __sklearn_tags__(self): class _UnstableArchMixin: - """Mark estimators that are non-determinstic on 32bit or PowerPC""" + """Mark estimators that are non-deterministic on 32bit or PowerPC""" def __sklearn_tags__(self): tags = super().__sklearn_tags__() diff --git a/sklearn/cluster/tests/test_hierarchical.py b/sklearn/cluster/tests/test_hierarchical.py index c3261ab6ee747..66488c6338f07 100644 --- a/sklearn/cluster/tests/test_hierarchical.py +++ b/sklearn/cluster/tests/test_hierarchical.py @@ -880,7 +880,7 @@ def test_precomputed_connectivity_metric_with_2_connected_components(): @pytest.mark.parametrize("Clustering", [AgglomerativeClustering, FeatureAgglomeration]) -def test_agglomeration_ward_contrained_metric(Clustering): +def test_agglomeration_ward_constrained_metric(Clustering): """Check that we raise an error when 'euclidean' or 'l2' are not passed with ward linkage.""" rng = np.random.RandomState(0) diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index 98961a1ece7d4..93f31ed5f963d 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -1698,7 +1698,7 @@ def test_column_transformer_reordered_column_names_remainder( tf.transform(X_array) -def test_feature_name_validation_missing_columns_drop_passthough(): +def test_feature_name_validation_missing_columns_drop_passthrough(): """Test the interaction between {'drop', 'passthrough'} and missing column names.""" pd = pytest.importorskip("pandas") @@ -1738,7 +1738,7 @@ def test_feature_names_in_(): Column transformer deliberately does not check for column name consistency. It only checks that the non-dropped names seen in `fit` are seen in `transform`. This behavior is already tested in - `test_feature_name_validation_missing_columns_drop_passthough`""" + `test_feature_name_validation_missing_columns_drop_passthrough`""" pd = pytest.importorskip("pandas") @@ -2497,7 +2497,7 @@ def test_remainder_set_output(): def test_transform_pd_na(): - """Check behavior when a tranformer's output contains pandas.NA + """Check behavior when a transformer's output contains pandas.NA It should raise an error unless the output config is set to 'pandas'. """ diff --git a/sklearn/cross_decomposition/tests/test_pls.py b/sklearn/cross_decomposition/tests/test_pls.py index f2b91a2712ef5..375a7826cbab0 100644 --- a/sklearn/cross_decomposition/tests/test_pls.py +++ b/sklearn/cross_decomposition/tests/test_pls.py @@ -354,7 +354,7 @@ def test_convergence_fail(): @pytest.mark.parametrize("Est", (PLSSVD, PLSRegression, PLSCanonical)) -def test_attibutes_shapes(Est): +def test_attributes_shapes(Est): # Make sure attributes are of the correct shape depending on n_components d = load_linnerud() X = d.data diff --git a/sklearn/datasets/descr/wine_data.rst b/sklearn/datasets/descr/wine_data.rst index 64efe49900ebf..8d5c3126df21e 100644 --- a/sklearn/datasets/descr/wine_data.rst +++ b/sklearn/datasets/descr/wine_data.rst @@ -63,7 +63,7 @@ wine. Original Owners: Forina, M. et al, PARVUS - -An Extendible Package for Data Exploration, Classification and Correlation. +An Extendable Package of Programs for Data Exploration, Classification and Correlation. Institute of Pharmaceutical and Food Analysis and Technologies, Via Brigata Salerno, 16147 Genoa, Italy. diff --git a/sklearn/datasets/tests/test_lfw.py b/sklearn/datasets/tests/test_lfw.py index cc86fe8637232..7ea741679d11b 100644 --- a/sklearn/datasets/tests/test_lfw.py +++ b/sklearn/datasets/tests/test_lfw.py @@ -105,7 +105,7 @@ def test_load_fake_lfw_people(mock_data_home): data_home=mock_data_home, min_faces_per_person=3, download_if_missing=False ) - # The data is croped around the center as a rectangular bounding box + # The data is cropped around the center as a rectangular bounding box # around the face. Colors are converted to gray levels: assert lfw_people.images.shape == (10, 62, 47) assert lfw_people.data.shape == (10, 2914) @@ -177,7 +177,7 @@ def test_load_fake_lfw_pairs(mock_data_home): data_home=mock_data_home, download_if_missing=False ) - # The data is croped around the center as a rectangular bounding box + # The data is cropped around the center as a rectangular bounding box # around the face. Colors are converted to gray levels: assert lfw_pairs_train.pairs.shape == (10, 2, 62, 47) diff --git a/sklearn/decomposition/tests/test_pca.py b/sklearn/decomposition/tests/test_pca.py index 4f1d5ddaf8bfd..0aec4837cc490 100644 --- a/sklearn/decomposition/tests/test_pca.py +++ b/sklearn/decomposition/tests/test_pca.py @@ -157,7 +157,7 @@ def test_sparse_pca_solver_error(global_random_seed, svd_solver, sparse_containe @pytest.mark.parametrize("sparse_container", CSR_CONTAINERS + CSC_CONTAINERS) -def test_sparse_pca_auto_arpack_singluar_values_consistency( +def test_sparse_pca_auto_arpack_singular_values_consistency( global_random_seed, sparse_container ): """Check that "auto" and "arpack" solvers are equivalent for sparse inputs.""" @@ -877,7 +877,7 @@ def test_mle_simple_case(): assert pca_skl.n_components_ == n_dim - 1 -def test_assess_dimesion_rank_one(): +def test_assess_dimension_rank_one(): # Make sure assess_dimension works properly on a matrix of rank 1 n_samples, n_features = 9, 6 X = np.ones((n_samples, n_features)) # rank 1 matrix diff --git a/sklearn/ensemble/_gradient_boosting.pyx b/sklearn/ensemble/_gradient_boosting.pyx index 6224dee324a57..a9dcac9c7c2e7 100644 --- a/sklearn/ensemble/_gradient_boosting.pyx +++ b/sklearn/ensemble/_gradient_boosting.pyx @@ -19,7 +19,7 @@ from sklearn.tree._utils cimport safe_realloc from numpy import zeros as np_zeros -# constant to mark tree leafs +# constant to mark tree leaves cdef intp_t TREE_LEAF = -1 cdef void _predict_regression_tree_inplace_fast_dense( diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py index cb8cc1971a0d2..a42e15fd2b202 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_gradient_boosting.py @@ -524,7 +524,7 @@ def test_small_trainset(): def test_missing_values_minmax_imputation(): - # Compare the buit-in missing value handling of Histogram GBC with an + # Compare the built-in missing value handling of Histogram GBC with an # a-priori missing value imputation strategy that should yield the same # results in terms of decision function. # diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_grower.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_grower.py index a55cb871e3c72..4bd6a30c9d9d5 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_grower.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_grower.py @@ -146,7 +146,7 @@ def test_grow_tree(n_bins, constant_hessian, stopping_param, shrinkage): assert len(right_right_node.sample_indices) > 0.2 * n_samples assert len(right_right_node.sample_indices) < 0.4 * n_samples - # All the leafs are pure, it is not possible to split any further: + # All the leaves are pure, it is not possible to split any further: assert not grower.splittable_nodes grower._apply_shrinkage() diff --git a/sklearn/ensemble/_hist_gradient_boosting/utils.py b/sklearn/ensemble/_hist_gradient_boosting/utils.py index 3107177cac87a..1e9319b101b49 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/utils.py +++ b/sklearn/ensemble/_hist_gradient_boosting/utils.py @@ -106,7 +106,7 @@ def get_equivalent_estimator(estimator, lib="lightgbm", n_classes=None): catboost_loss_mapping = { "squared_error": "RMSE", # catboost does not support MAE when leaf_estimation_method is Newton - "absolute_error": "LEAST_ASBOLUTE_DEV_NOT_SUPPORTED", + "absolute_error": "LEAST_ABSOLUTE_DEV_NOT_SUPPORTED", "log_loss": "Logloss" if n_classes == 2 else "MultiClass", "gamma": None, "poisson": "Poisson", diff --git a/sklearn/ensemble/tests/test_gradient_boosting.py b/sklearn/ensemble/tests/test_gradient_boosting.py index 51c090f747a90..9be764c5d9ccf 100644 --- a/sklearn/ensemble/tests/test_gradient_boosting.py +++ b/sklearn/ensemble/tests/test_gradient_boosting.py @@ -1036,7 +1036,7 @@ def test_monitor_early_stopping(Cls): def test_complete_classification(): - # Test greedy trees with max_depth + 1 leafs. + # Test greedy trees with max_depth + 1 leaves. from sklearn.tree._tree import TREE_LEAF X, y = datasets.make_hastie_10_2(n_samples=100, random_state=1) @@ -1053,7 +1053,7 @@ def test_complete_classification(): def test_complete_regression(): - # Test greedy trees with max_depth + 1 leafs. + # Test greedy trees with max_depth + 1 leaves. from sklearn.tree._tree import TREE_LEAF k = 4 @@ -1677,7 +1677,7 @@ def test_gb_denominator_zero(global_random_seed): } clf = GradientBoostingClassifier(**params) - # _safe_devide would raise a RuntimeWarning + # _safe_divide would raise a RuntimeWarning with warnings.catch_warnings(): warnings.simplefilter("error") clf.fit(X, y) diff --git a/sklearn/ensemble/tests/test_iforest.py b/sklearn/ensemble/tests/test_iforest.py index d495bef8fc6d7..8abb2d73afc55 100644 --- a/sklearn/ensemble/tests/test_iforest.py +++ b/sklearn/ensemble/tests/test_iforest.py @@ -389,7 +389,7 @@ def test_iforest_predict_parallel(global_random_seed, contamination, n_jobs): ) clf_parallel.fit(X) with parallel_backend("threading", n_jobs=n_jobs): - pred_paralell = clf_parallel.predict(X) + pred_parallel = clf_parallel.predict(X) # assert the same results as non-parallel - assert_array_equal(pred, pred_paralell) + assert_array_equal(pred, pred_parallel) diff --git a/sklearn/feature_extraction/tests/test_text.py b/sklearn/feature_extraction/tests/test_text.py index 1749d1a183012..621268bed383a 100644 --- a/sklearn/feature_extraction/tests/test_text.py +++ b/sklearn/feature_extraction/tests/test_text.py @@ -1628,7 +1628,7 @@ def test_tfidf_transformer_copy(csr_container): @pytest.mark.parametrize("dtype", [np.float32, np.float64]) -def test_tfidf_vectorizer_perserve_dtype_idf(dtype): +def test_tfidf_vectorizer_preserve_dtype_idf(dtype): """Check that `idf_` has the same dtype as the input data. Non-regression test for: diff --git a/sklearn/gaussian_process/_gpr.py b/sklearn/gaussian_process/_gpr.py index cf1917a8d9c13..d0f13187cc8fd 100644 --- a/sklearn/gaussian_process/_gpr.py +++ b/sklearn/gaussian_process/_gpr.py @@ -640,7 +640,7 @@ def log_marginal_likelihood( # it is equivalent to: # for param_idx in range(n_kernel_params): # for output_idx in range(n_output): - # log_likehood_gradient_dims[param_idx, output_idx] = ( + # log_likelihood_gradient_dims[param_idx, output_idx] = ( # inner_term[..., output_idx] @ # K_gradient[..., param_idx] # ) diff --git a/sklearn/gaussian_process/tests/test_gpr.py b/sklearn/gaussian_process/tests/test_gpr.py index 9a2b2474bfaeb..a1f920c0d5bb4 100644 --- a/sklearn/gaussian_process/tests/test_gpr.py +++ b/sklearn/gaussian_process/tests/test_gpr.py @@ -306,7 +306,7 @@ def test_y_normalization(kernel): def test_large_variance_y(): """ - Here we test that, when noramlize_y=True, our GP can produce a + Here we test that, when normalize_y=True, our GP can produce a sensible fit to training data whose variance is significantly larger than unity. This test was made in response to issue #15612. diff --git a/sklearn/impute/_base.py b/sklearn/impute/_base.py index 6d10812abc3fd..ad9fcce8e621c 100644 --- a/sklearn/impute/_base.py +++ b/sklearn/impute/_base.py @@ -580,7 +580,7 @@ def _dense_fit(self, X, strategy, missing_values, fill_value): # Constant elif strategy == "constant": - # for constant strategy, self.statistcs_ is used to store + # for constant strategy, self.statistics_ is used to store # fill_value in each column, or np.nan for columns to drop statistics = np.full(X.shape[1], fill_value, dtype=np.object_) diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index 826eec4332148..309cc7f41e1ac 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -936,7 +936,7 @@ def test_n_classes_attribute(pyplot, estimator, n_blobs, expected_n_classes): assert disp_coi.n_classes == 2 -def test_n_classes_raises_if_not_inferrable(pyplot): +def test_n_classes_raises_if_not_inferable(pyplot): """Check behaviour if `n_classes` can't be inferred. Non-regression test for issue #33194. diff --git a/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py b/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py index 75869079be9cc..855c88e17fe15 100644 --- a/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py +++ b/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py @@ -383,7 +383,7 @@ def test_plot_partial_dependence_passing_numpy_axes( @pytest.mark.parametrize("nrows, ncols", [(2, 2), (3, 1)]) @pytest.mark.parametrize("use_custom_values", [True, False]) -def test_plot_partial_dependence_incorrent_num_axes( +def test_plot_partial_dependence_incorrect_num_axes( pyplot, clf_diabetes, diabetes, diff --git a/sklearn/inspection/tests/test_permutation_importance.py b/sklearn/inspection/tests/test_permutation_importance.py index b51ad7b71f66d..d3015488dd03d 100644 --- a/sklearn/inspection/tests/test_permutation_importance.py +++ b/sklearn/inspection/tests/test_permutation_importance.py @@ -239,7 +239,7 @@ def test_permutation_importance_mixed_types_pandas(): assert np.all(result.importances_mean[-1] > result.importances_mean[:-1]) -def test_permutation_importance_linear_regresssion(): +def test_permutation_importance_linear_regression(): X, y = make_regression(n_samples=500, n_features=10, random_state=0) X = scale(X) @@ -329,7 +329,7 @@ def test_permutation_importance_equivalence_array_dataframe(n_jobs, max_samples) X_df[new_col_idx] = cat_column assert X_df[new_col_idx].dtype == cat_column.dtype - # Stich an arbitrary index to the dataframe: + # Stitch an arbitrary index to the dataframe: X_df.index = np.arange(len(X_df)).astype(str) rf = RandomForestRegressor(n_estimators=5, max_depth=3, random_state=0) @@ -352,7 +352,7 @@ def test_permutation_importance_equivalence_array_dataframe(n_jobs, max_samples) imp_max = importance_array["importances"].max() assert imp_max - imp_min > 0.3 - # Now check that importances computed on dataframe matche the values + # Now check that importances computed on dataframe match the values # of those computed on the array with the same data. importance_dataframe = permutation_importance( rf, diff --git a/sklearn/linear_model/_cd_fast.pyx b/sklearn/linear_model/_cd_fast.pyx index 4a5bb1e62ece7..b5d3ae47a9350 100644 --- a/sklearn/linear_model/_cd_fast.pyx +++ b/sklearn/linear_model/_cd_fast.pyx @@ -737,7 +737,7 @@ def sparse_enet_coordinate_descent( cdef floating normalize_sum cdef unsigned int n_active = n_features cdef uint32_t[::1] active_set - # TODO: use binset insteaf of array of bools + # TODO: use binset instead of array of bools cdef uint8_t[::1] excluded_set cdef int32_t i, i_ind cdef unsigned int j @@ -1153,7 +1153,7 @@ def enet_coordinate_descent_gram( cdef floating dual_norm_XtA cdef unsigned int n_active = n_features cdef uint32_t[::1] active_set - # TODO: use binset insteaf of array of bools + # TODO: use binset instead of array of bools cdef uint8_t[::1] excluded_set cdef unsigned int j cdef unsigned int n_iter = 0 diff --git a/sklearn/linear_model/_glm/tests/test_glm.py b/sklearn/linear_model/_glm/tests/test_glm.py index 70bee38626e05..0c8cdf77650b9 100644 --- a/sklearn/linear_model/_glm/tests/test_glm.py +++ b/sklearn/linear_model/_glm/tests/test_glm.py @@ -1000,7 +1000,7 @@ def test_linalg_warning_with_newton_solver(global_random_seed): # We check that the model could successfully fit information in X_orig to # improve upon the constant baseline by a large margin (when evaluated on - # the traing set). + # the training set). assert constant_model_deviance - original_newton_deviance > 0.1 # LBFGS is robust to a collinear design because its approximation of the diff --git a/sklearn/linear_model/_passive_aggressive.py b/sklearn/linear_model/_passive_aggressive.py index c5f62efd35bf6..0bf4ad964d0a3 100644 --- a/sklearn/linear_model/_passive_aggressive.py +++ b/sklearn/linear_model/_passive_aggressive.py @@ -40,7 +40,7 @@ class PassiveAggressiveClassifier(BaseSGDClassifier): Parameters ---------- C : float, default=1.0 - Aggressiveness parameter for the passive-agressive algorithm, see [1]. + Aggressiveness parameter for the passive-aggressive algorithm, see [1]. For PA-I it is the maximum step size. For PA-II it regularizes the step size (the smaller `C` the more it regularizes). As a general rule-of-thumb, `C` should be small when the data is noisy. @@ -367,7 +367,7 @@ class PassiveAggressiveRegressor(BaseSGDRegressor): ---------- C : float, default=1.0 - Aggressiveness parameter for the passive-agressive algorithm, see [1]. + Aggressiveness parameter for the passive-aggressive algorithm, see [1]. For PA-I it is the maximum step size. For PA-II it regularizes the step size (the smaller `C` the more it regularizes). As a general rule-of-thumb, `C` should be small when the data is noisy. diff --git a/sklearn/linear_model/_ridge.py b/sklearn/linear_model/_ridge.py index d50beba5f8fc7..5d5ef7536450c 100644 --- a/sklearn/linear_model/_ridge.py +++ b/sklearn/linear_model/_ridge.py @@ -1397,7 +1397,7 @@ def __sklearn_tags__(self): return tags def _get_scorer_instance(self): - """Return a scorer which corresponds to what's defined in ClassiferMixin + """Return a scorer which corresponds to what's defined in ClassifierMixin parent class. This is used for routing `sample_weight`. """ return get_scorer("accuracy") diff --git a/sklearn/linear_model/_sgd_fast.pyx.tp b/sklearn/linear_model/_sgd_fast.pyx.tp index 6170444aefe2b..21201f78a8fa9 100644 --- a/sklearn/linear_model/_sgd_fast.pyx.tp +++ b/sklearn/linear_model/_sgd_fast.pyx.tp @@ -362,7 +362,7 @@ def _plain_sgd{{name_suffix}}( eta0 : double The initial learning rate. For PA-1 (`learning_rate=PA1`) and PA-II (`PA2`), it specifies the - aggressiveness parameter for the passive-agressive algorithm, see [1] where it + aggressiveness parameter for the passive-aggressive algorithm, see [1] where it is called C: - For PA-I it is the maximum step size. diff --git a/sklearn/linear_model/_stochastic_gradient.py b/sklearn/linear_model/_stochastic_gradient.py index 9be78917f299c..0fd47f41be097 100644 --- a/sklearn/linear_model/_stochastic_gradient.py +++ b/sklearn/linear_model/_stochastic_gradient.py @@ -1109,7 +1109,7 @@ class SGDClassifier(BaseSGDClassifier): Values must be in the range `(0.0, inf)`. For PA-1 (`learning_rate=pa1`) and PA-II (`pa2`), it specifies the - aggressiveness parameter for the passive-agressive algorithm, see [1] where it + aggressiveness parameter for the passive-aggressive algorithm, see [1] where it is called C: - For PA-I it is the maximum step size. @@ -1933,7 +1933,7 @@ class SGDRegressor(BaseSGDRegressor): Values must be in the range `(0.0, inf)`. For PA-1 (`learning_rate=pa1`) and PA-II (`pa2`), it specifies the - aggressiveness parameter for the passive-agressive algorithm, see [1] where it + aggressiveness parameter for the passive-aggressive algorithm, see [1] where it is called C: - For PA-I it is the maximum step size. diff --git a/sklearn/linear_model/meson.build b/sklearn/linear_model/meson.build index 6d8405c793389..31faad737c156 100644 --- a/sklearn/linear_model/meson.build +++ b/sklearn/linear_model/meson.build @@ -18,7 +18,7 @@ foreach name: name_list output: name + '.pyx', input: name + '.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: [linear_model_cython_tree, utils_cython_tree, _loss_cython_tree], diff --git a/sklearn/linear_model/tests/test_base.py b/sklearn/linear_model/tests/test_base.py index 737df13fc2cf9..0679c4debc009 100644 --- a/sklearn/linear_model/tests/test_base.py +++ b/sklearn/linear_model/tests/test_base.py @@ -323,7 +323,7 @@ def test_inplace_data_preprocessing(sparse_container, use_sw, global_random_seed rng = np.random.RandomState(global_random_seed) original_X_data = rng.randn(10, 12) original_y_data = rng.randn(10, 2) - orginal_sw_data = rng.rand(10) + original_sw_data = rng.rand(10) if sparse_container is not None: X = sparse_container(original_X_data) @@ -334,7 +334,7 @@ def test_inplace_data_preprocessing(sparse_container, use_sw, global_random_seed # implementation of LinearRegression. if use_sw: - sample_weight = orginal_sw_data.copy() + sample_weight = original_sw_data.copy() else: sample_weight = None @@ -348,7 +348,7 @@ def test_inplace_data_preprocessing(sparse_container, use_sw, global_random_seed assert_allclose(y, original_y_data) if use_sw: - assert_allclose(sample_weight, orginal_sw_data) + assert_allclose(sample_weight, original_sw_data) # Allow inplace preprocessing of X and y reg = LinearRegression(copy_X=False) @@ -368,7 +368,7 @@ def test_inplace_data_preprocessing(sparse_container, use_sw, global_random_seed if use_sw: # Sample weights have no reason to ever be modified inplace. - assert_allclose(sample_weight, orginal_sw_data) + assert_allclose(sample_weight, original_sw_data) def test_linear_regression_pd_sparse_dataframe_warning(): diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index 4c23e72cbfb58..02a3d358cf732 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -1007,7 +1007,7 @@ def test_enet_copy_X_False_check_input_False(): assert np.any(np.not_equal(original_X, X)) -def test_overrided_gram_matrix(): +def test_overridden_gram_matrix(): X, y, _, _ = build_dataset(n_samples=20, n_features=10) Gram = X.T.dot(X) clf = ElasticNet(selection="cyclic", tol=1e-8, precompute=Gram) diff --git a/sklearn/linear_model/tests/test_least_angle.py b/sklearn/linear_model/tests/test_least_angle.py index 39d93098dee58..e1011f8ac3915 100644 --- a/sklearn/linear_model/tests/test_least_angle.py +++ b/sklearn/linear_model/tests/test_least_angle.py @@ -501,8 +501,8 @@ def test_lars_path_readonly_data(): # fold data is in read-only mode # This is a non-regression test for: # https://github.com/scikit-learn/scikit-learn/issues/4597 - splitted_data = train_test_split(X, y, random_state=42) - with TempMemmap(splitted_data) as (X_train, X_test, y_train, y_test): + split_data = train_test_split(X, y, random_state=42) + with TempMemmap(split_data) as (X_train, X_test, y_train, y_test): # The following should not fail despite copy=False _lars_path_residues(X_train, y_train, X_test, y_test, copy=False) diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index 9ca5f6c45f2a4..a1bd4e2c10314 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -1994,7 +1994,7 @@ def test_LogisticRegressionCV_on_folds(): ).fit(X[train_fold_0], y[train_fold_0]) for cl in np.unique(y): - # Coefficients without intecept + # Coefficients without intercept assert_allclose( lrcv.coefs_paths_[cl][idx_fold, idx_C, :-1], lr.coef_[cl], diff --git a/sklearn/linear_model/tests/test_sgd.py b/sklearn/linear_model/tests/test_sgd.py index fadb0f8f0fdff..f69fd22d5cfc7 100644 --- a/sklearn/linear_model/tests/test_sgd.py +++ b/sklearn/linear_model/tests/test_sgd.py @@ -1861,7 +1861,7 @@ def test_l1_ratio(): assert_array_almost_equal(est_en.coef_, est_l2.coef_) -def test_underflow_or_overlow(): +def test_underflow_or_overflow(): with np.errstate(all="raise"): # Generate some weird data with hugely unscaled features rng = np.random.RandomState(0) diff --git a/sklearn/metrics/_pairwise_distances_reduction/meson.build b/sklearn/metrics/_pairwise_distances_reduction/meson.build index 0f7eaa286399c..7ae3417668a7e 100644 --- a/sklearn/metrics/_pairwise_distances_reduction/meson.build +++ b/sklearn/metrics/_pairwise_distances_reduction/meson.build @@ -31,7 +31,7 @@ _datasets_pair_pyx = custom_target( output: '_datasets_pair.pyx', input: '_datasets_pair.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: [_datasets_pair_pxd, _pairwise_distances_reduction_cython_tree, utils_cython_tree], @@ -55,7 +55,7 @@ _base_pyx = custom_target( output: '_base.pyx', input: '_base.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: [_base_pxd, _pairwise_distances_reduction_cython_tree, @@ -80,7 +80,7 @@ _middle_term_computer_pyx = custom_target( output: '_middle_term_computer.pyx', input: '_middle_term_computer.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: [_middle_term_computer_pxd, @@ -106,7 +106,7 @@ _argkmin_pyx = custom_target( output: '_argkmin.pyx', input: '_argkmin.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: [_argkmin_pxd, @@ -132,7 +132,7 @@ _radius_neighbors_pyx = custom_target( output: '_radius_neighbors.pyx', input: '_radius_neighbors.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: [_radius_neighbors_pxd, @@ -152,7 +152,7 @@ _argkmin_classmode_pyx = custom_target( output: '_argkmin_classmode.pyx', input: '_argkmin_classmode.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: [_classmode_pxd, @@ -176,7 +176,7 @@ _radius_neighbors_classmode_pyx = custom_target( output: '_radius_neighbors_classmode.pyx', input: '_radius_neighbors_classmode.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: [_classmode_pxd, diff --git a/sklearn/metrics/_plot/tests/test_precision_recall_display.py b/sklearn/metrics/_plot/tests/test_precision_recall_display.py index 86f9c0abb1bcb..e7bb8da37fb70 100644 --- a/sklearn/metrics/_plot/tests/test_precision_recall_display.py +++ b/sklearn/metrics/_plot/tests/test_precision_recall_display.py @@ -259,7 +259,7 @@ def test_precision_recall_display_from_cv_results_plotting( ), ], ) -def test_precison_recall_plot_parameter_length_validation(pyplot, params, err_msg): +def test_precision_recall_plot_parameter_length_validation(pyplot, params, err_msg): """Check `plot` parameter length validation performed correctly.""" display = PrecisionRecallDisplay(**params) if err_msg: diff --git a/sklearn/metrics/_ranking.py b/sklearn/metrics/_ranking.py index d032412801e35..ef1fba35189c3 100644 --- a/sklearn/metrics/_ranking.py +++ b/sklearn/metrics/_ranking.py @@ -2268,7 +2268,7 @@ def metric_at_thresholds( r"""Compute `metric_func` per threshold for :term:`binary` data. Aids visualization of metric values across thresholds when tuning the - :ref:`decision threshold <threshold_tunning>`. + :ref:`decision threshold <threshold_tuning>`. Read more in the :ref:`User Guide <metric_at_thresholds>`. diff --git a/sklearn/metrics/meson.build b/sklearn/metrics/meson.build index f0f9894cc6f59..b648d9be8df91 100644 --- a/sklearn/metrics/meson.build +++ b/sklearn/metrics/meson.build @@ -23,7 +23,7 @@ _dist_metrics_pyx = custom_target( output: '_dist_metrics.pyx', input: '_dist_metrics.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: metrics_cython_tree, diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index e13ac345fc66b..8f7cf9f1ef69a 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -3222,7 +3222,7 @@ def test_f1_for_small_binary_inputs_with_zero_division(y_true, y_pred, expected_ make_scorer(recall_score, zero_division=np.nan), ], ) -def test_classification_metric_division_by_zero_nan_validaton(scoring): +def test_classification_metric_division_by_zero_nan_validation(scoring): """Check that we validate `np.nan` properly for classification metrics. With `n_jobs=2` in cross-validation, the `np.nan` used for the singleton will be diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 34a18c254a09f..84e32135c6677 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -235,7 +235,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): """ precision, recall, thresholds = precision_recall_curve(*args, **kwargs) - pad_threshholds = len(precision) - len(thresholds) + pad_thresholds = len(precision) - len(thresholds) return np.array( [ @@ -243,7 +243,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): recall, np.pad( thresholds.astype(np.float64), - pad_width=(0, pad_threshholds), + pad_width=(0, pad_thresholds), mode="constant", constant_values=[np.nan], ), @@ -362,7 +362,7 @@ def precision_recall_curve_padded_thresholds(*args, **kwargs): } # Threshold-based metrics with an "average" argument -CONTINOUS_CLASSIFICATION_METRICS_WITH_AVERAGING = { +CONTINUOUS_CLASSIFICATION_METRICS_WITH_AVERAGING = { "roc_auc_score", "average_precision_score", "partial_roc_auc", @@ -1521,7 +1521,7 @@ def check_averaging(name, y_true, y_true_binarize, y_pred, y_pred_binarize, y_sc _check_averaging( metric, y_true, y_pred, y_true_binarize, y_pred_binarize, is_multilabel ) - elif name in CONTINOUS_CLASSIFICATION_METRICS_WITH_AVERAGING: + elif name in CONTINUOUS_CLASSIFICATION_METRICS_WITH_AVERAGING: _check_averaging( metric, y_true, y_score, y_true_binarize, y_score, is_multilabel ) @@ -1546,7 +1546,7 @@ def test_averaging_multiclass(name): @pytest.mark.parametrize( "name", - sorted(METRICS_WITH_AVERAGING | CONTINOUS_CLASSIFICATION_METRICS_WITH_AVERAGING), + sorted(METRICS_WITH_AVERAGING | CONTINUOUS_CLASSIFICATION_METRICS_WITH_AVERAGING), ) def test_averaging_multilabel(name): n_samples, n_classes = 40, 5 diff --git a/sklearn/metrics/tests/test_pairwise.py b/sklearn/metrics/tests/test_pairwise.py index 29eebc207892f..9cef6840343eb 100644 --- a/sklearn/metrics/tests/test_pairwise.py +++ b/sklearn/metrics/tests/test_pairwise.py @@ -1219,7 +1219,7 @@ def test_nan_euclidean_distances_complete_nan(missing_value): @pytest.mark.parametrize("missing_value", [np.nan, -1]) -def test_nan_euclidean_distances_not_trival(missing_value): +def test_nan_euclidean_distances_not_trivial(missing_value): X = np.array( [ [1.0, missing_value, 3.0, 4.0, 2.0], diff --git a/sklearn/metrics/tests/test_ranking.py b/sklearn/metrics/tests/test_ranking.py index abab50ea5def6..247fe6f658491 100644 --- a/sklearn/metrics/tests/test_ranking.py +++ b/sklearn/metrics/tests/test_ranking.py @@ -2380,7 +2380,7 @@ def test_ranking_metric_pos_label_types(metric, classes): assert not np.isnan(thresholds).any() -def test_roc_curve_with_probablity_estimates(global_random_seed): +def test_roc_curve_with_probability_estimates(global_random_seed): """Check that thresholds do not exceed 1.0 when `y_score` is a probability estimate. diff --git a/sklearn/model_selection/_classification_threshold.py b/sklearn/model_selection/_classification_threshold.py index 381ee42fee5eb..3dfa02fd1238a 100644 --- a/sklearn/model_selection/_classification_threshold.py +++ b/sklearn/model_selection/_classification_threshold.py @@ -504,7 +504,7 @@ class TunedThresholdClassifierCV(BaseThresholdClassifier): into a class label. The tuning is done by optimizing a binary metric, potentially constrained by another metric. - Read more in the :ref:`User Guide <threshold_tunning>`. + Read more in the :ref:`User Guide <threshold_tuning>`. .. versionadded:: 1.5 diff --git a/sklearn/model_selection/tests/test_split.py b/sklearn/model_selection/tests/test_split.py index afaf979019f1c..55fe4f2732caf 100644 --- a/sklearn/model_selection/tests/test_split.py +++ b/sklearn/model_selection/tests/test_split.py @@ -1225,7 +1225,7 @@ def test_repeated_cv_repr(RepeatedCV): assert repeated_cv_repr == repr(repeated_cv) -def test_repeated_kfold_determinstic_split(): +def test_repeated_kfold_deterministic_split(): X = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] random_state = 258173307 rkf = RepeatedKFold(n_splits=2, n_repeats=2, random_state=random_state) @@ -1270,7 +1270,7 @@ def test_get_n_splits_for_repeated_stratified_kfold(): assert expected_n_splits == rskf.get_n_splits() -def test_repeated_stratified_kfold_determinstic_split(): +def test_repeated_stratified_kfold_deterministic_split(): X = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] y = [1, 1, 1, 0, 0] random_state = 1944695409 diff --git a/sklearn/neighbors/_quad_tree.pyx b/sklearn/neighbors/_quad_tree.pyx index 5f623bf6cbecd..f041858c7f780 100644 --- a/sklearn/neighbors/_quad_tree.pyx +++ b/sklearn/neighbors/_quad_tree.pyx @@ -342,7 +342,7 @@ cdef class _QuadTree: if not cell.is_leaf: # Compute the number of point in children and compare with - # its cummulative_size. + # its cumulative_size. n_points = 0 for idx in range(self.n_cells_per_cell): child_id = cell.children[idx] diff --git a/sklearn/neighbors/meson.build b/sklearn/neighbors/meson.build index 7993421896218..ee3b45b95ab9d 100644 --- a/sklearn/neighbors/meson.build +++ b/sklearn/neighbors/meson.build @@ -21,7 +21,7 @@ foreach name: name_list output: name + '.pyx', input: name + '.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: [neighbors_cython_tree, utils_cython_tree, metrics_cython_tree], diff --git a/sklearn/preprocessing/_function_transformer.py b/sklearn/preprocessing/_function_transformer.py index b3a64508e906c..58f4a7367213f 100644 --- a/sklearn/preprocessing/_function_transformer.py +++ b/sklearn/preprocessing/_function_transformer.py @@ -381,7 +381,7 @@ def _transform(self, X, func=None, kw_args=None): return func(X, **(kw_args if kw_args else {})) def __sklearn_is_fitted__(self): - """Return True since FunctionTransfomer is stateless.""" + """Return True since FunctionTransformer is stateless.""" return True def __sklearn_tags__(self): diff --git a/sklearn/preprocessing/_label.py b/sklearn/preprocessing/_label.py index dd7f65c752059..1b906ba62e468 100644 --- a/sklearn/preprocessing/_label.py +++ b/sklearn/preprocessing/_label.py @@ -1023,7 +1023,7 @@ def inverse_transform(self, yt): Parameters ---------- yt : {ndarray, sparse matrix} of shape (n_samples, n_classes) - A matrix containing only 1s ands 0s. + A matrix containing only 1s and 0s. Returns ------- diff --git a/sklearn/preprocessing/tests/test_data.py b/sklearn/preprocessing/tests/test_data.py index 12d45eed7cff7..d7ea7e2fd35d9 100644 --- a/sklearn/preprocessing/tests/test_data.py +++ b/sklearn/preprocessing/tests/test_data.py @@ -696,7 +696,7 @@ def test_partial_fit_sparse_input(sample_weight, sparse_container): @pytest.mark.parametrize("sample_weight", [True, None]) -def test_standard_scaler_trasform_with_partial_fit(sample_weight): +def test_standard_scaler_transform_with_partial_fit(sample_weight): # Check some postconditions after applying partial_fit and transform X = X_2d[:100, :] @@ -2748,7 +2748,7 @@ def test_kernel_centerer_feature_names_out(): @pytest.mark.parametrize("standardize", [True, False]) def test_power_transformer_constant_feature(standardize): - """Check that PowerTransfomer leaves constant features unchanged.""" + """Check that PowerTransformer leaves constant features unchanged.""" X = [[-2, 0, 2], [-2, 0, 2], [-2, 0, 2]] pt = PowerTransformer(method="yeo-johnson", standardize=standardize).fit(X) diff --git a/sklearn/preprocessing/tests/test_encoders.py b/sklearn/preprocessing/tests/test_encoders.py index b467e36b83a2e..e7baa4b0bd0d8 100644 --- a/sklearn/preprocessing/tests/test_encoders.py +++ b/sklearn/preprocessing/tests/test_encoders.py @@ -343,7 +343,7 @@ def test_one_hot_encoder_inverse_transform_raise_error_with_unknown( X, X_trans, sparse_ ): """Check that `inverse_transform` raise an error with unknown samples, no - dropped feature, and `handle_unknow="error`. + dropped feature, and `handle_unknown="error`. Non-regression test for: https://github.com/scikit-learn/scikit-learn/issues/14934 """ diff --git a/sklearn/preprocessing/tests/test_function_transformer.py b/sklearn/preprocessing/tests/test_function_transformer.py index c4d6867fc66ab..8364b12eed6ef 100644 --- a/sklearn/preprocessing/tests/test_function_transformer.py +++ b/sklearn/preprocessing/tests/test_function_transformer.py @@ -214,7 +214,7 @@ def inverse_func(X): transformer.fit(data) -def test_function_transformer_support_all_nummerical_dataframes_check_inverse_True(): +def test_function_transformer_support_all_numerical_dataframes_check_inverse_True(): """Check support for dataframes with only numerical values.""" pd = pytest.importorskip("pandas") @@ -231,7 +231,7 @@ def test_function_transformer_support_all_nummerical_dataframes_check_inverse_Tr def test_function_transformer_with_dataframe_and_check_inverse_True(): """Check error is raised when check_inverse=True. - Non-regresion test for gh-25261. + Non-regression test for gh-25261. """ pd = pytest.importorskip("pandas") transformer = FunctionTransformer( diff --git a/sklearn/tests/test_calibration.py b/sklearn/tests/test_calibration.py index 6ae1a28408eda..eb816d0a3126f 100644 --- a/sklearn/tests/test_calibration.py +++ b/sklearn/tests/test_calibration.py @@ -1192,17 +1192,17 @@ def test_float32_predict_proba(data, use_sample_weight, method): else: sample_weight = None - class DummyClassifer32(DummyClassifier): + class DummyClassifier32(DummyClassifier): def predict_proba(self, X): return super().predict_proba(X).astype(np.float32) - model = DummyClassifer32() + model = DummyClassifier32() calibrator = CalibratedClassifierCV(model, method=method) # Does not raise an error. calibrator.fit(*data, sample_weight=sample_weight) # Check with frozen prefit model - model = DummyClassifer32().fit(*data, sample_weight=sample_weight) + model = DummyClassifier32().fit(*data, sample_weight=sample_weight) calibrator = CalibratedClassifierCV(FrozenEstimator(model), method=method) # Does not raise an error. calibrator.fit(*data, sample_weight=sample_weight) diff --git a/sklearn/tests/test_min_dependencies_readme.py b/sklearn/tests/test_min_dependencies_readme.py index 9a51041e2321f..3e7da7a713ce8 100644 --- a/sklearn/tests/test_min_dependencies_readme.py +++ b/sklearn/tests/test_min_dependencies_readme.py @@ -123,27 +123,27 @@ def test_min_dependencies_readme(): message = ( f"{package} has inconsistent minimum versions in README.rst and" - f" _min_depencies.py: {version} != {min_version}" + f" _min_dependencies.py: {version} != {min_version}" ) assert version == min_version, message def extract_packages_and_pyproject_tags(dependencies): - min_depencies_tag_to_packages_without_version = defaultdict(list) + min_dependencies_tag_to_packages_without_version = defaultdict(list) for package, (min_version, tags) in dependencies.items(): for t in tags.split(", "): - min_depencies_tag_to_packages_without_version[t].append(package) + min_dependencies_tag_to_packages_without_version[t].append(package) pyproject_section_to_min_dependencies_tag = { "build-system.requires": "build", "project.dependencies": "install", } - for tag in min_depencies_tag_to_packages_without_version: + for tag in min_dependencies_tag_to_packages_without_version: section = f"project.optional-dependencies.{tag}" pyproject_section_to_min_dependencies_tag[section] = tag return ( - min_depencies_tag_to_packages_without_version, + min_dependencies_tag_to_packages_without_version, pyproject_section_to_min_dependencies_tag, ) @@ -182,7 +182,7 @@ def check_pyproject_sections(pyproject_toml, min_dependencies): pyproject_build_min_versions[package] = version - msg = f"Packages in {pyproject_section} differ from _min_depencies.py" + msg = f"Packages in {pyproject_section} differ from _min_dependencies.py" assert sorted(pyproject_build_min_versions) == sorted(expected_packages), msg @@ -194,7 +194,7 @@ def check_pyproject_sections(pyproject_toml, min_dependencies): message = ( f"{package} has inconsistent minimum versions in pyproject.toml and" - f" _min_depencies.py: {version} != {expected_min_version}" + f" _min_dependencies.py: {version} != {expected_min_version}" ) assert version == expected_min_version, message @@ -241,16 +241,16 @@ def test_check_matching_pyproject_section(example_pyproject): ), ( TOY_MISSING_PACKAGE_PYPROJECT_SECTIONS, - "Packages in .* differ from _min_depencies.py", + "Packages in .* differ from _min_dependencies.py", ), ( TOY_ADDITIONAL_PACKAGE_PYPROJECT_SECTIONS, - "Packages in .* differ from _min_depencies.py", + "Packages in .* differ from _min_dependencies.py", ), ( TOY_NON_MATCHING_VERSION_PYPROJECT_SECTIONS, ".* has inconsistent minimum versions in pyproject.toml and" - " _min_depencies.py: .* != .*", + " _min_dependencies.py: .* != .*", ), ], ) diff --git a/sklearn/tests/test_pipeline.py b/sklearn/tests/test_pipeline.py index 37f1416369d47..7c81ac4ac9a97 100644 --- a/sklearn/tests/test_pipeline.py +++ b/sklearn/tests/test_pipeline.py @@ -1831,7 +1831,7 @@ def test_feature_union_check_if_fitted(): def test_pipeline_get_feature_names_out_passes_names_through(): """Check that pipeline passes names through. - Non-regresion test for #21349. + Non-regression test for #21349. """ X, y = iris.data, iris.target diff --git a/sklearn/tree/_classes.py b/sklearn/tree/_classes.py index 7410fd91c89e8..5b3781f1e856d 100644 --- a/sklearn/tree/_classes.py +++ b/sklearn/tree/_classes.py @@ -411,10 +411,10 @@ def _fit( ) valid_constraints = np.isin(monotonic_cst, (-1, 0, 1)) if not np.all(valid_constraints): - unique_constaints_value = np.unique(monotonic_cst) + unique_constraints_value = np.unique(monotonic_cst) raise ValueError( "monotonic_cst must be None or an array-like of -1, 0 or 1, but" - f" got {unique_constaints_value}" + f" got {unique_constraints_value}" ) monotonic_cst = np.asarray(monotonic_cst, dtype=np.int8) if is_classifier(self): diff --git a/sklearn/tree/_criterion.pyx b/sklearn/tree/_criterion.pyx index d3258169cd4ca..b04766ee266ef 100644 --- a/sklearn/tree/_criterion.pyx +++ b/sklearn/tree/_criterion.pyx @@ -1054,7 +1054,7 @@ cdef void precompute_absolute_errors( sample_indices : const intp_t[:] indices indicating which samples to use. Shape: (n_samples,) tree : WeightedFenwickTree - pre-instanciated tree + pre-instantiated tree start : intp_t Start index in `sample_indices` end : intp_t diff --git a/sklearn/tree/_tree.pyx b/sklearn/tree/_tree.pyx index 6facd0cc34b79..31985fdeca56d 100644 --- a/sklearn/tree/_tree.pyx +++ b/sklearn/tree/_tree.pyx @@ -620,7 +620,7 @@ cdef class BestFirstTreeBuilder(TreeBuilder): if node_id == INTPTR_MAX: return -1 - # compute values also for split nodes (might become leafs later). + # compute values also for split nodes (might become leaves later). splitter.node_value(tree.value + node_id * tree.value_stride) if splitter.with_monotonic_cst: splitter.clip_node_value(tree.value + node_id * tree.value_stride, parent_record.lower_bound, parent_record.upper_bound) diff --git a/sklearn/tree/tests/test_reingold_tilford.py b/sklearn/tree/tests/test_reingold_tilford.py index bf0ce3ce2cffc..fdf25c261560f 100644 --- a/sklearn/tree/tests/test_reingold_tilford.py +++ b/sklearn/tree/tests/test_reingold_tilford.py @@ -43,7 +43,7 @@ def walk_tree(draw_tree): while True: x_at_this_depth = [node[0] for node in coordinates if node[1] == depth] if not x_at_this_depth: - # reached all leafs + # reached all leaves break assert len(np.unique(x_at_this_depth)) == len(x_at_this_depth) depth += 1 diff --git a/sklearn/tree/tests/test_tree.py b/sklearn/tree/tests/test_tree.py index 53c301fa19035..f132c795dbfaf 100644 --- a/sklearn/tree/tests/test_tree.py +++ b/sklearn/tree/tests/test_tree.py @@ -1216,7 +1216,7 @@ def test_class_weight_errors(name): def test_max_leaf_nodes(): - # Test greedy trees with max_depth + 1 leafs. + # Test greedy trees with max_depth + 1 leaves. X, y = datasets.make_hastie_10_2(n_samples=100, random_state=1) k = 4 for name, TreeEstimator in ALL_TREES.items(): @@ -1268,7 +1268,7 @@ def test_almost_constant_feature(tree_cls): # Make sure that almost constant features are discarded. random_state = check_random_state(0) X = random_state.rand(10, 2) - # FEATURE_TRESHOLD=1e-7 is defined in sklearn/tree/_partitioner.pxd but not + # FEATURE_THRESHOLD=1e-7 is defined in sklearn/tree/_partitioner.pxd but not # accessible from Python feature_threshold = 1e-7 X[:, 0] *= feature_threshold # almost constant feature diff --git a/sklearn/utils/_testing.py b/sklearn/utils/_testing.py index 79d92be534a81..792259482ae79 100644 --- a/sklearn/utils/_testing.py +++ b/sklearn/utils/_testing.py @@ -1509,7 +1509,7 @@ def to_filterwarning_str(self): message=".+scattermapbox.+deprecated.+scattermap.+instead", category=DeprecationWarning, ), - # TODO(1.10): remove PassiveAgressive + # TODO(1.10): remove PassiveAggressive WarningInfo( "ignore", message="Class PassiveAggressive.+is deprecated", diff --git a/sklearn/utils/estimator_checks.py b/sklearn/utils/estimator_checks.py index 1c18fc628ce20..07d70688b40ea 100644 --- a/sklearn/utils/estimator_checks.py +++ b/sklearn/utils/estimator_checks.py @@ -134,7 +134,7 @@ def _yield_api_checks(estimator): tags = get_tags(estimator) # This is commented out since it's the first check both - # `parametrize_with_checks` and `check_esitmator` do + # `parametrize_with_checks` and `check_estimator` do # anyway. But leaving it here as commented out to know # it's a part of the basic API. # yield check_estimator_cloneable @@ -2568,7 +2568,7 @@ def check_transformer_preserve_dtypes(name, transformer_orig): for Xt, method in zip([X_trans1, X_trans2], ["fit_transform", "transform"]): if isinstance(Xt, tuple): - # cross-decompostion returns a tuple of (x_scores, y_scores) + # cross-decomposition returns a tuple of (x_scores, y_scores) # when given y with fit_transform; only check the first element Xt = Xt[0] diff --git a/sklearn/utils/extmath.py b/sklearn/utils/extmath.py index 3e0979fc6f2da..61520fd13d23e 100644 --- a/sklearn/utils/extmath.py +++ b/sklearn/utils/extmath.py @@ -331,7 +331,7 @@ def _randomized_range_finder( # Note: we cannot combine the astype and to_device operations in one go # using xp.asarray(..., dtype=dtype, device=device) because downcasting # from float64 to float32 in asarray might not always be accepted as only - # casts following type promotion rules are guarateed to work. + # casts following type promotion rules are guaranteed to work. # https://github.com/data-apis/array-api/issues/647 if is_array_api_compliant: Q = xp.asarray(Q, device=device(A)) diff --git a/sklearn/utils/meson.build b/sklearn/utils/meson.build index 0a8a7ff7fbe4e..c3402df91363c 100644 --- a/sklearn/utils/meson.build +++ b/sklearn/utils/meson.build @@ -80,7 +80,7 @@ foreach name: util_extension_names output: name + '.pyx', input: name + '.pyx.tp', command: [tempita, '@INPUT@', '-o', '@OUTDIR@'], - # TODO in principle this should go in py.exension_module below. This is + # TODO in principle this should go in py.extension_module below. This is # temporary work-around for dependency issue with .pyx.tp files. For more # details, see https://github.com/mesonbuild/meson/issues/13212 depends: [pxd, utils_cython_tree], diff --git a/sklearn/utils/tests/test_plotting.py b/sklearn/utils/tests/test_plotting.py index 94357dd761f69..be123ace869b9 100644 --- a/sklearn/utils/tests/test_plotting.py +++ b/sklearn/utils/tests/test_plotting.py @@ -438,7 +438,7 @@ def test_validate_score_name(score_name, scoring, negate_score, expected_score_n ([1, 2, 5, 10, 20, 50], 20, 40), ], ) -def test_inverval_max_min_ratio(data, lower_bound, upper_bound): +def test_interval_max_min_ratio(data, lower_bound, upper_bound): assert lower_bound < _interval_max_min_ratio(data) < upper_bound diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index f232c60e0dd41..25f08c993f376 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -2539,13 +2539,13 @@ def _check_monotonic_cst(estimator, monotonic_cst=None): set(original_monotonic_cst) - set(estimator.feature_names_in_) ) unexpected_feature_names.sort() # deterministic error message - n_unexpeced = len(unexpected_feature_names) + n_unexpected = len(unexpected_feature_names) if unexpected_feature_names: if len(unexpected_feature_names) > 5: unexpected_feature_names = unexpected_feature_names[:5] unexpected_feature_names.append("...") raise ValueError( - f"monotonic_cst contains {n_unexpeced} unexpected feature " + f"monotonic_cst contains {n_unexpected} unexpected feature " f"names: {unexpected_feature_names}." ) for feature_idx, feature_name in enumerate(estimator.feature_names_in_): From 7a766944f659bd5842a19c0e87317b3097513645 Mon Sep 17 00:00:00 2001 From: Shyan Paul <132336657+Shy4n7@users.noreply.github.com> Date: Mon, 4 May 2026 19:50:20 +0530 Subject: [PATCH 424/462] DOC clarify cluster metric label inputs (#33912) --- sklearn/metrics/cluster/_supervised.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sklearn/metrics/cluster/_supervised.py b/sklearn/metrics/cluster/_supervised.py index 7a064f0ffaa2a..2476a431afe51 100644 --- a/sklearn/metrics/cluster/_supervised.py +++ b/sklearn/metrics/cluster/_supervised.py @@ -972,11 +972,11 @@ def adjusted_mutual_info_score( Parameters ---------- - labels_true : int array-like of shape (n_samples,) + labels_true : array-like of shape (n_samples,) A clustering of the data into disjoint subsets, called :math:`U` in the above formula. - labels_pred : int array-like of shape (n_samples,) + labels_pred : array-like of shape (n_samples,) A clustering of the data into disjoint subsets, called :math:`V` in the above formula. @@ -1108,10 +1108,10 @@ def normalized_mutual_info_score( Parameters ---------- - labels_true : int array-like of shape (n_samples,) + labels_true : array-like of shape (n_samples,) A clustering of the data into disjoint subsets. - labels_pred : int array-like of shape (n_samples,) + labels_pred : array-like of shape (n_samples,) A clustering of the data into disjoint subsets. average_method : {'min', 'geometric', 'arithmetic', 'max'}, default='arithmetic' From 63ee814f30843640b3d3b7992eb6863058704ede Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Mon, 4 May 2026 16:25:51 +0200 Subject: [PATCH 425/462] DOC Update colors in Scaling Importance example (#33888) --- examples/preprocessing/plot_scaling_importance.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/preprocessing/plot_scaling_importance.py b/examples/preprocessing/plot_scaling_importance.py index 267e4d4e764a4..f2f6c46f5d91e 100644 --- a/examples/preprocessing/plot_scaling_importance.py +++ b/examples/preprocessing/plot_scaling_importance.py @@ -65,6 +65,7 @@ # of features. import matplotlib.pyplot as plt +from matplotlib.colors import ListedColormap from sklearn.inspection import DecisionBoundaryDisplay from sklearn.neighbors import KNeighborsClassifier @@ -83,7 +84,10 @@ def fit_and_plot_model(X_plot, y, clf, ax): alpha=0.5, ax=ax, ) - disp.ax_.scatter(X_plot["proline"], X_plot["hue"], c=y, s=20, edgecolor="k") + cmap = ListedColormap(disp.multiclass_colors_) + disp.ax_.scatter( + X_plot["proline"], X_plot["hue"], c=y, cmap=cmap, s=20, edgecolor="k" + ) disp.ax_.set_xlim((X_plot["proline"].min(), X_plot["proline"].max())) disp.ax_.set_ylim((X_plot["hue"].min(), X_plot["hue"].max())) return disp.ax_ From b786f9554fd1170a87004d3d2ca8381e1a821fae Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 4 May 2026 10:47:29 -0400 Subject: [PATCH 426/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33864) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/circle/doc_linux-64_conda.lock | 75 ++++++++++--------- .../doc_min_dependencies_linux-64_conda.lock | 65 ++++++++-------- build_tools/github/debian_32bit_lock.txt | 4 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 73 +++++++++--------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 22 +++--- .../pylatest_conda_forge_osx-arm64_conda.lock | 36 ++++----- ...st_pip_openblas_pandas_linux-64_conda.lock | 16 ++-- ...n_conda_forge_arm_linux-aarch64_conda.lock | 26 +++---- ...nblas_min_dependencies_linux-64_conda.lock | 42 +++++------ ...e_openblas_ubuntu_2204_linux-64_conda.lock | 22 +++--- ...min_conda_forge_openblas_win-64_conda.lock | 24 +++--- build_tools/github/ubuntu_atlas_lock.txt | 4 +- 12 files changed, 206 insertions(+), 203 deletions(-) diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 860a6b0df9f11..8c2688595e6d5 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -7,17 +7,18 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_10.conda#590b5a14299d67b9669fe5eb1fdd4d3b +https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_11.conda#4a1793b78e4309bbdb99bd033226f0d2 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda#06901733131833f5edd68cf3d9679798 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.3-h4922eb0_0.conda#f7781cb22afa62ef27fd0b3300c53c86 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.4-h4922eb0_0.conda#fa2c5c7f8d5319ab9c9fcbbd04022abf +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_11.conda#c0004c583be9ac82ad2115bc08f3d77d https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -32,7 +33,7 @@ https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2f https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -47,7 +48,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.cond https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.8.1-h1fbca29_0.conda#d83958768626b3c8471ce032e28afcd3 @@ -74,7 +75,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e -https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 +https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.4.0-h10be129_0.conda#3a9428b74c403c71048104d38437b48c https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -94,12 +95,12 @@ https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#34672 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.1-hc31b594_0.conda#68ceffc6cadae61846a207cae60de094 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-3.0.1-hc31b594_0.conda#d21cf8ca2e3e175299022c6f29d5ace7 https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da -https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h6705ce6_0.conda#42c424ab163c576c7fb5981f7fb379cf +https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-h174a0a3_1.conda#850f48943d6b4589800a303f0de6a816 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 @@ -116,10 +117,10 @@ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.con https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_23.conda#b6090b005c6e1947e897c926caac1286 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h50e9bb6_24.conda#91b0f19212d79a1a4dca034aac729e4f https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c @@ -136,13 +137,13 @@ https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda#7 https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda#c6b0543676ecb1fb2d7643941fe375f2 https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 -https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 +https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.4.0-py314h680f03e_0.conda#b712198b257f378e9bd8cde277218296 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2#576d629e47797577ab0f1b351297ef4a https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 -https://conda.anaconda.org/conda-forge/noarch/click-8.3.2-pyhc90fa1f_0.conda#4d18bc3af7cfcea97bd817164672a08c +https://conda.anaconda.org/conda-forge/noarch/click-8.3.3-pyhc90fa1f_0.conda#2266262ce8a425ecb6523d765f79b303 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -152,11 +153,11 @@ https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/doit-0.37.0-pyhcf101f3_0.conda#37b3d4c558f2bb2b5378c43f4d6f1fb5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h7499c90_23.conda#3a937700705778ab8f5a6ce4f38eccca -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h91b0f8e_23.conda#12d093c7df954a01b396a748442bd5cb +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h6b77fdb_24.conda#491f76c26b2d032b21ba0b79cc324c4f +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h8a413ad_24.conda#ea3921760f33250a1c12926fce1660eb https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac -https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 +https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda#1269891272187518a0a75c286f7d0bbf @@ -166,17 +167,17 @@ https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b96 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.19.0-pyhcf101f3_0.conda#b94cbc2227cdca1e9a65d7ad4ee636c1 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f @@ -191,8 +192,7 @@ https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.21.2-pyhe01879c_0.conda#23029aae904a2ba587daba708208012f -https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda#a61bf9ec79426938ff785eb69dbb1960 -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.1-pyhd8ed1ab_0.conda#d8d30923ccee7525704599efd722aa16 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda#f6ad7450fc21e00ecc23812baed6d2e4 https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.3-py314h67df5f8_1.conda#2035f68f96be30dc60a5dfd7452c7941 https://conda.anaconda.org/conda-forge/noarch/rfc3986-validator-0.1.1-pyh9f0ad1d_0.tar.bz2#912a71cc01012ee38e6b90ddd561e36f https://conda.anaconda.org/conda-forge/noarch/roman-numerals-4.1.0-pyhd8ed1ab_0.conda#0dc48b4b570931adc8641e55c6c17fe4 @@ -228,11 +228,11 @@ https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.con https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda#cf45f4278afd6f4e6d03eda0f435d527 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda#0ba6225c279baf7ea9473a62ea0ec9ae https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d @@ -240,18 +240,19 @@ https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#61 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_1.conda#80daec8cf93185515ac7b5d359e3f929 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 -https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.0-pyhcf101f3_0.conda#b11e360fc4de2b0035fc8aaa74f17fd6 +https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda#b97e84d1553b4a1c765b87fff83453ad https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda#3e9427ee186846052e81fadde8ebe96a https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 +https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efcf_0.conda#1cd2f3e885162ee1366312bd1b1677fd https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 @@ -276,7 +277,7 @@ https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.4-pyhcf101f3_ https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b @@ -285,12 +286,12 @@ https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.c https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.1-pyhcf101f3_0.conda#4552b601cf622dea2bb5075baccc2c5b https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda#082985717303dab433c976986c674b35 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda#8368d58342d0825f0843dc6acdd0c483 https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 @@ -300,14 +301,14 @@ https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 -https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.0-pyhe01879c_0.conda#31e11c30bbee1682a55627f953c6725a +https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda#bf42ee94c750c0b2e7e998b79ac299ea https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.1-pyhbbac1ac_0.conda#d8f030e3730713c93a358fdb46f08281 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py314h1ae5b44_2.conda#63c263894d9cf9540fec26d9e67115f1 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py314h2730e07_3.conda#8664abf57c0ab721522b72879a101d6c https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda#2bce0d047658a91b99441390b9b27045 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py314hb4ffadd_0.conda#41ee6fe2a848876bc9f524c5a500b85b @@ -315,21 +316,21 @@ https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#867 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda#d79a87dcfa726bcea8e61275feed6f83 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.9-py314h1194b4b_0.conda#11a821746ad11e642fcc615c3d66aa44 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py314hc02f841_0.conda#224e6e308b3df5c0c99d8ca5244bb34c -https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.4.11-pyhd8ed1ab_0.conda#e0ed123314d08b63cd1ee95331c67ae3 +https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.5.2-pyhd8ed1ab_0.conda#acb237de455d7fbac79afc8a33eb43c0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.9-py314hdafbbf9_0.conda#2046de06d7f4149a29c5d0e2cc26d6dd https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py314hda1ea4c_0.conda#50d6faa367ca045c438d3bb25315b476 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 https://conda.anaconda.org/conda-forge/noarch/seaborn-0.13.2-hd8ed1ab_3.conda#62afb877ca2c2b4b6f9ecb37320085b6 https://conda.anaconda.org/conda-forge/noarch/jupyterlite-sphinx-0.22.1-pyhcf101f3_0.conda#1f90643873d0cc2f7b0bf2752db71016 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 -https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.17.0-pyhcf101f3_0.conda#c09bb5f9960ff1cd334c5573b5ad79c2 +https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.17.1-pyhcf101f3_0.conda#620cee61c85cf6a407f80e8d502796ec https://conda.anaconda.org/conda-forge/noarch/sphinx-copybutton-0.5.2-pyhd8ed1ab_1.conda#bf22cb9c439572760316ce0748af3713 https://conda.anaconda.org/conda-forge/noarch/sphinx-design-0.7.0-pyhd8ed1ab_0.conda#28eddfb8b9ecdd044a6f609f985398a7 -https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.20.0-pyhd8ed1ab_0.conda#4cae490c8d142824fb80d9aed672fddd +https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.21.0-pyhd8ed1ab_0.conda#9b783047bd5bef0998f129bef8fad477 https://conda.anaconda.org/conda-forge/noarch/sphinx-prompt-1.10.1-pyhd8ed1ab_0.conda#bfc047865de18ef2657bd8a95d7b8b49 https://conda.anaconda.org/conda-forge/noarch/sphinx-remove-toctrees-1.0.0.post1-pyhd8ed1ab_1.conda#b275c865b753413caaa8548b9d44c024 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda#16e3f039c0aa6446513e94ab18a8784b diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 5cacf16954921..809c5fccfe28d 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -7,17 +7,18 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_10.conda#590b5a14299d67b9669fe5eb1fdd4d3b +https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_11.conda#4a1793b78e4309bbdb99bd033226f0d2 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda#06901733131833f5edd68cf3d9679798 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.3-h4922eb0_0.conda#f7781cb22afa62ef27fd0b3300c53c86 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.4-h4922eb0_0.conda#fa2c5c7f8d5319ab9c9fcbbd04022abf +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_11.conda#c0004c583be9ac82ad2115bc08f3d77d https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -34,7 +35,7 @@ https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499cd8e2d4358986dbe3b30e8fe1bf6a https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -50,7 +51,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#e https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/rav1e-0.8.1-h1fbca29_0.conda#d83958768626b3c8471ce032e28afcd3 @@ -78,7 +79,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e -https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.3.0-h4c17acf_1.conda#c2a0c1d0120520e979685034e0b79859 +https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.4.0-h10be129_0.conda#3a9428b74c403c71048104d38437b48c https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda#8ee3cb7f64be0e8c4787f3a4dbe024e6 @@ -101,13 +102,13 @@ https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#34672 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-2.23.1-hc31b594_0.conda#68ceffc6cadae61846a207cae60de094 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-3.0.1-hc31b594_0.conda#d21cf8ca2e3e175299022c6f29d5ace7 https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da -https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-ha09017c_0.conda#1df8c1b1d6665642107883685db6cf37 +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h6705ce6_0.conda#42c424ab163c576c7fb5981f7fb379cf +https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-h174a0a3_1.conda#850f48943d6b4589800a303f0de6a816 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 @@ -124,11 +125,11 @@ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.con https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_23.conda#b6090b005c6e1947e897c926caac1286 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h50e9bb6_24.conda#91b0f19212d79a1a4dca034aac729e4f https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda#b52b769cd13f7adaa6ccdc68ef801709 +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.88.1-h040f060_0.conda#55e7cea32f68a173635bcd4ea3d6e02c https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c @@ -144,36 +145,36 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0. https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda#def531a3ac77b7fb8c21d17bb5d0badb https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 -https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a +https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py311h6b1f9c4_0.conda#aa8c3009fd8903bebdcb22fbcb4c0dea https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 -https://conda.anaconda.org/conda-forge/noarch/click-8.3.2-pyhc90fa1f_0.conda#4d18bc3af7cfcea97bd817164672a08c +https://conda.anaconda.org/conda-forge/noarch/click-8.3.3-pyhc90fa1f_0.conda#2266262ce8a425ecb6523d765f79b303 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h7499c90_23.conda#3a937700705778ab8f5a6ce4f38eccca -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h91b0f8e_23.conda#12d093c7df954a01b396a748442bd5cb +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h6b77fdb_24.conda#491f76c26b2d032b21ba0b79cc324c4f +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h8a413ad_24.conda#ea3921760f33250a1c12926fce1660eb https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac -https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 +https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -183,7 +184,7 @@ https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_ https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac -https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.1-pyhd8ed1ab_0.conda#d8d30923ccee7525704599efd722aa16 +https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2026.2-pyhd8ed1ab_0.conda#f6ad7450fc21e00ecc23812baed6d2e4 https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda#3eeeeb9e4827ace8c0c1419c85d590ad https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 @@ -204,19 +205,19 @@ https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda#e1c https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.1-py311h3778330_0.conda#dd214022a8f01bc2ebed383dfdc8deea https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d -https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 +https://conda.anaconda.org/conda-forge/linux-64/glib-2.88.1-h5110415_0.conda#2ec5e3e179440179c28c974c8c3fe984 https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda#0ba6225c279baf7ea9473a62ea0ec9ae https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.3-default_h99862b1_1.conda#1cf5d6f2ae346ea959f223401764845c -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_1.conda#80daec8cf93185515ac7b5d359e3f929 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.4-default_h99862b1_0.conda#fe7972688e6e3dd9b97d1fcce2d88235 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda#9f6a8664f1fe752f79473eeb9bf33a60 @@ -225,7 +226,7 @@ https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f +https://conda.anaconda.org/conda-forge/noarch/wheel-0.47.0-pyhd8ed1ab_0.conda#d0e3b2f0030cf4fca58bde71d246e94c https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f @@ -233,7 +234,7 @@ https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.11-h29cf534_0.con https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.1.0-pyhd8ed1ab_0.conda#e3bffa82b874f8b9a2631bddb3869529 https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.5-pyhd8ed1ab_0.conda#4c8327180586e7b1cd8b6815fc8827f1 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda#d53ffc0edc8eabf4253508008493c5bc https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be @@ -242,9 +243,9 @@ https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.11-h6d08254_0.conda#971da16e7fc43161329213557688d315 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 @@ -255,7 +256,7 @@ https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.con https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc -https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h2f21a4e_2.conda#1a7670cc9bddc4310c7cd411d05a8e43 +https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py311h5d55412_3.conda#b6784a1d00abcf066925b91b71f887fc https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py311h7db5c69_1.conda#643f8cb35133eb1be4919fb953f0a25f https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 diff --git a/build_tools/github/debian_32bit_lock.txt b/build_tools/github/debian_32bit_lock.txt index b02d9a6e4243e..2791202438166 100644 --- a/build_tools/github/debian_32bit_lock.txt +++ b/build_tools/github/debian_32bit_lock.txt @@ -14,13 +14,13 @@ iniconfig==2.3.0 # via pytest joblib==1.5.3 # via -r build_tools/github/debian_32bit_requirements.txt -meson==1.11.0 +meson==1.11.1 # via meson-python meson-python==0.19.0 # via -r build_tools/github/debian_32bit_requirements.txt ninja==1.13.0 # via -r build_tools/github/debian_32bit_requirements.txt -packaging==26.1 +packaging==26.2 # via # meson-python # pyproject-metadata diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock index 751f1dd6399b3..a92191295d04b 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -7,16 +7,17 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.26.0-ha770c72_0.conda#cb93c6e226a7bed5557601846555153d -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_10.conda#590b5a14299d67b9669fe5eb1fdd4d3b https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 +https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_11.conda#4a1793b78e4309bbdb99bd033226f0d2 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.3-h4922eb0_0.conda#f7781cb22afa62ef27fd0b3300c53c86 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.4-h4922eb0_0.conda#fa2c5c7f8d5319ab9c9fcbbd04022abf +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_11.conda#c0004c583be9ac82ad2115bc08f3d77d https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 @@ -32,7 +33,7 @@ https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1.conda#72c8fd1af66bd67bf580645b426513ed https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -48,7 +49,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.co https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -86,13 +87,13 @@ https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b5 https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.1-h1cbb8d7_1.conda#9d978822b57bafe72ebd3f8b527bba71 +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.7.2-hc5a330e_1.conda#3f578c7d2b0bb52469340e4060d48d94 https://conda.anaconda.org/conda-forge/linux-64/sleef-3.9.0-ha0421bc_0.conda#e8a0b4f5e82ecacffaa5e805020473cb https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda#996583ea9c796e5b915f7d7580b51ea6 https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-hc87160b_0.conda#dde6a3e4fe6bb2ecd2a7050dd1e701fb +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-h692f434_1.conda#14260392d0b491c537b5e26e9a506fff https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca @@ -100,12 +101,12 @@ https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h6705ce6_0.conda#42c424ab163c576c7fb5981f7fb379cf https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 -https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h454ac66_1.conda#8ed82d90e6b1686f5e98f8b7825a15ef +https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h7d032f7_2.conda#b6e326fbe1e3948da50ec29cee0380db https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 @@ -121,9 +122,9 @@ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.con https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda#c3cc2864f82a944bc90a7beb4d3b0e88 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa @@ -140,10 +141,10 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_ https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h2d2dd48_2.conda#675ea6d90900350b1dcfa8231a5ea2dd https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-he9ea9c5_1.conda#8e77514673f5773b40ff8953583938b6 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 -https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.3.0-py314h680f03e_0.conda#a2ac7763a9ac75055b68f325d3255265 +https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.4.0-py314h680f03e_0.conda#b712198b257f378e9bd8cde277218296 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 @@ -151,28 +152,28 @@ https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.29.0-pyhd8ed1ab_0.conda#8fa8358d022a3a9bd101384a808044c6 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b -https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.4.0-py314h42812f9_0.conda#bf19183372b78e064d41f42c1a1846a1 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.4.0-pyhd8ed1ab_0.conda#2c11aa96ea85ced419de710c1c3a78ff +https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.5.0-py314h42812f9_0.conda#d92bd1c6aa279f0c2e9add8aa5a8c846 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac -https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 +https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/linux-64/playwright-1.59.1-h5585027_0.conda#3ec4a57c54725b9be3cad126ccbad2c0 @@ -203,13 +204,13 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cd https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_1.conda#80daec8cf93185515ac7b5d359e3f929 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 @@ -229,9 +230,9 @@ https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0- https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_10.conda#f010e1db3ddc8db985cfd4e04ed24b7b +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d -https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.58.0-pyhcf101f3_0.conda#3b886c49cf44aa133d0eb07e4d0cac89 +https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.59.0-pyhcf101f3_0.conda#313ba7b8e2a4fed359c935202853932c https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 @@ -239,38 +240,38 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3. https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_10.conda#568282798682e81eb59c592b8a0267ad +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-23.0.1-ha7f89c6_9_cpu.conda#b94c6431eadc98b61f4b9c62a338b3c6 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-24.0.0-ha7f89c6_0_cpu.conda#8aeb79715524b48267068fb0fd185956 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-23.0.1-h53684a4_9_cpu.conda#b3ba3597c481a636fc161185819cf6b1 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-24.0.0-h53684a4_0_cpu.conda#73e0aeaa603ff40128e75435a3c5ac77 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 -https://conda.anaconda.org/conda-forge/linux-64/libparquet-23.0.1-h7376487_9_cpu.conda#2dccf1b6cf9dba8857050740dbc0497e +https://conda.anaconda.org/conda-forge/linux-64/libparquet-24.0.0-h7376487_0_cpu.conda#c828cca50cd3a7c53d12ce8f0872c6ec https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h7058990_103.conda#2df90510834746b1f52c5299bc99a81f https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-23.0.1-h635bf11_9_cpu.conda#84cdfd12ec9a363b400f7d3850838ea3 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-24.0.0-h635bf11_0_cpu.conda#178d7e3f5c392e606ccd0aaff4331019 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py314hb4ffadd_0.conda#41ee6fe2a848876bc9f524c5a500b85b -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-23.0.1-py314h969be7f_0_cpu.conda#97c21b0d5952f4e0f80bb790df1a5c88 +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-24.0.0-py314h969be7f_0_cpu.conda#b066370d80ec7fca3c1d4028dc09164f https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h6018c46_103.conda#a3c40f317db763f9631d078d0fb2759e https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-23.0.1-h635bf11_9_cpu.conda#9c5282b7aaf2261d3dbe5a61d24d5337 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.8-py314h1194b4b_0.conda#b8683e6068099b69c10dbfcf7204203f +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-24.0.0-h635bf11_0_cpu.conda#dc226b80ae51753ce2bd8193dcc42a88 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.9-py314h1194b4b_0.conda#11a821746ad11e642fcc615c3d66aa44 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_103.conda#54ad123774a53ce33aa7e99b6e53b4a6 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-23.0.1-hb4dd7c2_9_cpu.conda#d5338f154126253750e8ccc539386b92 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.8-py314hdafbbf9_0.conda#8286e3966eac286d5ac7c7a4afbac812 -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-23.0.1-py314hdafbbf9_0.conda#860f29e99f5b5f15b0d6a21166588bab +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-24.0.0-hb4dd7c2_0_cpu.conda#cb5a9557a2ffa1b18b4e05621354c6bd +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.9-py314hdafbbf9_0.conda#2046de06d7f4149a29c5d0e2cc26d6dd +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-24.0.0-py314hdafbbf9_0.conda#6629041b133a9d65d68c4f2269432378 diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 0db3f02d98c4e..ab0353214a469 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -6,12 +6,12 @@ https://conda.anaconda.org/conda-forge/osx-64/mkl-include-2023.2.0-h694c41f_5050 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda#4173ac3b19ec0a4f400b4f782910368b -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda#627eca44e62e2b665eeec57a984a7f00 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 -https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.3-h19cb2f5_0.conda#212ddd7bd52988f751905114325b5c0b +https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.4-h19cb2f5_0.conda#4394b1ba4b9604ac4e1c5bdc74451279 https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 -https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.5-hcc62823_0.conda#1d6e71b8c73711e28ffe207acdc4e2f8 +https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.8.0-hcc62823_0.conda#d2e01f78c1daaeb4d2aa870125ebcd7e https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda#66a0dc7464927d0853b590b6f53ba3ea https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda#210a85a1119f97ea7887188d176db135 https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.4.1-ha1e9b39_0.conda#57cc1464d457d01ac78f5860b9ca1714 @@ -19,8 +19,8 @@ https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda#bec https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda#ec88ba8a245855935b871a7324373105 https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda#7bb6608cf1f83578587297a158a6630b https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda#30439ff30578e504ee5e0b390afc8c65 -https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.3-h0d3cbff_0.conda#fbc27eb49069842d5335776d600856ff -https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda#ced34dd9929f491ca6dab6a2927aff25 +https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.4-h0d3cbff_0.conda#fac1a640081b85688ead36a88c4d20ff +https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_0.conda#31b8740cf1b2588d4e61c81191004061 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda#47f1b8b4a76ebd0cd22bd7153e54a4dc https://conda.anaconda.org/conda-forge/osx-64/xorg-libxdmcp-1.1.5-h8616949_1.conda#435446d9d7db8e094d2c989766cfb146 @@ -55,14 +55,14 @@ https://conda.anaconda.org/conda-forge/osx-64/cython-3.2.4-py314hf0dd12f_0.conda https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.5.0-py314hd6e1bd6_0.conda#25a8718587d3d0d9114b25dfa93b864c -https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.18-h90db99b_0.conda#753acc10c7277f953f168890e5397c80 +https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.19-h5ea7634_0.conda#f05fc88b6b2480486c006a9bf04db0b7 https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.3-h694c41f_0.conda#63b822fcf984c891f0afab2eedfcfaf4 https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda#ca52daf58cea766656266c8771d8be81 https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h52bb76a_0.conda#46e628da6e796c948fa8ec9d6d10bda3 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 @@ -77,7 +77,7 @@ https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.1-py314h4f144dc_0.conda#773e3141f292d9698e706da094ada8c1 https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.5-py314h77fa6c7_0.conda#c5d3ea7d5f490c69a6af7c056624fca4 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.3-h694c41f_0.conda#6ab1403cc6cb284d56d0464f19251075 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda#34a9f67498721abcfef00178bcf4b190 @@ -101,6 +101,6 @@ https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.3.3-py314h22a2ed9_4.co https://conda.anaconda.org/conda-forge/osx-64/pandas-3.0.2-py314h99bb933_0.conda#84a0c511492546f0363360ad1e4e6510 https://conda.anaconda.org/conda-forge/osx-64/scipy-1.17.1-py314h5727af0_0.conda#adbed17bd17ac00193e6dce1f1a37781 https://conda.anaconda.org/conda-forge/osx-64/blas-2.120-mkl.conda#b041a7677a412f3d925d8208936cb1e2 -https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.8-py314hd47142c_0.conda#91d76a5937b47f7f0894857ce88feb9f +https://conda.anaconda.org/conda-forge/osx-64/matplotlib-base-3.10.9-py314h7c1ad30_0.conda#9ab3835bd11afa0a9571ade6a875b5ce https://conda.anaconda.org/conda-forge/osx-64/pyamg-5.3.0-py314h81027db_1.conda#47390f4299f43bcdae539d454178596e -https://conda.anaconda.org/conda-forge/osx-64/matplotlib-3.10.8-py314hee6578b_0.conda#7fdf446de012e1750bf465b76412928d +https://conda.anaconda.org/conda-forge/osx-64/matplotlib-3.10.9-py314hee6578b_0.conda#4cfadc239dd7d8ca653048e041f70cd0 diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock index 332199c46f263..f62613232b922 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock @@ -9,12 +9,12 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539 https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_7.conda#5f0ebbfea12d8e5bddff157e271fdb2f https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda#620b85a3f45526a8bc4d23fd78fc22f0 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa -https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.3-h55c6f16_0.conda#acbb3f547c4aae16b19e417db0c6e5ed +https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.4-h55c6f16_0.conda#448a1af83a9205655ee1cf48d3875ca3 https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c -https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.5-hf6b4638_0.conda#a32123f93e168eaa4080d87b0fb5da8a +https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda#65466e82c09e888ca7560c11a97d5450 https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda#43c04d9cb46ef176bb2a4c77e324d599 https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda#4d5a7445f0b25b6a3ddbb56e790f5251 https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.4.1-h84a0fba_0.conda#b8a7544c83a67258b0e8592ec6a5d322 @@ -23,8 +23,8 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda#c0d87c3c8e075daf1daf6c31b53e8083 https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda#e5e7d467f80da752be17796b87fe6385 https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda#bc5a5721b6439f2f62a84f2548136082 -https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.3-hc7d1edf_0.conda#086b00b77f5f0f7ef5c2a99855650df4 -https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda#068d497125e4bf8a66bf707254fff5ae +https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.4-hc7d1edf_0.conda#46d04a647df7a4525e487d88068d19ef +https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda#343d10ed5b44030a2f67193905aea159 https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda#415816daf82e0b23a736a069a75e9da7 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda#78b548eed8227a689f93775d5d23ae09 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxdmcp-1.1.5-hc919400_1.conda#9d1299ace1924aa8f4e0bc8e71dd0cf7 @@ -70,21 +70,21 @@ https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4 https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.2.4-py314hc6117b3_0.conda#1289de88f884ac89144949cb97ccabe7 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.29.0-pyhd8ed1ab_0.conda#8fa8358d022a3a9bd101384a808044c6 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.3.0-pyhd8ed1ab_0.conda#c18d2ba7577cdc618a20d45f1e31d14b +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.4.0-pyhd8ed1ab_0.conda#2c11aa96ea85ced419de710c1c3a78ff https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.5.0-py314hf8a3a22_0.conda#eb1465d8a644ef290d18fb86af6e9bc4 -https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.18-hdfa7624_0.conda#6631a7bd2335bb9699b1dbc234b19784 +https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.19-hdfa7624_0.conda#57baad99764cf6057227e50b11e2ec5b https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.3-hce30654_0.conda#f73b109d49568d5d1dda43bb147ae37f https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda#c4a6f7989cffb0544bfd9207b6789971 https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py314h6e9b3f0_1.conda#d33c0a15882b70255abdd54711b06a45 -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.4.0-h169892a_0.conda#2845c3a1d0d8da1db92aba8323892475 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hd9e9057_0.conda#4b5d3a91320976eec71678fad1e3569b -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 @@ -101,13 +101,13 @@ https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py314h6c2aa35_0.conda#4fffb3ba871bb05f34ffb705534dfef5 https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.5-py314h6e9b3f0_0.conda#cdbafe4a3e605024e7372c9580f9d734 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.0-pyh7db6752_0.conda#049f68f9c90f00069c748cd6fb7bfb55 +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.3-hce30654_0.conda#6dcc75ba2e04c555e881b72793d3282f https://conda.anaconda.org/conda-forge/osx-arm64/gmpy2-2.3.0-py314hf9f5e1b_1.conda#036584b863246f278f4057327c36a94d https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_4.conda#eaf3d06e3a8a10dee7565e8d76ae618d -https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_8.conda#445fc95210a8e15e8b5f9f93782e3f80 +https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_9.conda#ddb70ebdcbf3a44bddc2657a51faf490 https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda#26981599908ed2205366e8fc91b37fc6 https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.2.0-py314hab283cf_0.conda#adf49537da0e0c34cf735e71fe579506 @@ -115,7 +115,7 @@ https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda# https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_8.conda#06c1a0f7eb6c393e16cc99e280784b36 +https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_9.conda#5a77d772c22448f6ab340fbfff55db48 https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_4.conda#22eb76f8d98f4d3b8319d40bda9174de https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.32-openmp_he657e61_0.conda#3a1111a4b6626abebe8b978bb5a323bf https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df @@ -142,19 +142,19 @@ https://conda.anaconda.org/conda-forge/osx-arm64/pandas-3.0.2-py314he609de1_0.co https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-2.10.0-cpu_generic_py314_he36690f_3.conda#51da3d684a7d90b35adfd742fb551cc4 https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.1-py314hfc1f868_0.conda#7806ce54b78b0b11517b465a3398e910 https://conda.anaconda.org/conda-forge/osx-arm64/blas-2.306-openblas.conda#4cd635f3755993f4658959c2b3e1f2ef -https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.8-py314hd63e3f0_0.conda#c84152e510d41378b8758826655b6ed7 +https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-base-3.10.9-py314hc042b31_0.conda#3252e58ac5ade3ba2dacd5dacfa6e7b8 https://conda.anaconda.org/conda-forge/osx-arm64/pyamg-5.3.0-py314h95ce61a_1.conda#44282cc9330eb206f808c4f5be281fe2 https://conda.anaconda.org/conda-forge/osx-arm64/pytorch-cpu-2.10.0-cpu_generic_hcc7c195_3.conda#e7ebf31f2c197adaba9bbf84a40dffd9 -https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.8-py314he55896b_0.conda#ad9a3f773f13989b92b41c0eabed5a38 +https://conda.anaconda.org/conda-forge/osx-arm64/matplotlib-3.10.9-py314he55896b_0.conda#553de53f80d4eeef68ff2b2ec225ed5f https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda#148516e0c9edf4e9331a4d53ae806a9b -https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_8.conda#ededa5c4f241dad0a7ebc99bb11e5dbb +https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_9.conda#20056c993a8c9df01e04a0e165579ec1 https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda#8d99c82e0f5fed6cc36fcf66a11e03f0 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_impl_osx-arm64-14.3.0-h6d03799_1.conda#1e9ec88ecc684d92644a45c6df2399d0 https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda#39451684370ae65667fa5c11222e43f7 -https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_8.conda#6bee2e04d81e5023286770ef6b56e146 +https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_9.conda#2aec2e39be3b4999bda2a3e5bd4cd2e6 https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_31.conda#6645630920c0980a33f055a49fbdb88e -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_8.conda#c5d2fcbd218812e18feb9f60a04359e3 -https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_hc995acf_8.conda#5ec2b8416b3a6af3650f9bb3984ba439 +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_9.conda#8b7425e84f940861653c919142435bde +https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_hc995acf_9.conda#9a1ac8e5124fcc201adb20a103d51cc6 https://conda.anaconda.org/conda-forge/osx-arm64/gfortran_osx-arm64-14.3.0-h3c33bd0_0.conda#8db8c0061c0f3701444b7b9cc9966511 https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_31.conda#bd6926e81dc196064373b614af3bc9ff https://conda.anaconda.org/conda-forge/osx-arm64/gfortran-14.3.0-h3ef1dbf_0.conda#e148e0bc9bbc90b6325a479a5501786d diff --git a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock index 5aafd911b1ce6..fdf3b63ff8821 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -4,7 +4,7 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de @@ -12,13 +12,13 @@ https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 @@ -31,7 +31,7 @@ https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp31 https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 -# pip certifi @ https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl#sha256=027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa +# pip certifi @ https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl#sha256=3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a # pip charset-normalizer @ https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd # pip coverage @ https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3 # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 @@ -39,16 +39,16 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip fonttools @ https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1 -# pip idna @ https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl#sha256=771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea +# pip idna @ https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl#sha256=892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 # pip imagesize @ https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl#sha256=5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip joblib @ https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl#sha256=5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 # pip kiwisolver @ https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 -# pip meson @ https://files.pythonhosted.org/packages/08/84/1ae2022a3562ac011c80c090e387a07e189d077b01fe58a266759b8fc2ff/meson-1.11.0-py3-none-any.whl#sha256=9774eb62bbf2cb8043aa3feb771c09b510d112c0c382221e29aea7453ecce753 +# pip meson @ https://files.pythonhosted.org/packages/5e/cd/f3a881ff5e601d6bbeff63b38ee2362e1167c47d9cde03eddf8d71a4ffb0/meson-1.11.1-py3-none-any.whl#sha256=9b3a023657e393dbc5335b95c561337d49b7a458f5541e47ec44f2cc566e0d80 # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip numpy @ https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83 -# pip packaging @ https://files.pythonhosted.org/packages/7a/c2/920ef838e2f0028c8262f16101ec09ebd5969864e5a64c4c05fad0617c56/packaging-26.1-py3-none-any.whl#sha256=5d9c0669c6285e491e0ced2eee587eaf67b670d94a19e94e3984a481aba6802f +# pip packaging @ https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl#sha256=5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e # pip pillow @ https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3 # pip pluggy @ https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl#sha256=e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 # pip pygments @ https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl#sha256=81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176 @@ -73,7 +73,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip requests @ https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl#sha256=4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a # pip scipy @ https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464 # pip lightgbm @ https://files.pythonhosted.org/packages/42/86/dabda8fbcb1b00bcfb0003c3776e8ade1aa7b413dff0a2c08f457dace22f/lightgbm-4.6.0-py3-none-manylinux_2_28_x86_64.whl#sha256=cb19b5afea55b5b61cbb2131095f50538bd608a00655f23ad5d25ae3e3bf1c8d -# pip matplotlib @ https://files.pythonhosted.org/packages/75/97/a471f1c3eb1fd6f6c24a31a5858f443891d5127e63a7788678d14e249aea/matplotlib-3.10.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=a0a7f52498f72f13d4a25ea70f35f4cb60642b466cbb0a9be951b5bc3f45a486 +# pip matplotlib @ https://files.pythonhosted.org/packages/8a/17/4402d0d14ccf1dfc70932600b68097fbbf9c898a4871d2cbbe79c7801a32/matplotlib-3.10.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=8f3bcac1ca5ed000a6f4337d47ba67dfddf37ed6a46c15fd7f014997f7bf865f # pip meson-python @ https://files.pythonhosted.org/packages/16/7f/d1b0c65b267a1463d752b324f11d3470e30889daefc4b9ec83029bfa30b5/meson_python-0.19.0-py3-none-any.whl#sha256=67b5906c37404396d23c195e12c8825506074460d4a2e7083266b845d14f0298 # pip pandas @ https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e # pip pyamg @ https://files.pythonhosted.org/packages/63/f3/c13ae1422434baeefe4d4f306a1cc77f024fe96d2abab3c212cfa1bf3ff8/pyamg-5.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl#sha256=5cc223c66a7aca06fba898eb5e8ede6bb7974a9ddf7b8a98f56143c829e63631 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 037fca9f12d56..73c2a3984e927 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -12,7 +12,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.co https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/linux-aarch64/_openmp_mutex-4.5-20_gnu.conda#468fd3bb9e1f671d36c2cbc677e56f1d -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-aarch64/libegl-1.7.0-hd24410f_2.conda#cf105bce884e4ef8c8ccdca9fe6695e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2.conda#cf9d12bfab305e48d095a4c79002c922 @@ -25,7 +25,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.cond https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda#e7df0aab10b9cbb73ab2a467ebfaf8c7 https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d5cf_1.conda#8ec1d03f3000108899d1799d9964f281 https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda#a9138815598fe6b91a1d6782ca657b0c -https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.7.5-hfae3067_0.conda#05d1e0b30acd816a192c03dc6e164f4d +https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.8.0-hfae3067_0.conda#3bacd6171f0a3f8fddd06c3d5ae01955 https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda#2f364feefb6a7c00423e80dcb12db62a https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda#4feebd0fbf61075a1a9c2e9b3936c257 https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda#574d88ce3348331e962cfa5ed451b247 @@ -39,7 +39,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.0-h022381a_0 https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42-h1022ec0_0.conda#a0b5de740d01c390bdbb46d7503c9fab https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af -https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.5-ha32ae93_3.conda#182afabe009dc78d8b73100255ee6868 +https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.6-hf8d1292_0.conda#b2a43456aa56fe80c2477a5094899eff https://conda.anaconda.org/conda-forge/linux-aarch64/openssl-3.6.2-h546c87b_0.conda#3b129669089e4d6a5c6871dbb4669b99 https://conda.anaconda.org/conda-forge/linux-aarch64/pthread-stubs-0.4-h86ecc28_1002.conda#bb5a90c93e3bac3d5690acf76b4a6386 https://conda.anaconda.org/conda-forge/linux-aarch64/tk-8.6.13-noxft_h0dc03b3_103.conda#7fc6affb9b01e567d2ef1d05b84aa6ed @@ -96,16 +96,16 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_ https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.3-h8af1aa0_0.conda#f11edf8adf0d119148b97f745548390d https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.5.0-py311h229e7f7_0.conda#aeade47300d466d9d6ba01daaca31a86 -https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.18-h9d5b58d_0.conda#bb960f01525b5e001608afef9d47b79c +https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.19-h9d5b58d_0.conda#6bc596d689e559787079968b885e75d8 https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-6_haddc8a3_openblas.conda#652bb20bb4618cacd11e17ae070f47ce https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h4f2b762_6.conda#67828c963b17db7dc989fe5d509ef04a https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.3-h869d058_0.conda#2cffef27cb2eb9ed1e315a1e269d4335 -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.32-pthreads_h3a8cbd8_0.conda#62e1383bcaf8f5244d2598bbda509e3b https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 @@ -125,20 +125,20 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86e https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.5-py311h2dad8b0_0.conda#d3bcad889948820993ded0b13c2ae906 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.62.0-py311h164a683_0.conda#d3ef6350930100e30aaf0ecdf4e4dd3a +https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.62.1-py311h164a683_0.conda#247d8664e397d43269288370ffe81ac3 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-6_hd72aa62_openblas.conda#939e300b110db241a96a1bed438c315b https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda#0d00176464ebb25af83d40736a2cd3bb https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-devel-1.7.0-hd24410f_2.conda#1f9ddbb175a63401662d1c6222cef6ff https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-6_h88aeb00_openblas.conda#e23a27b52fb320687239e2c5ae4d7540 -https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.3-hfd2ba90_0.conda#c2e1304da2e44348df892c1425bf294d +https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.4-hfd2ba90_0.conda#6985556a15653f1df6639744cabef3f9 https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.13-h2fb54aa_0.conda#67eea19865a3463f75ca0d3a1d096350 https://conda.anaconda.org/conda-forge/linux-aarch64/pillow-12.2.0-py311h8e17b9e_0.conda#c2e33eff9ea2d1501b83d938d9d4334d https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f +https://conda.anaconda.org/conda-forge/noarch/wheel-0.47.0-pyhd8ed1ab_0.conda#d0e3b2f0030cf4fca58bde71d246e94c https://conda.anaconda.org/conda-forge/linux-aarch64/xcb-util-cursor-0.1.6-he30d5cf_0.conda#8b70063c86f7f9a0b045e78d2d9971f7 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcomposite-0.4.7-he30d5cf_0.conda#9c639c1abdbfe6759c5beb2c1db4bc13 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxcursor-1.2.3-h86ecc28_0.conda#f2054759c2203d12d0007005e1f1296d @@ -146,8 +146,8 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxdamage-1.1.6-h86ec https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0.conda#eeee3bdb31c6acde2b81ad1b8c287087 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda#1f64c613f0b8d67e9fb0e165d898fb6b https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.7-he30d5cf_0.conda#b15ca02584678f38df6e114c32f93959 -https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-14.1.0-h1134a53_0.conda#5461f9f6ba3c30ee46e014fc127c8ac0 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.3-default_h94a09a5_1.conda#59bdf54337dcba90b3910baaca02388f +https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-14.2.0-h1134a53_0.conda#1775defbef30aa990498e753a948cb18 +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.4-default_h94a09a5_0.conda#e15885f06e02c0d6b7e1fc3bc8a97efb https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-devel-1.7.0-hd24410f_2.conda#5d8323dff6a93596fb6f985cf6e8521a https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-6_hb558247_openblas.conda#12da32239ec4cc63d4f94d83b8425947 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.3-h7d4fc67_0.conda#7eb18b198b1d35da9352062c69c4ee64 @@ -164,7 +164,7 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-aarch64/scipy-1.17.1-py311h399493a_0.conda#be28b3d39c6942f89652b505e85ae3d6 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-2.306-openblas.conda#cc7cac46a53a5c76f20439cb298d10a2 -https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.8-py311hb9c6b48_0.conda#4c9c9538c5a0a581b2dac04e2ea8c305 +https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-base-3.10.9-py311hb9c6b48_0.conda#a89049617b540aa442cdc8db9a2ae704 https://conda.anaconda.org/conda-forge/linux-aarch64/qt6-main-6.11.0-pl5321h598db47_4.conda#e93276397240a46199cc7ddee1cfeb2d https://conda.anaconda.org/conda-forge/linux-aarch64/pyside6-6.11.0-py311hb02cd75_2.conda#0f363faaee54d4d8164b762f1afc336f -https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.8-py311hfecb2dc_0.conda#3920b856b59a909812f1913b96adaad8 +https://conda.anaconda.org/conda-forge/linux-aarch64/matplotlib-3.10.9-py311hfecb2dc_0.conda#7b312514c56cac422f44b2b92c238ee4 diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 0654556d3487f..487ede81c72b7 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -8,11 +8,11 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77 https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.3-h4922eb0_0.conda#f7781cb22afa62ef27fd0b3300c53c86 +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.4-h4922eb0_0.conda#fa2c5c7f8d5319ab9c9fcbbd04022abf https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 @@ -28,7 +28,7 @@ https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda# https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499cd8e2d4358986dbe3b30e8fe1bf6a https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -46,7 +46,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.con https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -98,7 +98,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.co https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda#bb26456332b07f68bf3b7622ed71c0da +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h6705ce6_0.conda#42c424ab163c576c7fb5981f7fb379cf https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 @@ -121,10 +121,10 @@ https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.con https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda#b52b769cd13f7adaa6ccdc68ef801709 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.88.1-h040f060_0.conda#55e7cea32f68a173635bcd4ea3d6e02c +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda#d50608c443a30c341c24277d28290f76 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda#c3cc2864f82a944bc90a7beb4d3b0e88 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 @@ -144,7 +144,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.7.10-h9ab9c9b_2.con https://conda.anaconda.org/conda-forge/linux-64/brotli-1.0.9-h166bdaf_9.conda#4601544b4982ba1861fa9b9c607b2c06 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.0.9-py311ha362b79_9.conda#ced5340f5dc6cff43a80deac8d0e398f https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 @@ -152,19 +152,19 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.con https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac -https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 +https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.3-hf7376ad_0.conda#aeb186f7165bf287495a267fa8ff4129 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -190,20 +190,20 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.8.13-hd4f18eb_5.con https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py311h3778330_0.conda#e32c4e7639b1c1b5680fabdaa6081e56 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.0-py311h3778330_0.conda#bd4aa764c1b2f877aff5049f26cbffde -https://conda.anaconda.org/conda-forge/linux-64/glib-2.86.4-h5192d8d_1.conda#61272bde04aeccf919351b92fbb96a53 +https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.1-py311h3778330_0.conda#dd214022a8f01bc2ebed383dfdc8deea +https://conda.anaconda.org/conda-forge/linux-64/glib-2.88.1-h5110415_0.conda#2ec5e3e179440179c28c974c8c3fe984 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.1.0-h6083320_0.conda#ca8a94b613db5d805c3d2498a7c30997 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.3-default_h99862b1_1.conda#1cf5d6f2ae346ea959f223401764845c -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.3-default_h746c552_1.conda#80daec8cf93185515ac7b5d359e3f929 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.4-default_h99862b1_0.conda#fe7972688e6e3dd9b97d1fcce2d88235 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad -https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f +https://conda.anaconda.org/conda-forge/noarch/wheel-0.47.0-pyhd8ed1ab_0.conda#d0e3b2f0030cf4fca58bde71d246e94c https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.11-h29cf534_0.conda#1e0e854b77451ac918b4a68f28932b1d https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae @@ -226,7 +226,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h7b9373a_16. https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h0c412b5_8.conda#80e27e7982af989ebc2e0f0d57c75ea7 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 @@ -234,5 +234,5 @@ https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1 https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.0-py311h39c9aba_9_cpu.conda#c35fe329bcc51a1a3a254c990ba8f738 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b -# pip pytz @ https://files.pythonhosted.org/packages/10/99/781fe0c827be2742bcc775efefccb3b048a3a9c6ce9aec0cbf4a101677e5/pytz-2026.1.post1-py2.py3-none-any.whl#sha256=f2fd16142fda348286a75e1a524be810bb05d444e5a081f37f7affc635035f7a +# pip pytz @ https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl#sha256=04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 # pip pandas @ https://files.pythonhosted.org/packages/fa/fe/c81ad3991f2c6aeacf01973f1d37b1dc76c0682f312f104741602a9557f1/pandas-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=e252a9e49b233ff96e2815c67c29702ac3a062098d80a170c506dff3470fd060 diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index 8e96fd6907e46..e2de835e0dca0 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -4,7 +4,7 @@ @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda#4492fd26db29495f0ba23f146cd5638d +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de @@ -13,7 +13,7 @@ https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_ https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 -https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda#49f570f3bc4c874a06ea69b7225753af +https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 @@ -24,7 +24,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#e https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 -https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda#47e340acb35de30501a76c7c799c41d7 +https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda#b3c17d95b5a10c6e64a21fa17573e70e https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab @@ -46,16 +46,16 @@ https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.co https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.18-h0c24ade_0.conda#6f2e2c8f58160147c4d1c6f4c14cbac4 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.32-pthreads_h6ec200e_0.conda#2e9cf6ff9a29b98a4faf627f2eb2cdb7 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 -https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.3.0-py311h6b1f9c4_0.conda#adda5ef2a74c9bdb338ff8a51192898a +https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py311h6b1f9c4_0.conda#aa8c3009fd8903bebdcb22fbcb4c0dea https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 -https://conda.anaconda.org/conda-forge/noarch/certifi-2026.2.25-pyhd8ed1ab_0.conda#765c4d97e877cdbbb88ff33152b86125 +https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py311h0daaf2c_0.conda#e9173db94f5c77b3e854a9c76c0568a5 @@ -63,14 +63,14 @@ https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac -https://conda.anaconda.org/conda-forge/noarch/idna-3.11-pyhd8ed1ab_0.conda#53abe63df7e10a6ba605dc5f9f961d36 +https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 @@ -91,7 +91,7 @@ https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_h6ae95b6_ope https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py311h2e04523_0.conda#cfc8f864dea571677095ebae8e6f0c07 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f +https://conda.anaconda.org/conda-forge/noarch/wheel-0.47.0-pyhd8ed1ab_0.conda#d0e3b2f0030cf4fca58bde71d246e94c https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_h1ea3ea9_openblas.conda#064f82e2cd0146b28a0bda3ca9b6fb7e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py311h8032f78_0.conda#138e5d98884407fcc8ccc6088574b1c7 @@ -102,7 +102,7 @@ https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-openblas.conda#81122e5749efe4c34c07471ad866eab1 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_0.conda#10afbb4dbf06ff959ad25a92ccee6e59 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda#16e3f039c0aa6446513e94ab18a8784b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda#910f28a05c178feba832f842155cbfff diff --git a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock index e139821dbeb3d..cfbcc1e8ffcef 100644 --- a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock @@ -9,7 +9,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.co https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda#71b24316859acd00bdb8b38f5e2ce328 -https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda#f001e6e220355b7f87403a4d0e5bf1ca +https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-h4c7d964_0.conda#56fb2c6c73efc627b40c77d14caecfba https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda#8a86073cf3b343b87d03f41790d8b4e5 https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda#242d9f25d2ae60c76b38a5e42858e51d @@ -25,7 +25,7 @@ https://conda.anaconda.org/conda-forge/win-64/icu-78.3-h637d24d_0.conda#0097b248 https://conda.anaconda.org/conda-forge/win-64/lerc-4.1.0-hd936e49_0.conda#54b231d595bc1ff9bff668dd443ee012 https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.conda#444b0a45bbd1cb24f82eedb56721b9c4 https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e -https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.5-hac47afa_0.conda#bfb43f52f13b7c56e7677aa7a8efdf0c +https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda#264e350e035092b5135a2147c238aec4 https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda#720b39f5ec0610457b725eb3f396219a https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda#b085746891cca3bd2704a450a7b4b5ce https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#64571d1dd6cdcfa25d0664a5950fdaa2 @@ -64,16 +64,16 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.5.0-py311h275cad7_0.conda#e50d15677f2673c114f18d60c88d9196 https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-6_h2a8eebe_openblas.conda#56ab25cf3cbce9e3a809e3e89739b5a8 -https://conda.anaconda.org/conda-forge/win-64/libclang13-22.1.3-default_ha2db4b5_0.conda#deb5befa374fcbc9ec2534c8467b0a6b +https://conda.anaconda.org/conda-forge/win-64/libclang13-22.1.4-default_ha2db4b5_0.conda#8759fc24d708cc4af95af5d86f5441d1 https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_0.conda#f9975a0177ee6cdda10c86d1db1186b0 -https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.4-h0c9aed9_1.conda#0329a7e92c8c8b61fcaaf7ad44642a96 +https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.1-h822be2e_0.conda#76f642848b6cac29977dbb8b66d4f29c https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-6_hd232482_openblas.conda#06d2ad5bf21e9b86c46783833b2e3c42 https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_0.conda#95591ca5671d2213f5b2d5aa7818420d -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.0-pyhcf101f3_0.conda#14169516e99ac241295da3dc81dab218 +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.1-pyhc364b38_0.conda#b8ae38639d323d808da535fb71e31be8 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 @@ -89,7 +89,7 @@ https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda#bc58 https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.5-py311h3f79411_0.conda#32eaff69a4a2426c01748784090a5e76 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/win-64/lcms2-2.18-hf2c6c5f_0.conda#b6c68d6b829b044cd17a41e0a8a23ca1 +https://conda.anaconda.org/conda-forge/win-64/lcms2-2.19-hf2c6c5f_0.conda#cc37ca38374ac2a5dbe11f9abb10110f https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_0.conda#d9f70dd06674e26b6d5a657ddd22b568 https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-6_hbb0e6ff_openblas.conda#7111f949f68a554498655d268b5fa7a5 https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 @@ -97,11 +97,11 @@ https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.3-py311h65cb7f3_0.conda# https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.4-h0e57b4f_0.conda#e723ab7cc2794c954e1b22fde51c16e4 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/wheel-0.46.3-pyhd8ed1ab_0.conda#bdbd7385b4a67025ac2dba4ef8cb6a8f +https://conda.anaconda.org/conda-forge/noarch/wheel-0.47.0-pyhd8ed1ab_0.conda#d0e3b2f0030cf4fca58bde71d246e94c https://conda.anaconda.org/conda-forge/win-64/blas-devel-3.11.0-6_ha590de0_openblas.conda#085478f89f9e91d9e2cf6e81b9f4665b https://conda.anaconda.org/conda-forge/win-64/contourpy-1.3.3-py311h275cad7_4.conda#9fb1f375c704c5287c97c60f6a88d137 https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda#a0b1b87e871011ca3b783bbf410bc39f -https://conda.anaconda.org/conda-forge/win-64/fonttools-4.62.0-py311h3f79411_0.conda#5abfb5569386a6a7e8f6f88d4845af10 +https://conda.anaconda.org/conda-forge/win-64/fonttools-4.62.1-py311h3f79411_0.conda#2963b1774c916733613de34d7e3e0457 https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_0.conda#507b36518b5a595edda64066c820a6ef https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/win-64/pillow-12.2.0-py311h17b8079_0.conda#80382ea49ddde54350b5ca5135be2838 @@ -110,10 +110,10 @@ https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.1-py311h9c22a71_0.conda#24047b0ff1fa264427c456e4c7f68283 https://conda.anaconda.org/conda-forge/win-64/blas-2.306-openblas.conda#8fe2bc7bfe72359526e4e94b018853a3 https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda#52ea1beba35b69852d210242dd20f97d -https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.8-py311h1675fdf_0.conda#57671b98b86015c8b28551cdb09ee294 +https://conda.anaconda.org/conda-forge/win-64/matplotlib-base-3.10.9-py311h1675fdf_0.conda#0579f9b8de16d67c61c265cfbd283cf0 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/win-64/harfbuzz-14.1.0-h5a1b470_0.conda#d261a3229a9cdded071fa5049c327944 +https://conda.anaconda.org/conda-forge/win-64/harfbuzz-14.2.0-h5a1b470_0.conda#b8862b83b5c899f5b65bcba0298b8478 https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.11.0-pl5321hfcac499_4.conda#1aca2896ea9f0d1f0761a7b278f670a0 https://conda.anaconda.org/conda-forge/win-64/pyside6-6.11.0-py311he824864_2.conda#30aa3757b558ffc51d662b73531dbb1f -https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.8-py311h1ea47a8_0.conda#64fe28aa2486e41918239d385336e88e +https://conda.anaconda.org/conda-forge/win-64/matplotlib-3.10.9-py311h1ea47a8_0.conda#007ed4b4117621a19e545d62f47339c4 diff --git a/build_tools/github/ubuntu_atlas_lock.txt b/build_tools/github/ubuntu_atlas_lock.txt index 477f214473f08..52db7c125e0ef 100644 --- a/build_tools/github/ubuntu_atlas_lock.txt +++ b/build_tools/github/ubuntu_atlas_lock.txt @@ -12,13 +12,13 @@ iniconfig==2.3.0 # via pytest joblib==1.3.0 # via -r build_tools/github/ubuntu_atlas_requirements.txt -meson==1.11.0 +meson==1.11.1 # via meson-python meson-python==0.19.0 # via -r build_tools/github/ubuntu_atlas_requirements.txt ninja==1.13.0 # via -r build_tools/github/ubuntu_atlas_requirements.txt -packaging==26.1 +packaging==26.2 # via # meson-python # pyproject-metadata From a63dda2b52f5d1ceac1d317a9f96aff4c3365c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dea=20Mar=C3=ADa=20L=C3=A9on?= <deamarialeon@gmail.com> Date: Mon, 4 May 2026 18:27:17 +0200 Subject: [PATCH 427/462] FIX: `TransformerTargetRegressor` HTML display (#33850) --- sklearn/compose/_target.py | 13 +++++++++++++ .../utils/_repr_html/tests/test_estimator.py | 19 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/sklearn/compose/_target.py b/sklearn/compose/_target.py index 38ba0dce1adeb..2303c363cf534 100644 --- a/sklearn/compose/_target.py +++ b/sklearn/compose/_target.py @@ -17,6 +17,7 @@ process_routing, ) from sklearn.utils._param_validation import HasMethods +from sklearn.utils._repr_html.estimator import _VisualBlock from sklearn.utils._tags import get_tags from sklearn.utils.validation import check_is_fitted @@ -395,3 +396,15 @@ def _get_regressor(self, get_clone=False): return LinearRegression() return clone(self.regressor) if get_clone else self.regressor + + def _sk_visual_block_(self): + regressor = ( + self.regressor_ if hasattr(self, "regressor_") else self._get_regressor() + ) + return _VisualBlock( + "serial", + [regressor], + names=[f"regressor: {regressor.__class__.__name__}"], + name_details=[str(regressor)], + dash_wrapped=True, + ) diff --git a/sklearn/utils/_repr_html/tests/test_estimator.py b/sklearn/utils/_repr_html/tests/test_estimator.py index d2dff4ec7bb9a..2684a6a589bd0 100644 --- a/sklearn/utils/_repr_html/tests/test_estimator.py +++ b/sklearn/utils/_repr_html/tests/test_estimator.py @@ -13,7 +13,11 @@ from sklearn import config_context from sklearn.base import BaseEstimator, clone from sklearn.cluster import AgglomerativeClustering, Birch -from sklearn.compose import ColumnTransformer, make_column_transformer +from sklearn.compose import ( + ColumnTransformer, + TransformedTargetRegressor, + make_column_transformer, +) from sklearn.datasets import load_iris from sklearn.decomposition import PCA, TruncatedSVD from sklearn.ensemble import StackingClassifier, StackingRegressor, VotingClassifier @@ -21,7 +25,7 @@ from sklearn.gaussian_process.kernels import ExpSineSquared from sklearn.impute import SimpleImputer from sklearn.kernel_ridge import KernelRidge -from sklearn.linear_model import LogisticRegression +from sklearn.linear_model import LinearRegression, LogisticRegression from sklearn.model_selection import RandomizedSearchCV from sklearn.multiclass import OneVsOneClassifier from sklearn.neural_network import MLPClassifier @@ -142,6 +146,17 @@ def test_get_visual_block_column_transformer(): assert est_html_info.name_details == (["num1", "num2"], [0, 3]) +def test_get_visual_block_transformed_target_regressor(): + X = np.array([[0], [1], [2], [3], [4]]) + y = np.array([1.0, 7.3, 54.5, 403.5]) + tt = TransformedTargetRegressor(func=np.log, inverse_func=np.exp) + est_html_info = _get_visual_block(tt) + assert est_html_info.kind == "serial" + assert isinstance(est_html_info.estimators[0], LinearRegression) + assert est_html_info.names == ["regressor: LinearRegression"] + assert est_html_info.name_details == ["LinearRegression()"] + + def test_estimator_html_repr_an_empty_pipeline(): """Check that the representation of an empty Pipeline does not fail. From 9be86a2ba065cc169302f08bad9cca8a543a1992 Mon Sep 17 00:00:00 2001 From: James Dean <24254612+AcylSilane@users.noreply.github.com> Date: Mon, 4 May 2026 13:28:40 -0400 Subject: [PATCH 428/462] ENH Improve error messages for missing columns in indexing helpers (#33628) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- sklearn/inspection/tests/test_partial_dependence.py | 2 +- sklearn/utils/_indexing.py | 10 ++++++++-- sklearn/utils/tests/test_indexing.py | 7 +++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/sklearn/inspection/tests/test_partial_dependence.py b/sklearn/inspection/tests/test_partial_dependence.py index dc5b949ab97ef..119c6899c0ed3 100644 --- a/sklearn/inspection/tests/test_partial_dependence.py +++ b/sklearn/inspection/tests/test_partial_dependence.py @@ -640,7 +640,7 @@ def test_partial_dependence_unknown_feature_string(estimator): estimator = clone(estimator).fit(df, y) features = ["random"] - err_msg = "A given column is not a column of the dataframe" + err_msg = "Some column names are not columns of the dataframe" with pytest.raises(ValueError, match=err_msg): partial_dependence(estimator, df, features) diff --git a/sklearn/utils/_indexing.py b/sklearn/utils/_indexing.py index 6d8a4fbf9e92b..05d5f4a0ff0d3 100644 --- a/sklearn/utils/_indexing.py +++ b/sklearn/utils/_indexing.py @@ -487,7 +487,10 @@ def _get_column_indices(X, key): column_indices.append(col_idx) except KeyError as e: - raise ValueError("A given column is not a column of the dataframe") from e + missing = {*columns} - {*all_columns} + raise ValueError( + f"Some column names are not columns of the dataframe: {missing}" + ) from e return column_indices @@ -519,7 +522,10 @@ def _get_column_indices_interchange_and_polars(n_columns, column_names, key, key try: return [column_names.index(col) for col in selected_columns] except ValueError as e: - raise ValueError("A given column is not a column of the dataframe") from e + missing = {*selected_columns} - {*column_names} + raise ValueError( + f"Some column names are not columns of the dataframe: {missing}" + ) from e @validate_params( diff --git a/sklearn/utils/tests/test_indexing.py b/sklearn/utils/tests/test_indexing.py index 088b37956a9e9..673a80deda90b 100644 --- a/sklearn/utils/tests/test_indexing.py +++ b/sklearn/utils/tests/test_indexing.py @@ -477,7 +477,10 @@ def test_safe_assign(array_type): "key, err_msg", [ (10, r"all features must be in \[0, 2\]"), - ("whatever", "A given column is not a column of the dataframe"), + ( + "whatever", + r"Some column names are not columns of the dataframe: \{'whatever'\}", + ), (object(), "No valid specification of the columns"), ], ) @@ -529,7 +532,7 @@ def test_get_column_indices_interchange_and_polars(df_type): for key, result in key_results: assert _get_column_indices(df, key) == result - msg = "A given column is not a column of the dataframe" + msg = r"Some column names are not columns of the dataframe: \{'not_a_column'\}" with pytest.raises(ValueError, match=msg): _get_column_indices(df, ["not_a_column"]) From db63de009088b65474ae130bf5a561a69217ae62 Mon Sep 17 00:00:00 2001 From: Virgil Chan <virchan.math@gmail.com> Date: Mon, 4 May 2026 11:12:49 -0700 Subject: [PATCH 429/462] FIX Unsigned integer overflow in label binarisation (#33441) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.linear_model/33441.fix.rst | 4 ++ sklearn/preprocessing/_label.py | 11 ++++- sklearn/preprocessing/tests/test_label.py | 49 ++++++++++++++++++- 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33441.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33441.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33441.fix.rst new file mode 100644 index 0000000000000..e581cb03edef4 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33441.fix.rst @@ -0,0 +1,4 @@ +- Fix unsigned integer overflow in :class:`linear_model.RidgeClassifier` + when fitting with unsigned integer inputs. Internal label binarisation now + avoids wrapping -1 for unsigned integer target dtypes. + By :user:`Virgil Chan <virchan>`. diff --git a/sklearn/preprocessing/_label.py b/sklearn/preprocessing/_label.py index 1b906ba62e468..1d0982dc3488f 100644 --- a/sklearn/preprocessing/_label.py +++ b/sklearn/preprocessing/_label.py @@ -590,11 +590,18 @@ def label_binarize(y, *, classes, neg_label=0, pos_label=1, sparse_output=False) n_samples = y.shape[0] if hasattr(y, "shape") else len(y) n_classes = classes.shape[0] - if hasattr(y, "dtype") and xp.isdtype(y.dtype, "integral"): + + y_has_dtype = hasattr(y, "dtype") + if y_has_dtype and xp.isdtype(y.dtype, "signed integer"): int_dtype_ = y.dtype else: int_dtype_ = indexing_dtype(xp) + # Align `classes` dtype with integral `y` to ensure correct comparisons + # and avoid signed/unsigned dtype mismatches + if y_has_dtype and xp.isdtype(y.dtype, "integral"): + classes = xp.astype(classes, y.dtype, copy=False) + if y_type == "binary": if n_classes == 1: if sparse_output: @@ -752,7 +759,7 @@ def _inverse_binarize_thresholding(y, output_type, classes, threshold, xp=None): ) dtype_ = _find_matching_floating_dtype(y, xp=xp) - if hasattr(y, "dtype") and xp.isdtype(y.dtype, "integral"): + if hasattr(y, "dtype") and xp.isdtype(y.dtype, "signed integer"): int_dtype_ = y.dtype else: int_dtype_ = indexing_dtype(xp) diff --git a/sklearn/preprocessing/tests/test_label.py b/sklearn/preprocessing/tests/test_label.py index cf8b2857830ce..2b9f5f1b265ed 100644 --- a/sklearn/preprocessing/tests/test_label.py +++ b/sklearn/preprocessing/tests/test_label.py @@ -12,8 +12,11 @@ label_binarize, ) from sklearn.utils._array_api import ( + _atol_for_type, + _convert_to_numpy, _is_numpy_namespace, get_namespace, + indexing_dtype, move_to, yield_namespace_device_dtype_combinations, ) @@ -22,6 +25,7 @@ ) from sklearn.utils._testing import ( _array_api_for_tests, + assert_allclose, assert_array_equal, ) from sklearn.utils.fixes import ( @@ -245,7 +249,7 @@ def test_label_binarizer_sparse_errors(csr_container): def test_label_binarizer_array_api_compliance( y, classes, expected, array_namespace, device_name, dtype_name ): - """Test that :class:`LabelBinarizer` works correctly with the Array API for binary + """Test that :class:`LabelBinarizer` works correctly with the array API for binary and multi-class inputs for numerical labels and non-sparse outputs. """ xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) @@ -775,7 +779,7 @@ def test_invalid_input_label_binarize(): def test_label_binarize_array_api_compliance( y, classes, expected, array_namespace, device_name, dtype_name ): - """Test that :func:`label_binarize` works correctly with the Array API for binary + """Test that :func:`label_binarize` works correctly with the array API for binary and multi-class inputs for numerical labels and non-sparse outputs. """ xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) @@ -809,6 +813,47 @@ def test_label_binarize_array_api_compliance( label_binarize(y=y, classes=classes) +@pytest.mark.parametrize( + "array_namespace, device_name, dtype_name", + yield_namespace_device_dtype_combinations(), +) +@pytest.mark.parametrize("classes", [[0, 1], [0, 1, 2]]) +def test_label_binarize_unsigned_integer_overflow( + array_namespace, device_name, dtype_name, classes +): + """Ensure label_binarize does not overflow when y has unsigned integer dtype. + + In particular, verify that label_binarize does not wrap -1 to the maximum value + of unsigned integer dtypes. + """ + xp, device = _array_api_for_tests(array_namespace, device_name) + y = classes * 10 + + with config_context(array_api_dispatch=True): + # Stable signed baseline + signed_dtype = indexing_dtype(xp) + y_signed = xp.asarray(y, dtype=signed_dtype, device=device) + desired = label_binarize(y_signed, classes=classes, pos_label=1, neg_label=-1) + + # All namespace support `unit8` dtype + uint_dtypes = [xp.uint8] + + # PyTorch doesn't fully support `uint16`, `uint32`, `uint64`. + # See https://github.com/pytorch/pytorch/issues/58734 + if "torch" not in xp.__name__: + uint_dtypes += [xp.uint16, xp.uint32, xp.uint64] + + for uint_dtype in uint_dtypes: + y_uint = xp.asarray(y, dtype=uint_dtype, device=device) + actual = label_binarize(y_uint, classes=classes, pos_label=1, neg_label=-1) + + assert_allclose( + _convert_to_numpy(actual, xp=xp), + _convert_to_numpy(desired, xp=xp), + atol=_atol_for_type(dtype_name), + ) + + @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) def test_inverse_binarize_multiclass(csr_container): got = _inverse_binarize_multiclass( From 38542048c261d4d4bff63f5702e501fe4532e5e4 Mon Sep 17 00:00:00 2001 From: Olivier Grisel <olivier.grisel@ensta.org> Date: Tue, 5 May 2026 16:58:15 +0200 Subject: [PATCH 430/462] DOC Financial supporters (#33704) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> Co-authored-by: Gael Varoquaux <gael.varoquaux@normalesup.org> Co-authored-by: Christian Lorentzen <lorentzen.ch@gmail.com> --- doc/_static/bnp-small.png | Bin 12497 -> 0 bytes doc/about.rst | 383 +------------------------------ doc/conf.py | 3 +- doc/images/bnp-paribas-small.png | Bin 0 -> 4537 bytes doc/images/bnp-paribas.jpg | Bin 48732 -> 0 bytes doc/images/bnp-paribas.png | Bin 0 -> 232229 bytes doc/images/michelin-small.png | Bin 0 -> 4636 bytes doc/images/michelin.png | Bin 0 -> 46959 bytes doc/images/nasa-small.png | Bin 0 -> 5025 bytes doc/images/nasa.png | Bin 0 -> 25668 bytes doc/index.rst.template | 1 + doc/institutional_support.rst | 281 +++++++++++++++++++++++ doc/scss/custom.scss | 59 ++++- doc/scss/index.scss | 19 +- doc/templates/funding_links.html | 16 ++ doc/templates/index.html | 64 ++++-- 16 files changed, 408 insertions(+), 418 deletions(-) delete mode 100644 doc/_static/bnp-small.png create mode 100644 doc/images/bnp-paribas-small.png delete mode 100644 doc/images/bnp-paribas.jpg create mode 100644 doc/images/bnp-paribas.png create mode 100644 doc/images/michelin-small.png create mode 100644 doc/images/michelin.png create mode 100644 doc/images/nasa-small.png create mode 100644 doc/images/nasa.png create mode 100644 doc/institutional_support.rst create mode 100644 doc/templates/funding_links.html diff --git a/doc/_static/bnp-small.png b/doc/_static/bnp-small.png deleted file mode 100644 index 3dda0ee559cc59045b34669df5445ea2d2781ae6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12497 zcmV;?FfPxDP)<h;3K|Lk000e1NJLTq005f+001Ni1^@s6p8ZHH000wIdQ@0+Qek%> zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3*tavVE$h5us}UP1!67sGNeMtBEazQ2=IdU{f; zyQ3W@MY5R8#Bhf*pcKyk{Pzw2#fN#ZU|w74r96CCx1I(s+VlDN{EUyi-`|fuzkiFr zUJuE>e@I-){LG(U%lY0vxb8n6sNehJ{PlXM>pM>S4)p!Qj{&o0PQ2LPMScg$>2p1P ze-Ax<UX1d$?R>xPN?n)yyPe;Ew@NU!GhR+1ogDM?eovp7GONfv4_)UwSCXzIUZ-66 zZn^$r{K8+M`$GWp{B!)C^}Qqi4991nAKNOw#p!!J`k&+XM(OV>is^ex`uPWa%=zQV zKg93ucJKM@ZdeI~t9&>0V~g)AZe(MY-^U7{l`rRYeLp*&?HSJ^Yn!dk@JxQ`F%j7t zE$%qtjpzNj;$n%GPOAJ&X{G#LYq_SL)|(X5XS}Hf^0RXzAB)UoE~mfN65n~d=3}zP z%sX;tiVUVK{_+`qzwm$k{AHkfRpv1&n0dajVqHn~#WIvRedjI`67M&r{>C?k&yVN# z4<$B}L4U*C*x-2PXNc+XXKm#-&-wAdt@eESCD#2NfDkdavzVC4z*A!OSmIMtsxcDB zMt%k>PubEW1JQ%0%_@`STu4q!nww{8eD6)3K9_+P65+H+B{eh<$ue^*^jo8ZM)2(B z?!~J&?><T{R=ku_i*RbxT&;R7wboX99W6I&-b$;jwcbWgJp*GNdg-;d-uoC#I&3i3 z;QqmdnP#3geU@2gn|+Q&`7B$$%BriazQ#^FZy+G-vg>ZU?{VUxl#U%g<<!$oKjTts zH($Gc%dNNFe#c)~`)2jmto@$3f1S1X&02aBrTgm7tZ}*4A45dJi7RJhELkMuRT-e5 zlXCX7XqJ>Y<?QJxhnzjJN>_4rRL01lotXT_zjF68bN@7Nf$09Hc}suFTu|!%KQb4T zy1!-aAM^HytnKl_ZGID^E+nQPWTySjA{U$cd$}<ms(-N}>v2!BB`_LqDU5zj-fO42 z=k$8-c>3D+zP!d1%`J{)^BB8k$g}4lrMdx#bFW-D%#us(FwFE+$J}@Jk#9NM!Q9Xi z!MyvXc~7(-6Tx$zsor@&TPN0g)_uB{`+()Kc1D9Aef3+~4RhYP=-XM!jBVXpx)BQ= zCR1X>eD)sH;(qKDU7zRu!>Bu-w5=p6EuFBMQ&j!t*<jA&zPYW$JvLhzz?+fQ_9Q=4 z6X?87A9Lo?jIH=!vvHL>ofrXmr2Z4KZ^UZx6B%0h-r&#Pwu*Pl=b0Vqtu3<0#U@hO z2ejWO>_P4B-gAl#blqjxw!=qRlc4Rpw~sYS>OC4o1qz?%fPtkiKcn<k3iXhK?S6Wd zN*Z+$k2Ia;porfQ%cb_H*2fwc*YcXy+Ox`bR;kd>^Q;@onc<=_tak=+>W2vDiDb%` z)yLe{S((xu)FzF2<DksfEqkQ7(nNWbNrloFC!{r>SvGM$)(EAQe4JL9<-m%FkH+|A zlDB8qcH*Smn4EZervG9rqtlf;<fpr+Xsn3rsqq3S*T(xz^G+fa&)9>#@{;N!#Ani; z!$^H}wwhxrp$ljT{A~R`WADS0Y2DT+^+Fk!Icuf{5k)nRQM<=Q%%XF9W(_0*`j0n| z+eohKNtXyN(!>@B)I+sWwCRp@crZ=#G^|bvc%(-&Z{=uPril1sm_T<fWnH>6O)BCV z*nnX4`$n`L7`V0Solae#3Cp9X@7!~F@)^?_P~8dCjIy=Cjn*?cBF1lA>o|Hk-$m2f zAytvwFYc+ah}8R0XFUoh*$K>g2_jgt&tb}ZqOgJnUr(oA+F*ZRd9JZjF)b3swb(rE zkjJ)q0i`n%s&=((rHw<ORFu@5q>E_IzG(PSC)=#d4IEoLr<X%MV+G4jvIbwIJPR?Z z?YXU_Tm9VV6enFfjS}-kr`1V`1D8(%nsd99)|?QOdLLz;PwR>#`wtF+BFPwR*NIp# zVl&nGb`xbCZFQ>T0=z9xu&6Hj2GMW@B>*|yS!n1ICY4oz3PV@swh_LoW}>GMCe1by zs7}bBR--7vm;r2*N~0IMR5yK8%Lue=BX$EAA!v};xNTenVs+&KemfS^?VbIuZ^u4$ zj{C-LnyQc*c>?RK)I4C9e35jdCmlDSIUbJ*G)G#_ADufJv)GH}t<VgpR)E*<A^i(p zSruXjEmH0z%38d{79aC=IoKMBIR#8Fkzm3C@PRB|A<t*bF~-@UP%o(g2zNtb-mVIT zwmMPsK2%o$PbrE~XlH1TT(ibIv@`g&8|0rGLThmUrS@98hrXfmR0`=()DV41KK6n3 zv(pou{1{DH<}Mky7!T1GB;*q)8UZ2YBQRPum6~d~G#|}9gsXW`6&E(4v!IDptg)bn z^dP_e+CC1}hVe8YlPxEx9s~ilX}8{?Iw(VYRuJhl-L$i-%7{{X+8XBlF#8~&Mn{D< z_qwn?4J85tzcY<3J+^lS_0k!qWIO_twKw&XeUT)X>U=~iq;Z~7LX#n;IKW%g;7MaU zKyZQAb6Glqp<MQhEi@zcEk(Arvx>+Wrn*x+eFqw&qAV^N&r4?3(uu?%wSqD*muEpE zXa!WktdKrz&uqThDYOVh6&0JX3baXZ$|g(@tazKXEnuICP^h++x1Q`+A8rHzBf17( zc|;%+^)0%YVN=GLup6Mht0afFsHqEGLP-s}a<+@uqq&)!{0=(oGKqEIJg&*TNWbi7 zi4vY6MYB|8vqMAAFgn7thaT5+c2|#_3NhEE*;k(|1k?cW5jKI2S^y1X%!qWhShJSX zBCydfY6GwXS~l&`d;kyJPG3`@2*Bjx?n@@%emI8;BD?5O5E*3yzMysKjqWfMp)w<m z6fXE>7feJ&?%BpzS&%_-&E10g*=oyLq<9OROcm9fm#Xi;n3-r(qkFd*l??a`eY{~7 z`-rgEDoYE<i$u0FM0p7Wct`P~_ljH~Ol`DhX;AHzSZxbz@r5a70|{r07JNhtGmr)l z25G^nu0$|xGTDSf2CC0q=qH3WF$1wF?t`*r9T2xj433=65-m_eCgF(jU9_aFLw#VU z)vy=1XtK~<0sz^B+(P$91U8}x`$i!*IGEzeK?H?Jzm`XVo`8pp>Kw;}ZIGIQNLs-@ zLbA7_*fXg@ZtYyo0eXiN8~Z;RgUMh@ktEt^vfo9k0WBGR)eDkDj~u#%My5TFzM-Ze zOZ-Yr!MYwrt*~vNb0q_xfV6f{yDXEom3E7$3MW?&5Dag#9_W)|?osv^j0rd~6X|7h zYDO|Pq77c9l4oT)$`YU;WVw(7>KLhv0vpnqLUS;D9G?M!HGuYkVk7=+3lj{4J55QY z!ig4Xzya(#a+fqwpG2C_r}J(T{WH={VM+C%8jLnV5sh=P;2;M@De_nD5{xiulZw!! zxhmqP0Rk8&N7&-FkkgZ1JGG_>^+<Izil~h#HY_YatE(tR5Rt|)VJ3hpb^Y|c)_HWW z5*J*DIYyQsBoY-HDSO!@$5U7m_aj26#UglL05HCh0m&%6zwvFG_8{Ah=+d+lAKlg7 zJshe85y+z^8-i%WQUGkYHZqv{vvq!C6Wx!%K$*NaQrb>8kY3h;<voj?0<*Xfs)dFo zC`AgDiktRGfxwl!_~^#-><@p)<aiuv_t0xp;l-*&q-=?$>qRWSNHa<di#^ju(j%uB zF+v!UsI{+;is%Fm=3F<>%pe6Iib*9lg*u?m&@3~f0ofQdsHB0W_yJ@-d5Smol3UtX zJdp3<77y6`6UDzvDUG5A9gfMEyhD%|05>fqtKwb@WLom;_72z}OMoyX{Z)Pn$%B1y z$0sEnGBO~%@*d)?E9VDJ@UpFj_*@xo#0XNwSkR`E39f}kBoNX9ib=Qu#*O?XHb=8J z!7$F|!IPxCWdn*1i3A3Cwg}k6F|C$|fzWCwvh|(}6G8z!Oh+A(7s(;mrUU&6Y14|% zJtUgz{3s#lLP7&Eik%!TYM_QdP2AQgY2&I%)qowF!3+<I8C`@DL9n8(3*r#D18_MT zfCShYru12}8l**@;Yl!T?RNWvHmI-e2e?2pG#xw}r#HH6Z5k3KiK%M@u^=K6+>dIb z5r7YrnTm(Iz>czIlE~tcmBHLT1Jj&w=mquAjz9uf+@t}$N*zU*V2iz=kg@138f`^s z><QnOy=7*f4L{3=$fuwtX=w2t;tSPmSl0l~tq0ikhUibSuegVaRamkf*b8ET*+g+6 ziBG$g5_7O;3}_9J^3VetJPi|;I-=Amhb6-a$2Oa~k%q$C6?%!pQAA`xHURLtr>n5& zBZ3ELH3PH3nr0WpQq&G;S8NXgdn4-v^MH;Z4OhulCrY2o680;~;!U)NA<3VB<fI8f zCqNqZL#UB;jXavq(VKt@qNTBflaG2V%5q<{6WL2lRKdFyBw^FQ7wgRt-~cH;KsEM+ z@I=a9C8f}PXhk{zXF`~0RunmKWoVy~H{2IU4lAN5pJOR?9iL(Fu@F#*p_F+BPgT@) z{EPghA{tSq*iXjV5IqW`RNN7(Mv)8zXY7a~wTfIJVpGZ-9zl!5jM$?*2xtZ$MV|=d zF`q=;q5)D3y*or#=_uTNhCw_luB6g%dYBNw^wGHy{FSR>Cc0LH5HG;__M|n06lDm3 zQZ=mWC|D1qjsPq=qatX;2&;SOb#Y8l>!7|zjWQ@YR#<dyXvf7uC<-}$>4dRyP*tks zWpxH0G<~9_(XSnA{9s>jxJ6wrXfOEl8*EKElmk)@*BK7FK%RAi72q9Mfr2;cU$O_9 z1p~&T;|lyg!N9c^NzI8qa<mBU0<R*>reQLxb3`@{gQ{d~eA2=5r%K0DEOF`tL5E~R zTo1k@lmZbZ5_LiP#}SRRg#*|iAU+cUfYDu$iIN9uz(6QAI(5-mDwIwhH!h?Gyc!fv zwpv3Yv;?ps3guhUpxI>d07v$Fj%+n0NLv7glNDri7j!#%IXR#+sBvO<kq0~jP#{Fv zPlg~mH=*Mf>K^?_X;Ntq{ujLm_z@vJ!QGTl=yIeTOk<kr?NJPq-tL1!laA$>ZP2D0 zuAr=((9&R_80yF_ZA_l=|2v?n;Ou2+X?eaE9cZTIhHpTbfm{t?aXzP5$W0U-nuOSF zDJ4rKJ~JD#CdyZLonyIZA#3K5(b_uid1y#OiTRPu(+Q=ars*Wrv}fe@ga5!@<{<q~ zJyRD?h9%)B+E-_j7<bF>DxetGk)G3deX@1-S7=?GQnFEe6TT~C1(MW~QQQhTQ!)Wm ze#i-NM?52iX)r_(a6t3F^^kTnB+OWFS%WQC3v{o#o7?R@wYhKxQ3i6sxcErOP<ikp zX@DgT_=kLf-x$-UC_3)O4#LCs9Xax}iOEk>2ZB4Q?biYm@wUth($={^99jt#)7e>r zm=HJU477wlDNs0#08}8Qy_OnfxB0h`SDvS>iUWv~zG!d?H3yeqGD#3)O#%h^fdVa1 zhQtKPIZ+)nprb_&+J*3@SIO(>QAB%`r%e|nY%mb9sqP1aMx;Bi9*~7Dk4Sl;>j8l* z5<|zp{qIq{xe-owIaE-~rU0D8A`=v*<v2K0VL&@7n>f;`(`@i?F1;C49VRS&3pgg? zg>7G#e*&)ZAWB)95V$>vxhG?4RLHFUb9zp*BO&0Ag6&Eu-VVjbqtkwBFe~s~Zy_wy zQbz{D;KaBvNieJ(QnN~`0FlY!lK3R(tgz4C-s2s*I!dU-fBG~0dO=aAt8)bAbsCBP zOixv}V+NYQ97@28QaShwLW3oTfMCoZR1+T(^Z8OP`=EV6gQ;`9tdoZe<fg3ygpC<g zb#5>b_mXRJ)~}N|cunuzzHbQQtV^>EPK}u1YbtL7{tZF&7>dWzB^}`P=d6qDzJO~8 zHAiP7;?w)~1&S3p{drFWeUEOv^x)z71ssmI1nFelBF-Lu#6wTLnL?`KyaD0b%R5J< z5OlEio$51@AfB11WhY)Tbe)o-R@mwUfl~xqf#4@3w&hjt&(-&gdjYxMrF|EMsAOq0 z0|-j-6<SWeQkqd`Itj=C0)tU3lm2VgJ%Tp)w&U*xF$8)q0*1!SnRv+i8t}$MZ4fRT ztd7Y5ztZjq$)}7|K`vkfI%P$M*U}p)FXFP%=o|cjC5IL8N!lNL*CbMmAV&k10&1Zk zU%(X97!vJqSEsFrxdksXj4fm)PV}`qa{DwmNpEFhoVT<R4)U}xWclb1y-5Ynz<NUG zEFG?+9YC6=V-bSrs7vRox`fq`xEJp?q-PwMnvtJN4RTx7TbC`#6TNRtP#2m7oVnni z-g0P|gobRunV~FoP6q$Un|J_%ML>onL%*6%jA(!0+!8!f#Wt`Y7}_999ZWdxLdODD zZR%|Rst623`dzX*$m)(Ln8e_-GxMVuBaP*Pgl+JX4x<o!HN6MKk#bCATmOB+xH<Ta z?*vP+d7rv$AwEmz3u{#{c4M~kDvRB}{|V-ZcZKWv4;xsBsdf+X-vY#M_;BeR>_PZn z2)&qiOQ}AK0004mX+uL$Nkc;*aB^>EX>4Tx0C=2zkvmAkP!xv$rixN34i*$~$WWau zh%X$q3Pq?8YK2xEOm6yuCJjl7i=*ILaPYBMb#QUk)xlK|1Ro$Su1<<BQsTKup+$@r z4)^1~_y0NfTtKLonPzp20h(@`sYG1NWLL$mSA-x?^<zqAmN6$uN%*d>dj$A?7vov} z_x@ZxYR+OnKqQ`JhG`RT5KnK~2Iqa^2rJ4e@j3CRNevP|a$WKGjdQ_efoDd{bZVYB zLM#^ASZQNcG&SN$;;5?WlrLmFRyl8R*2-1Z?32GRoYPm9xlT2N1QxLb2_h6!Q9>Cu zVzld|SV+-%+{ZuY`XzEH<SK!YV*wRtkX=9cAN-!Jm7f^*lEQJI^TlyKhJmhKpiy(2 z?_<YloB+XR;7V`#D|KMzlk{3kiyi^J+rY(jOH=lM%N=0g$&gLim4Z}4J`cQ~(Kls* zzFQ!)=FP2nj?)JqO|weg00)P_NP)7~ecs*OKDU4GH0SpNTqJUyx&!9z00009a7bBm z001r{001r{0eGc9b^rhX2XskIMF-;w0ty;1C*E8K000|+Nkl<Zc-rlpcX(7){{LU+ zwwXyX3F#pTJtp8vmkvQdq$r975d{@R5f^oJZOE>!-L)(Wf~zbRY=8?23P`U?69N*N zNRbjs3MrFh%5A?tW->`gSnGFve(2|U?vr_P&zyV8`+Pp{Pq`xu%d`tUC0Mr2uPspy z7j9<+zsvb4%9)B%`n>TFrIlr5C8y(3HU8JIvuuk4`6ro}eLbUlUitg3oUdTBZ4hRF z7IBGm%WQ>&_*Djy5b4IYtlxL!d<L5k;FMJ^NJ%Hs5rO?HnbX*)Xk<zJz9Z)|*Z^FL zO1!%PnymgTunE8fVjK|&z-I&qSO!1DF3SicN&0<9{y!JL-%lVAKnQ`RX{f4-5F(`6 z5JV^{vMixn1~xwjYyz+D$7dJ}YSD?r$QTMLN;q)l82J??c+J2$`!`G-nIPDT&lIzC z$x=+qtkp&m67dNMw8&^qdU`qzha-G%|NaAP-n0ox2;vjsxwQYKD2f7r*Xw1;k|k7> zSJ0?&W3sb*A%x(&@4n-U^<RV+13*X;(QY?QnlvFbEtS~V*mE9&($X>(FIt3kmido} zh#)<^5$TQ6Nk~jU4UHo_SHocW(&ZEt6_J^hN#`z|>-2r{#7S1JTv>Z;2%@8-Y1E_< zsi~>N#m6Iu#%2TS)~@CFvEv9^(6vWbnm2FG@#Du?zji&AU3-j@B$1MwLbDdlNJ~pY zRn>auc;?I*mMvL^jZN=MdXt)(T5r44`T2ala4}0hUrIq?0kV)tN=fFT))z5y)JW3P z(?VucQ7|o&O27B#!P*Y0H{I|uZ_jFCoedb$vKzxM?1$IzbD%hn4M%f1<1NFfYG6aD zuN)Bgbw5(bj209W@W{gx@cVpdnnr4BLoCbY)QMC0{XU|i-Lz@fh8JFZfvl`d0Cwf> z<mOvOksRL;hg0K?8E-If-~a$BD=V2iX$m`Yb~5JfF=S`=0^s0*gN(X)6e;lykrf#U z8PhNc_<d**PEr~sG5GS!dF(F}aJgJ{rdwQmhMR60NpgHLk|ZHZ3btY5_v=WSAR#G% zuHCxw<kL@*mR7w<hYlX%zI*Sdq_~8OJ9p&c1s~(Aac}^R9zDvan}hR_WeFJ>)3osW z{b(+g#H2(94jRCN4?jd=VglIk*@A_<_s)CR!e-W-SwXNJJI*5yJxU;;<8*2?Y?y`~ z@N@FyDGb9Tx`CU{T{`pPD=(5(50K`6ynu<1PQ>r?^U#C`nJ{reoi<yxY+?MkdpP>t zQ4GUC77C_qV%ZkUK3`6kE}cnFPeT%bLs8L918>0l^DaH~*YKem0Zw{O^WM&7e4T%Y zD9uH?<P2_UH;8eahBCVS<-|GNR0e!h>Rxn151&#+RnRmIAp~vPw`K9N#jIGfoJ~0! z_}epoqq4G+FV}s^Yg4C%C#-3X(1{i30i6jCJ;vcfhlBkoDw?VyB!N?NhP8zj+F&6G z`d@Y_IlH#9E%z&yu3bi-e!V$%G>?D$eG*frOvN<Kx*SASh>M6vNP>i<L{@KDMb4fa z)^1tD*t_o}@7M`GnfnP3Klm_}6_p_kZZc=~9Eu7GQ52ai8@I4-?YcUBtC||7CM_~E z*tC5kIlH&9a{UUfx%O&K=AC5fKc?}@OD|)ZCPIKK!iA86bj0D*0B|@RNV0?w(7W#? ztXQ**RqI!=IcF1pyzg$xO3GOF`7&mIIJ*voDn3)pjOjCi>lWeU{dYg$)TvW-%;w}t zlR0$Y5KWsmVabXmY}&qo)nBY)`kSvaV9;eKYEZLFAkY*ApW&xc|LIpnz)yL=hhdpC zjEtjilMamScqI>azkxp_HVF?dQgssRbhBX3dcMlri`Veu4fxS511SUoS(Z^18QZpT zxm-j?M-v?#O=@Zy{rX>uZQ96+Oy2Rl8emhy=0TDrPUPh=ZR#|1T}M%5R87M&EmXDI zq}BW!85K!FLINobQ|Qp4J>%~gPf2kp?gmjT{A>~afWHnPBv}e;Jcs5WF(HA(q(oY^ zYRP@~-%C<rBAP>E;};t#I#UEdVL<`&=FUUYR4mg%R%E75eifh3R~u}K8Zs6(QIU}( zCMJ@coJ8ApZJ7A@MB?J(h>neB<Hk*Ry+MoQa5%8-pt)65Ed<)&p|x#@jEp2QGLq=% zXwuWu88GlNyyX=rs>110r|Zyxt=qP-Z_hqVBY4oh+5ZineY&s~D0N-u=+R@Ss){Vj zq^32bS+i!eZhaBg4ZDsR@64c6=T0FS1jvd)h3=;!;Qh&$g+-f`3mDO60E4o6qB>n{ zIdy=UxhptTQ5-x4rjCt`Wm_CCIZcJ`3w~esqMJsT8_AN49O5}uT%xS3jN`|T^Um9E zBPkN9s&e}sw^utDq4sg{aol;=ok)_zE0bQ~)A^sGC_znWS$3GmRXwL(HelNn78aqR zfE@&)B<k`uNs>@BrP@2Hp%_X^$|ycl8rD*>9DLT&rOPPDFQi+q9$Y*8S^&0vmBar1 z`)h-(ibL7p(6qD6cL^1qa%^mzPG@-CG))6+1OizJSqWJVjol7w%hJ+PjvhVA^nXn! zGR93*R20__9~K^C6|a2l)oD1K4#xg*EE$;@B*Z5$d)92q%gbvVa*YczGB6B-Lx&F2 zvuif*y!{UO`T3Zpg+tSDI-DVIRDdMQcmlp36=AbOjfEYYUb$|t{>ay?Ih=!GnSj8u zEiTXKOj1MxHXPr>hq)`cyVI3q#HMnlvW$v=4-wiR(=w}xxDa7er>ZJtWo3-H{Z97o z+Cxc6390F6Oqw!@p541wo3s#!Dl00vY2;1p*}aF=D_1l5pHt}A>0+Et4a>H|pbP@E zdU1=2irBGz2Of`yoSf~vJM&$l<K0x0RdD+qx7Tt;YC0^ML&I<Q(EWbC-nkQ1RoJ(8 zA9H5UK~li)4KVz!;Up#|Qe0BPi_g3W*xWv5G_eihc>9f+G>DJp^=Yp&W!jYRJgVkz zW234XmEKD7zsqM=?k=XjIt{}#DJd%Bs-ahgwX0GCEQ+jD{|)VxrfB5n=QCpXjT}FA zoRX4KF1)ZMlcxNWwr$(g=3$$+F#ogpwE06@?i_mu?r1m9?|6>AyZ5qw{dxuu9vlYS zU!M3YhYlWM&+dKr@bcIrk1=`D6fV8&Qbyl4npUk^Ap}SQ2}zQuF#MF)b9v6XN_8Ir zNiaC08)@z&$_yVBhL7?<1!ue-%KVjK(|Tb-Qxc<-cw*IC{B7+!>^gmroD=&Am<FdR ziz(NupJUl}n6uULa0Pfg9@@5PO~+0bQ(Ra|L4H2}d}R`A*VW}ZrfK1FIeBd21fn7% z*^|46S6+GrzhB3)tgxxBR!2cuwR|=0JG3XecQ${z|2}r__=W+4FJu0a`3xO;RV}Zu zPP_-mFDM{8yBFQMbz}5xqgk?S37xxi;<bNI<IxF^psFfcHg93yfqkT;q|mi%H`=#v z$AByP1Mt@Lne5%W_uN?))8g;XzsU91-oWnM-Lz@nhK0)(aQhu&s>deP^jzy%OG!{t zTtbf?J!spm9r;D4`0nr#Ui$k>?AX4e#u}Q;ojZ>xHJSl~29Tbf&fvj=k&Ga<dG()D zsi>$3w{PCO8UOj@KTLaLDlJ=OakAhfdB^gY@!AZo9&$DBz55=PWd$`GLQt;z>XKAh zA=VLvTXW%39N0kf1}R*3QC}=9-rctbf53~3sIwW8kT~KgWW|>sqS!W)2x_`RMJFis zdMNOg;Wzaf(Pc-yAqLa5NKbFX6Hh*YX_}0`=WfQ{c^4bL*uW<XKIWTmz9BO+GaOQ} z3=6|BXw$Y0Pe1=Ow~f4$Pv(A1L{ucIqGHq_`ZYO9pZ<LqKmLy(1W{G|EhVLv*{$n* z+gN6>kEG-z-kSLq5fLsTA|i;3k0&K1IjnX3em^tceuu=kM4Gi|&euD3psFgZTDD~K z#?8dUx>>YnF|Av-u7hUVwsA*CbMK$-;Xm)qLz04do{Kwos%2tL-3X7%u#CFlCBq;y zE0d?5c@o1gxP8TF?z(dvE0?ci>*j5&ShI{qjT^CN&tB%u2|g!2KAzR9R^#*gY16eW z`}XW*+gIDzzI_Khd-e$TotT)&u<Ng5;Gh9)+PH~%b3bP8?0I-R9&WkyX1e$2h5`ah z2+H(8b?gEgAtc%+G-Yr`C%UG!BsD4yAtWRrAqzpNuY%`#-^%ur-?H)8ZoVx(h1c|l z4tlVUl7hoE$V_n2PI-zr<|!oKS5eDsyEO-rki(p*DlTLg2DWVh60$7QwOdzuW%uHv zSswwAvu!(>nVA@&g|@K502q4pP?nBd#`2}hDfg5kBvA`sH9yD4#?iA^&mWi5wJh|| zb0sM_wwRdcdfTpBx1L#ZW|5kd#?~!cxn;wxAcDM6k|a=I`m1j+YSbvw(o(}QMj;@e z2e2)R)~#Ff&=U{x`qY21dDB<CJ>xCzyZ^rMA+;^L8la)M8Kw~?^rmUlq8)wv^`%SK zF05O#j&Bct%l`fQNli=T!}mX++*3|;tee-SzQ#0*5GF*Je!M&LUAlMgh9pVBa7@S% zal760zpOvKFX>Hud>n7hc$)?hv79_{DyVpE0Uq5Sx_o$aKV<<gUmVM2;+nS^v+y4j zdOfI;j4TAEZBZPkL{%NMPR-)(ZrAd3zuV~8Fbj_n2=`I5KacLiWB4iXd02hqYf5!r z=w9%$1mQ)qOcPT#!`@C!jhA0gz^<LU!ellsE-tvJp-ne*gMc0g2Unkb>Iq_FW3fZp zRX6k+TC;lbeLnw>&YoD7MZg#IQhk-)I^JAO?flW~ImAZAaY^6aEL*vhHD9h_?U!p< zv2HoTZWu<uA0Y3<2^P$sk8RuG`2gttK$ypk8#k6FO`G6!I(X^%msz=TRrMTnKO%Iv zb;Ag+pKS%5hN}Nn$?;=(?8@C0(uO9{F)`#F&tvhT#gvto^Z1j0W%c@1tlzknbsN^Q zXz4=Y<Kq!R@b4MZ$<56r5D4(tgo#X<{3?eI9m4MquA?l=q%=&ywrwgZD~U^pM-h?$ zNeYqrx{F;ZNxX9LRU}3<z@z(ct4==Iw}FwX-vmn!y4pgJAZsKkE^OPb6Zx+x$2>)x zIItDlGBM6FyH%V`H;iD)1Hr+A2YGeMs|X<|EGT5%+I8&OxtpT0LMBd_Nbf$q0SNem zn;!55YK0M+G;PWgPd&js<L&_=@caBVVnl(kCatI_$286VYBuYD$S^4>E+-}-g3{s= zEVKT3@7(z{pD$WUarqgpyy_}4LxJcj8GF~Ay#LmF#Ky(4VEzI|+&F?jp!!ghS5|}% zLVSEY4?Oq)w~QD~WOM{CJo`ND+qWYjA%V(@${?Mvs@KEk^9K)sfL%LxF>UHJ48!E~ z>C-G*vXoPKCn@q2F=g@;+O}=W<jGUWKV5)<pFx8Mk)EDjd#vNe^30RZ5E~W8r}IB0 zE2||(zdOpLNt5`?{g2bVUl)>6k|`-EWz+gic*-ic_x|x*kkKNT8<mBGWm<K-(Q?b+ zFP*NYXXDnq^yNoHYEJID_zGt4Sx21DSDS3>UQXMU=O)rsU@I%E*Xxyqgs9<7U66SJ zM(8BY|9C+-gpi(|PX7V@>DH|q-FtKoa~4^Z>DjFp4yO}QBTONL;HsfllAD{$x;5*F zh=>R}3X+5nf?hqc(KL;?`1o^brgNs}grG~W4#={MEGuCT{cP>`*@A^+walb-n~TWK zu4}3@T4XSM)D7(0vlrX6+4=QO+-^7ByY$56a*~vsRBLRPUvW8O#*HR-XHYABGVc>^ zyW@7Equq4u)DZ+!DQVlbY1yh}I4C{$qj?BG(NtQuZq4;KTu+Z4J?PT43+3hIY}>Mx z4i~qlO`BWlO-&8CY6z=Wug2%|^6j?=C@m{x$j~9UB3$g<y@&n#zU7;}`*AmLbH&w{ zGjPyAhFm!$Xl6aW3j0r=Pv!FiIdwX29G}LkgU0dLns?cG>>Dyun(?necQa(pQ~15* zzi0xtV{&u;-2Ga5x9Awoe4WGb`@U@1kGgOFz`p-mpTES|>g((K`nG@I+WeHY{3#L$ z1Slyk!Llu)V`7LnE5)ZEK#}AixvariY)N8Z^N##^(QE84JdOnHE;z=5Z#Gk2;RzPP z{eq&(GE$8o>rYt>@e}U<+(j3^U_0>(%!mIGu<8>{(@08A`fnvh0!30n9$YnmoU+R7 z9V;lRC`A$i8&G_HW^P@AWSacaWsX9KdgE-r%Xw7KCIqOm3TJ6HLl_kMd`LAEu>eXv z#s4Q~MHVum9<UjPL19r5g#`tad&<!q8i`4Xq$H=*TNYDXTuf!9m+0td-0rA4_scvU zJY}9bkz=PrBc?%vT2Xl2Fv!o(uVsgX5I7tTVj9HMYFp*`ozBlkAc%~Nq(Ot28e^)g zcikjOA|)mHd%5m;0k)uKlfkmWU=u=+-Mk%Z_HV<g*R%ZPt9hlfG@EVP?Ay1G7hiap zH7i$AR9HepgbUrL6A=@^`i<*p+O$cnK72kOw~rpfswFEKd(T*&eg4@x-sQqiKV#f& z<B%i?&E-T^Bm$KIQqq#?)4wnG-g^%hWL^NkiM%|TH_gKBbRtO#k}9DflbDi7_v{}0 z@sH!UsP#qR(9Cz=9U(LG0%9DoJoERb7=Pb*04Dw8pS<wQi$pjb2wM)Wo*jJmqIqT$ zHg4U7%jx_rfGrrTvkfa0JPqd4`ZQ}t?vZ_*_7wk51`;rg@EcyXZS(1Z&v^8qM<^;f z!-apikg5NAkc_MgC^((Zx^?SFu7?}!$l1Z-1xtxbjN$z^-{+38caV{hQL9a4R1^`> zk$B5|%$oZFSy@@^*}aG7pL?EJ@6TrUuHAe%>jP36rl2Y+aqb4FPMK?mUBknVJk06* z(=3?3fa%kwvwX=iUU=yRhFyOhLWpoZUPQDDhqF4D>T<boM@3>97H@qxgVeM%Y}>-` z4+d+sa}+L~cVM$^z_!4$t0T?AqIp~jz0)t^?c9}ELdGr0|EKRK1PnbKpF4g$k0+ma zk~766bnV`iH{X6USRe>wWoDiu(r+{G<Bw?&=LQ4;OK0)oCER=O_*$);Ar0aS_(@Mo zCoL_Fw6ru#(_+xzfqcDfCpkGe48D9YimDJ1;Xt<xl9Q5Y)VL9i8aJYS`wmEw%#>Fq z^Zc{VamgjUNlH$tRYg)0Y>^QWV1w>6>C&~!IjddIcaf?}er(Iewrot(BHz$4EQ?Xy zF6Y6n*Yb~nV`$c(A*NZ~?w7v&dH^#NOIo^Q3CE5cqp+xeVZ*Nr1MR=b!Gni*>$P{d zxJyUIjlT=qwt0Qpzc_t5{~R7#bp?oS7#uoy5E&KCp@p*&!OAc>oWu_EOIe~{zrK`I zmT+M2A+~JU66RlF&rH>70MCgHI9(1rWgbdPN+~HR!Rz(?wj6{|QVn5Q*rrK~l*T;T ze-zysw<6jRL6@c%vid*{N6wr?vg{wk*Mh}*KTZn<^gvj%ZQs5FNs_QIY1g*h4@w)& znKg$q-U6<^<{AbL8psFleZb!R`&hngIX8{Esh;?njL++3#=qZW&8ju5S+$17jT>?E ztvA!5V~6j3W@2Ju5MZ*z(IZDWd%8-E!b~mn*%j^J`fG2%wrzZsUjF*@Ul}!O<ZlOT zwryhtRU87r$<iWLAO4z_sm*BRa3K(EJ+dFKuA`pA3l%`0R-IUTXcw)L(#b0=q`2(I zaXr7GV}>}R%jpVNaRdT^@BQwnQ>Xa!(}iR-&7@oRuDIP%T+*jEh53cdn>UZ4S6@X` zRMc5uvvEbZNKH*;^~%*$R(N^trDqv2V#GOL{y5w74Dw40r_;&V&SZTr_Slxq@Efnk z>2y$5>Y;I?M!z*P3bth;6a^s(e10$QZdgR$Hy>m3v3=OK#jsA7GWqIzNNNxdl0ZlT zTR=eA6xljmGTQLMm1B8!$QU9VE{e-b5TSNI^zxfl*z?WqosDH!M5)2D=kJq+pDp6> zfkOmzKM&mhAR~s~$c8UBAS(*%R<7sEFTXrzfU{5EOK8`jEviH1^My-7A&MG}&k>P0 zeE4w4i<Zf1*|KiPCQu`hZkPz*bU^_lN8ZE(e|~_+pM0F`-r2uB&gQjrRELJpR3uHs zscG2drTk^(2ju1-rP<60%s;Y&PFd}VjE+HQD$UcIaYxrHm~+FUygTwSn#4C`*}g4o zKDq}<QxQM%3Sgp#@^^juUPAAFy>YlS-gxZ|wrtr#AP@*vLl_1}jvQgZ`~_H+MSgw( zZ@l(80dIgmKlA{%-F7Rt+<G$;9($Db9or$R5^qj_D-5ElB)tsix`E5(;^j#%laLU{ z-2cpF`Wycab4S~<!a2pNY7xt_ICb(A@4xo}u~BjKzv5ClUK}*LH46}GR#^CbK5W1w z5YG2XLi{FTYqia&1-faXI5gz5@&Y@K?cwFk3&;o<Z2q=7cPeWNCo4+`L}>JCbulZB z?qWmUw|rB40?ncQq=A^&;Z1hC-8}cgvpn+9qio)=nW0x)L-(HD`NKsQa{O2xE0!#0 z*of=6YUovL+^~TYc_(R+*@9bd8%?y^U9DYAll3dVV9VyO*u85vojP}-yu6$$>QH5( zTefV;$XiD7%;V4U`n1>S-lID`dUQwEbt+0KaKr>(T6y`!mpO9eD63blqNKEx-hF%X z%(G92J=`i_+P00?Tdg63HTyxc>emDORz(3Dzh$6kDw1v0;vOy=*6iOJtWT;1B0=NC zMtF1|!)HCi;gZu>X3$i~KM`z(B!$5Skd>9i%=c%qV%c)$f3kobTeq|As~l1qCUMR1 zYZx(N1eRs9Yu9f2UfP#Ig9p|E8bIH^eHnJsb?5<|+}t48qTFu!UD^*>mT`o}Dum#U zJI8SN;2|n1D_OdD2^~9jKv7h#96lt>&vJ5h;Bq;+anwy@XZNCg`}RaeMOHfknuB52 zT#u@%VFv=BVQNDLTs{!XvT$gQ-z?ZfQDvz;cHty;7oMcNMh(?}|5nh=_nQU^B2=*V z^F&i+Ug&iL*R}3jFBuO60$7%f8hWR+D$Ee9<P8?<N#{s+1q&x7WJSiRVHy=hsb$Kl z+E(4G(pEJ+YazrrYu>8Nd@wvxJs#6E!zDszKl8U`Mr|9P89-K)T2&W6L>#L2iw(pU zguT(TMOD>vdWhdw?0EKlNs`X_a|-qK^<#=Dg%I_QGg$8?^II1Mz-Q{Hl7%cQz^_qx zVWU}ko!_JQUCu|a0e;)YVe7xzKrGwBvVY%@^P006rfHunFRDe(e=Uh|M$y0-`TMS% br}F;*>3ZdX{y<G`00000NkvXXu0mjfR226E diff --git a/doc/about.rst b/doc/about.rst index 89ae80084eadf..278a8125cf185 100644 --- a/doc/about.rst +++ b/doc/about.rst @@ -175,341 +175,18 @@ source directory. The color palette is available in the .. image:: images/scikit-learn-logo-notext.png :align: center -Funding -======= - -Scikit-learn is a community driven project, however institutional and private -grants help to assure its sustainability. - -The project would like to thank the following funders. - -................................... - -.. div:: sk-text-image-grid-small - - .. div:: text-box - - `:probabl. <https://probabl.ai>`_ manages the whole sponsorship program - and employs the full-time core maintainers Adrin Jalali, Arturo Amor, - François Goupil, Guillaume Lemaitre, Jérémie du Boisberranger, Loïc Estève, - Olivier Grisel, and Stefanie Senger. - - .. div:: image-box - - .. image:: images/probabl.png - :target: https://probabl.ai - :width: 40% - -.......... - -Active Sponsors -=============== - -Founding sponsors ------------------ - -.. div:: sk-text-image-grid-small - - .. div:: text-box - - `Inria <https://www.inria.fr>`_ supports scikit-learn through their - sponsorship. - - .. div:: image-box - - .. image:: images/inria-logo.jpg - :target: https://www.inria.fr - -.......... - -Gold sponsors -------------- - -.. div:: sk-text-image-grid-small - - .. div:: text-box - - `Chanel <https://www.chanel.com>`_ supports scikit-learn through their - sponsorship. - - .. div:: image-box - - .. image:: images/chanel.png - :target: https://www.chanel.com - -.......... - -Silver sponsors ---------------- - -.. div:: sk-text-image-grid-small - - .. div:: text-box - - `BNP Paribas Group <https://group.bnpparibas/>`_ supports scikit-learn - through their sponsorship. - - .. div:: image-box - - .. image:: images/bnp-paribas.jpg - :target: https://group.bnpparibas/ - -.......... - -Bronze sponsors ---------------- - -.. div:: sk-text-image-grid-small - - .. div:: text-box - - `NVIDIA <https://nvidia.com>`_ supports scikit-learn through their sponsorship and employs full-time core maintainer Tim Head. - - .. div:: image-box - - .. image:: images/nvidia.png - :target: https://nvidia.com - -.......... - -Other contributions -------------------- - -.. |chanel| image:: images/chanel.png - :target: https://www.chanel.com - -.. |axa| image:: images/axa.png - :target: https://www.axa.fr/ - -.. |bnp| image:: images/bnp.png - :target: https://www.bnpparibascardif.com/ - -.. |bnpparibasgroup| image:: images/bnp-paribas.jpg - :target: https://group.bnpparibas/ - -.. |dataiku| image:: images/dataiku.png - :target: https://www.dataiku.com/ - -.. |nvidia| image:: images/nvidia.png - :target: https://www.nvidia.com - -.. |inria| image:: images/inria-logo.jpg - :target: https://www.inria.fr - -.. raw:: html - - <style> - table.image-subtable tr { - border-color: transparent; - } - - table.image-subtable td { - width: 50%; - vertical-align: middle; - text-align: center; - } - - table.image-subtable td img { - max-height: 40px !important; - max-width: 90% !important; - } - </style> - - -* `Microsoft <https://microsoft.com/>`_ funds Andreas Müller since 2020. - - -* `Quansight Labs <https://labs.quansight.org>`_ funds Lucy Liu since 2022. -* `The Chan-Zuckerberg Initiative <https://chanzuckerberg.com/>`_ and - `Wellcome Trust <https://wellcome.org/>`_ fund scikit-learn through the - `Essential Open Source Software for Science (EOSS) <https://chanzuckerberg.com/eoss/>`_ - cycle 6. - - It supports Lucy Liu and diversity & inclusion initiatives that will - be announced in the future. - -* `Tidelift <https://tidelift.com/>`_ supports the project via their service - agreement. - -Past Sponsors -============= - -`Quansight Labs <https://labs.quansight.org>`_ funded Meekail Zain in 2022 and 2023, -and funded Thomas J. Fan from 2021 to 2023. - -`Columbia University <https://columbia.edu/>`_ funded Andreas Müller -(2016-2020). - -`The University of Sydney <https://sydney.edu.au/>`_ funded Joel Nothman -(2017-2021). - -Andreas Müller received a grant to improve scikit-learn from the -`Alfred P. Sloan Foundation <https://sloan.org>`_ . -This grant supported the position of Nicolas Hug and Thomas J. Fan. - -`INRIA <https://www.inria.fr>`_ has provided funding for Fabian Pedregosa -(2010-2012), Jaques Grobler (2012-2013) and Olivier Grisel (2013-2017) to -work on this project full-time. It also hosts coding sprints and other events. - -`Paris-Saclay Center for Data Science <http://www.datascience-paris-saclay.fr/>`_ -funded one year for a developer to work on the project full-time (2014-2015), 50% -of the time of Guillaume Lemaitre (2016-2017) and 50% of the time of Joris van den -Bossche (2017-2018). - -`NYU Moore-Sloan Data Science Environment <https://cds.nyu.edu/mooresloan/>`_ -funded Andreas Mueller (2014-2016) to work on this project. The Moore-Sloan -Data Science Environment also funds several students to work on the project -part-time. - -`Télécom Paristech <https://www.telecom-paristech.fr/>`_ funded Manoj Kumar -(2014), Tom Dupré la Tour (2015), Raghav RV (2015-2017), Thierry Guillemot -(2016-2017) and Albert Thomas (2017) to work on scikit-learn. - -`The Labex DigiCosme <https://digicosme.lri.fr>`_ funded Nicolas Goix -(2015-2016), Tom Dupré la Tour (2015-2016 and 2017-2018), Mathurin Massias -(2018-2019) to work part time on scikit-learn during their PhDs. It also -funded a scikit-learn coding sprint in 2015. - -`The Chan-Zuckerberg Initiative <https://chanzuckerberg.com/>`_ funded Nicolas -Hug to work full-time on scikit-learn in 2020. - -The following students were sponsored by `Google -<https://opensource.google/>`_ to work on scikit-learn through -the `Google Summer of Code <https://en.wikipedia.org/wiki/Google_Summer_of_Code>`_ -program. - -- 2007 - David Cournapeau -- 2011 - `Vlad Niculae`_ -- 2012 - `Vlad Niculae`_, Immanuel Bayer -- 2013 - Kemal Eren, Nicolas Trésegnie -- 2014 - Hamzeh Alsalhi, Issam Laradji, Maheshakya Wijewardena, Manoj Kumar -- 2015 - `Raghav RV <https://github.com/raghavrv>`_, Wei Xue -- 2016 - `Nelson Liu <https://nelsonliu.me>`_, `YenChen Lin <https://yenchenlin.me/>`_ - -.. _Vlad Niculae: https://vene.ro/ - -................... - -The `NeuroDebian <https://neuro.debian.net>`_ project providing `Debian -<https://www.debian.org/>`_ packaging and contributions is supported by -`Dr. James V. Haxby <http://haxbylab.dartmouth.edu/>`_ (`Dartmouth -College <https://pbs.dartmouth.edu/>`_). - -................... - -The following organizations funded the scikit-learn consortium at Inria in -the past: - -.. |msn| image:: images/microsoft.png - :target: https://www.microsoft.com/ - -.. |bcg| image:: images/bcg.png - :target: https://www.bcg.com/beyond-consulting/bcg-gamma/default.aspx - -.. |fujitsu| image:: images/fujitsu.png - :target: https://www.fujitsu.com/global/ - -.. |aphp| image:: images/logo_APHP_text.png - :target: https://aphp.fr/ - -.. |hf| image:: images/huggingface_logo-noborder.png - :target: https://huggingface.co - -.. raw:: html - - <style> - div.image-subgrid img { - max-height: 50px; - max-width: 90%; - } - </style> - -.. grid:: 2 2 4 4 - :class-row: image-subgrid - :gutter: 1 - - .. grid-item:: - :class: sd-text-center - :child-align: center - - |msn| - - .. grid-item:: - :class: sd-text-center - :child-align: center - - |bcg| - - .. grid-item:: - :class: sd-text-center - :child-align: center - - |fujitsu| - - .. grid-item:: - :class: sd-text-center - :child-align: center - - |aphp| - - .. grid-item:: - :class: sd-text-center - :child-align: center - - |hf| - - .. grid-item:: - :class: sd-text-center - :child-align: center - - |dataiku| - - .. grid-item:: - :class: sd-text-center - :child-align: center - - |bnp| - - .. grid-item:: - :class: sd-text-center - :child-align: center - - |axa| +Institutional support +===================== +scikit-learn is a community driven project, however institutional and private +grants help to assure its sustainability. -Donations in Kind ------------------ -The following organizations provide non-financial contributions to the -scikit-learn project. - -.. raw:: html - - <table cellspacing="0" cellpadding="8"> - <thead> - <tr> - <th>Company</th> - <th>Contribution</th> - </tr> - </thead> - <tbody> - <tr> - <td><a href="https://www.anaconda.com">Anaconda Inc</a></td> - <td>Storage for our staging and nightly builds</td> - </tr> - <tr> - <td><a href="https://circleci.com/">CircleCI</a></td> - <td>CPU time on their Continuous Integration servers</td> - </tr> - <tr> - <td><a href="https://www.github.com">GitHub</a></td> - <td>CPU time on their Continuous Integration servers + Teams account</td> - </tr> - </tbody> - </table> +More details about institutional support are available in the :ref:`funding` +section. Coding Sprints --------------- +============== The scikit-learn project has a long history of `open source coding sprints <https://blog.scikit-learn.org/events/sprints-value/>`_ with over 50 sprint @@ -518,52 +195,6 @@ to costs which include venue, food, travel, developer time and more. See `scikit-learn sprints <https://blog.scikit-learn.org/sprints/>`_ for a full list of events. -Donating to the project -======================= - -If you have found scikit-learn to be useful in your work, research, or company, -please consider making a donation to the project commensurate with your resources. -There are several options for making donations: - -.. raw:: html - - <p class="text-center"> - <a class="btn sk-btn-orange mb-1" href="https://numfocus.org/donate-to-scikit-learn"> - Donate via NumFOCUS - </a> - <a class="btn sk-btn-orange mb-1" href="https://github.com/sponsors/scikit-learn"> - Donate via GitHub Sponsors - </a> - <a class="btn sk-btn-orange mb-1" href="https://causes.benevity.org/projects/433725"> - Donate via Benevity - </a> - </p> - -**Donation Options:** - -* **NumFOCUS**: Donate via the `NumFOCUS Donations Page - <https://numfocus.org/donate-to-scikit-learn>`_, scikit-learn's fiscal sponsor. - -* **GitHub Sponsors**: Support the project directly through `GitHub Sponsors - <https://github.com/sponsors/scikit-learn>`_. - -* **Benevity**: If your company uses scikit-learn, you can also support the - project through Benevity, a platform to manage employee donations. It is - widely used by hundreds of Fortune 1000 companies to streamline and scale - their social impact initiatives. If your company uses Benevity, you are - able to make a donation with a company match as high as 100%. Our project - ID is `433725 <https://causes.benevity.org/projects/433725>`_. - -All donations are managed by `NumFOCUS <https://numfocus.org/>`_, a 501(c)(3) -non-profit organization based in Austin, Texas, USA. The NumFOCUS board -consists of `SciPy community members <https://numfocus.org/board.html>`_. -Contributions are tax-deductible to the extent allowed by law. - -.. rubric:: Notes - -Contributions support the maintenance of the project, including development, -documentation, infrastructure and coding sprints. - scikit-learn Swag ----------------- diff --git a/doc/conf.py b/doc/conf.py index dbeaaca45ab28..57764eaffd9e1 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -289,11 +289,11 @@ "secondary_sidebar_items": { "**": [ "page-toc", - "sourcelink", # Sphinx-Gallery-specific sidebar components # https://sphinx-gallery.github.io/stable/advanced.html#using-sphinx-gallery-sidebar-components "sg_download_links", "sg_launcher_links", + "funding_links", ], }, "show_version_warning_banner": True, @@ -338,6 +338,7 @@ "roadmap": [], "governance": [], "about": [], + "institutional_support": [], } # Additional templates that should be rendered to pages, maps page names to diff --git a/doc/images/bnp-paribas-small.png b/doc/images/bnp-paribas-small.png new file mode 100644 index 0000000000000000000000000000000000000000..158d30819b14d0ae88bf95c7e7ddfe141af6e269 GIT binary patch literal 4537 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 E12`*UqW}N^ literal 0 HcmV?d00001 diff --git a/doc/images/bnp-paribas.jpg b/doc/images/bnp-paribas.jpg deleted file mode 100644 index e9fea64acbce69061df25870d19fbab43d7f92a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48732 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 Y*!Fk-Tax>~Mau49`Tym2#D53>2PVS-vj6}9 diff --git a/doc/images/bnp-paribas.png b/doc/images/bnp-paribas.png new file mode 100644 index 0000000000000000000000000000000000000000..fa4f25327d689ab0ade7d64369b78b6babc9219b GIT binary patch literal 232229 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 z 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 literal 0 HcmV?d00001 diff --git a/doc/images/michelin-small.png b/doc/images/michelin-small.png new file mode 100644 index 0000000000000000000000000000000000000000..3faabdc8b2cf313aa3a39ba944326c9bf811b219 GIT binary patch literal 4636 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 IoOQnPf2SJ@(f|Me literal 0 HcmV?d00001 diff --git a/doc/images/michelin.png b/doc/images/michelin.png new file mode 100644 index 0000000000000000000000000000000000000000..20f9d8b77ab1dee1b2de7327093701e39d80c42b GIT binary patch literal 46959 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 literal 0 HcmV?d00001 diff --git a/doc/images/nasa-small.png b/doc/images/nasa-small.png new file mode 100644 index 0000000000000000000000000000000000000000..ef5ba6a592e925441378cea515b3299fa9165530 GIT binary patch literal 5025 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 literal 0 HcmV?d00001 diff --git a/doc/images/nasa.png b/doc/images/nasa.png new file mode 100644 index 0000000000000000000000000000000000000000..1ca3d2c4529e07b7bb60c9263d819febe2e4bbb9 GIT binary patch literal 25668 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 L^?fbKEaZOxlDe~I literal 0 HcmV?d00001 diff --git a/doc/index.rst.template b/doc/index.rst.template index f1f1f49836515..fbfd73cf10d9d 100644 --- a/doc/index.rst.template +++ b/doc/index.rst.template @@ -21,4 +21,5 @@ related_projects roadmap Governance <governance> + institutional_support about diff --git a/doc/institutional_support.rst b/doc/institutional_support.rst new file mode 100644 index 0000000000000..ad84c4cc29ddc --- /dev/null +++ b/doc/institutional_support.rst @@ -0,0 +1,281 @@ +.. _funding: + +Institutional support +===================== + +Scikit-learn is a community driven project. However, a number of public +institutions and private entities have contributed and keep on contributing to +its success and sustainability. + +.. div:: sk-text-image-grid-small + + .. div:: image-box + + .. image:: images/inria-logo.jpg + :target: https://www.inria.fr + + .. div:: text-box + + Since the inception of scikit-learn and for a good decade, `Inria + <https://www.inria.fr>`_ has been its main supporting pillar, as the stable + employer of many core-maintainers and as the host for the scikit-learn + consortium. + +.. div:: sk-text-image-grid-small + + .. div:: image-box + + .. image:: images/probabl.png + :target: https://probabl.ai + + .. div:: text-box + + In 2023, Inria spun off `Probabl <https://probabl.ai>`_ as a mission driven + company to take scikit-learn beyond a research lab. All of the + scikit-learn core-maintainers employed by Inria have joined the spinoff as + co-founders, most as full-time employees. + + Today, Probabl employs the following core and non-core contributors: Adrin + Jalali, Antoine Baker, Arturo Amor, François Goupil, Guillaume Lemaitre, + Jérémie du Boisberranger, Loïc Estève, Olivier Grisel, Shruti Nath and + Stefanie Senger, as well as Gaël Varoquaux. + +The above financial commitments mean that Inria initially and now Probabl have +been and are the main source of financial support for scikit-learn, completed +by additional commitments detailed below. Cumulatively over a decade, these +represent several millions of euros or dollars worth of financial +participation. + + +Active financial participation (2026) +------------------------------------- + +In addition to the above financial commitments, the following organizations +financially support scikit-learn as follows: + +.. |probabl| image:: images/probabl.png + :target: https://probabl.ai + +.. |wellcome| image:: images/wellcome-trust-small.png + :target: https://wellcome.org + +.. |czi| image:: images/czi-small.png + :target: https://chanzuckerberg.com + +.. |nvidia| image:: images/nvidia-small.png + :target: https://www.nvidia.com + +.. |nasa| image:: images/nasa-small.png + :target: https://www.nasa.gov + +.. |chanel| image:: images/chanel-small.png + :target: https://www.chanel.com + +.. |bnpparibasgroup| image:: images/bnp-paribas-small.png + :target: https://group.bnpparibas/ + +.. |quansightlabs| image:: images/quansight-labs-small.png + :target: https://labs.quansight.org + +.. |michelin| image:: images/michelin-small.png + :target: https://www.michelin.com + +.. list-table:: + :widths: 33 33 34 + :header-rows: 1 + :class: sk-funding-participation-table + + * - 5 FTE or more + - 0.5 FTE or more + - less than 0.5 FTE + * - |probabl| + - * |czi| |wellcome| + * |nvidia| + * |nasa| |quansightlabs| + * |chanel| + - * |bnpparibasgroup| + * |michelin| + +FTE stands for Full-Time Equivalent. + +* `The Chan-Zuckerberg Initiative <https://chanzuckerberg.com/>`_ and `Wellcome + Trust <https://wellcome.org/>`_ support the work of Lucy Liu, Dea Maria Leon, + Anne Beyer and Francois Paugam through the `Essential Open Source Software + for Science (EOSS) <https://chanzuckerberg.com/eoss/>`_ cycle 6. + +* `NVIDIA <https://nvidia.com>`_ supports scikit-learn through their + sponsorship and employs full-time core maintainer Tim Head. + +* `NASA <https://www.nasa.gov>`_ supports work done by Quansight Labs and + Probabl team members via the NASA ROSES grant 80NSSC25K7215: "Ensuring a fast + and secure core for scientific Python". + +* `Quansight Labs <https://labs.quansight.org>`_ funds Lucy Liu since 2022. + +* `Chanel <https://www.chanel.com>`_ supports scikit-learn through a + multi-year sponsorship, initially through the Inria foundation (2023-2024), + now as a Gold Sponsor via Probabl (2024-2026). + +* `BNP Paribas Group <https://group.bnpparibas/>`_ supports scikit-learn + as a Silver Sponsor via Probabl (2025-2026). + +* `Michelin <https://www.michelin.com>`_ supports scikit-learn as a Bronze + Sponsor via Probabl (2025-2026). + +Past Sponsors +------------- + +`Microsoft <https://microsoft.com/>`_ funded Andreas Müller from 2020 to 2026. + +`APHP <https://aphp.fr/>`_, `AXA <https://www.axa.fr/>`_, `BCG +<https://www.bcg.com/>`_, `BNP-Paribas-Cardiff +<https://www.bnpparibascardif.com/>`_, `Dataiku <https://www.dataiku.com/>`_, +`Fujitsu <https://www.fujitsu.com/>`_, `Hugging Face +<https://huggingface.co/>`_, `Intel <https://www.intel.com/>`_, `Microsoft +<https://microsoft.com/>`_, `NVIDIA <https://nvidia.com>`_ supported the +project through their sponsorship via the Inria foundation between 2020 and +2024. + +`Tidelift <https://tidelift.com/>`_ financially supported the project via their +service agreement from 2023 to 2025. + +`Quansight Labs <https://labs.quansight.org>`_ and `NASA +<https://www.nasa.gov>`_ funded Meekail Zain in 2022 and 2023, and funded +Thomas J. Fan from 2021 to 2023 via the NASA ROSES grant 80NSSC22K0405: +"Reinforcing the Foundations of Scientific Python". + +`Columbia University <https://columbia.edu/>`_ funded Andreas Müller +(2016-2020). + +`The University of Sydney <https://sydney.edu.au/>`_ funded Joel Nothman +(2017-2021). + +Andreas Müller received a grant to improve scikit-learn from the +`Alfred P. Sloan Foundation <https://sloan.org>`_ . +This grant supported the position of Nicolas Hug and Thomas J. Fan. + +`INRIA <https://www.inria.fr>`_ has provided funding for Fabian Pedregosa +(2010-2012), Jaques Grobler (2012-2013) and Olivier Grisel (2013-2017) to +work on this project full-time. It also hosts coding sprints and other events. + +`Paris-Saclay Center for Data Science <http://www.datascience-paris-saclay.fr/>`_ +funded one year for a developer to work on the project full-time (2014-2015), 50% +of the time of Guillaume Lemaitre (2016-2017) and 50% of the time of Joris van den +Bossche (2017-2018). + +`NYU Moore-Sloan Data Science Environment <https://cds.nyu.edu/mooresloan/>`_ +funded Andreas Mueller (2014-2016) to work on this project. The Moore-Sloan +Data Science Environment also funds several students to work on the project +part-time. + +`Télécom Paristech <https://www.telecom-paristech.fr/>`_ funded Manoj Kumar +(2014), Tom Dupré la Tour (2015), Raghav RV (2015-2017), Thierry Guillemot +(2016-2017) and Albert Thomas (2017) to work on scikit-learn. + +`The Labex DigiCosme <https://digicosme.lri.fr>`_ funded Nicolas Goix +(2015-2016), Tom Dupré la Tour (2015-2016 and 2017-2018), Mathurin Massias +(2018-2019) to work part time on scikit-learn during their PhDs. It also +funded a scikit-learn coding sprint in 2015. + +`The Chan-Zuckerberg Initiative <https://chanzuckerberg.com/>`_ funded Nicolas +Hug to work full-time on scikit-learn in 2020. + +The following students were sponsored by `Google +<https://opensource.google/>`_ to work on scikit-learn through +the `Google Summer of Code <https://en.wikipedia.org/wiki/Google_Summer_of_Code>`_ +program. + +- 2007 - David Cournapeau +- 2011 - `Vlad Niculae`_ +- 2012 - `Vlad Niculae`_, Immanuel Bayer +- 2013 - Kemal Eren, Nicolas Trésegnie +- 2014 - Hamzeh Alsalhi, Issam Laradji, Maheshakya Wijewardena, Manoj Kumar +- 2015 - `Raghav RV <https://github.com/raghavrv>`_, Wei Xue +- 2016 - `Nelson Liu <https://nelsonliu.me>`_, `YenChen Lin <https://yenchenlin.me/>`_ + +.. _Vlad Niculae: https://vene.ro/ + +................... + +The `NeuroDebian <https://neuro.debian.net>`_ project providing `Debian +<https://www.debian.org/>`_ packaging and contributions is supported by +`Dr. James V. Haxby <http://haxbylab.dartmouth.edu/>`_ (`Dartmouth +College <https://pbs.dartmouth.edu/>`_). + + +Donating to the project +----------------------- + +If you have found scikit-learn to be useful in your work, research, or company, +please consider making a donation to the project commensurate with your resources. +There are several options for making donations: + +.. raw:: html + + <p class="text-center"> + <a class="btn sk-btn-orange mb-1" href="https://numfocus.org/donate-to-scikit-learn"> + Donate via NumFOCUS + </a> + <a class="btn sk-btn-orange mb-1" href="https://github.com/sponsors/scikit-learn"> + Donate via GitHub Sponsors + </a> + <a class="btn sk-btn-orange mb-1" href="https://causes.benevity.org/projects/433725"> + Donate via Benevity + </a> + </p> + +**Donation Options:** + +* **NumFOCUS**: Donate via the `NumFOCUS Donations Page + <https://numfocus.org/donate-to-scikit-learn>`_, scikit-learn's fiscal sponsor. + +* **GitHub Sponsors**: Support the project directly through `GitHub Sponsors + <https://github.com/sponsors/scikit-learn>`_. + +* **Benevity**: If your company uses scikit-learn, you can also support the + project through Benevity, a platform to manage employee donations. It is + widely used by hundreds of Fortune 1000 companies to streamline and scale + their social impact initiatives. If your company uses Benevity, you are + able to make a donation with a company match as high as 100%. Our project + ID is `433725 <https://causes.benevity.org/projects/433725>`_. + +All above donation options are managed by `NumFOCUS <https://numfocus.org/>`_, +a 501(c)(3) non-profit organization based in Austin, Texas, USA. The NumFOCUS +board consists of `SciPy community members <https://numfocus.org/board.html>`_. +Contributions are tax-deductible to the extent allowed by law. + +.. rubric:: Notes + +Contributions support the maintenance of the project, including development, +documentation, infrastructure and coding sprints. + + +Donations in kind +================= +The following organizations provide non-financial contributions to the +scikit-learn project. + +.. raw:: html + + <table cellspacing="0" cellpadding="8"> + <thead> + <tr> + <th>Company</th> + <th>Contribution</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="https://www.github.com">GitHub</a></td> + <td>CPU time on their Continuous Integration servers + Teams account and web hosting.</td> + </tr> + <tr> + <td><a href="https://circleci.com/">CircleCI</a></td> + <td>CPU time on their Continuous Integration servers</td> + </tr> + <tr> + <td><a href="https://www.anaconda.com">Anaconda Inc</a></td> + <td>Storage for our staging and nightly builds</td> + </tr> + </tbody> + </table> diff --git a/doc/scss/custom.scss b/doc/scss/custom.scss index a59c903f839eb..2dd8608c18802 100644 --- a/doc/scss/custom.scss +++ b/doc/scss/custom.scss @@ -216,13 +216,18 @@ div.sk-authors-container { @mixin sk-text-image-grid($img-max-height) { display: flex; - align-items: center; + align-items: flex-start; flex-wrap: wrap; - div.text-box, - div.image-box { - width: 50%; + div.text-box { + width: 65%; + @media screen and (max-width: 500px) { + width: 100%; + } + } + div.image-box { + width: 35%; @media screen and (max-width: 500px) { width: 100%; } @@ -252,6 +257,52 @@ div.sk-text-image-grid-large { @include sk-text-image-grid(100px); } +/* Institutional support: active funding participation table (institutional_support.rst) */ + +.bd-article table.sk-funding-participation-table { + width: 100%; + border-collapse: collapse; + --bs-table-striped-bg: #fff; + --bs-table-hover-bg: #fff; + --bs-table-active-bg: #fff; + tbody, + tr, + td { + } + + th, + td { + padding: 0.75rem 0.5rem; + border: 1px solid var(--pst-color-border); + text-align: center; + } + + li { + list-style: none !important; + list-style-type: none !important; + margin: 0.5rem !important; + } + + img { + height: 40px !important; + padding: 5px; + } +} + +/* Funding sidebar secondary panel (doc/templates/funding_links.html) */ + +.sk-funding-sidepanel { + margin-top: 1.25rem; + + .sk-funding-logos img { + max-width: 80%; + padding: 5px; + height: auto !important; + width: auto; + display: inline-block; + } +} + /* Responsive three-column grid list */ .grid-list-three-columns { display: grid; diff --git a/doc/scss/index.scss b/doc/scss/index.scss index c3bb8e86b41c6..7888dbc40979f 100644 --- a/doc/scss/index.scss +++ b/doc/scss/index.scss @@ -150,23 +150,14 @@ div.sk-landing-more-info { } } -/* Footer */ +/* Funding section */ -div.sk-landing-footer { - a.sk-footer-funding-link { +div.sk-landing-funding { + a.sk-funding-link { text-decoration: none; - p.sk-footer-funding-text { - color: var(--pst-color-link); - - &:hover { - color: var(--pst-color-secondary); - } - } - - div.sk-footer-funding-logos > img { - max-height: 40px; - max-width: 85px; + div.sk-funding-logos > img { + height: 40px; margin: 0 8px 8px 8px; padding: 5px; border-radius: 3px; diff --git a/doc/templates/funding_links.html b/doc/templates/funding_links.html new file mode 100644 index 0000000000000..b61c359c290e8 --- /dev/null +++ b/doc/templates/funding_links.html @@ -0,0 +1,16 @@ +<div class="sk-funding-sidepanel"> + <hr/> + <p>scikit-learn is <a href="{{ pathto('institutional_support') + }}#funding">financially supported</a> by Probabl and other + institutions.</p> + <div> + <div class="text-center"> + <a href="https://probabl.ai/lp/scikit-learn"> + <div class="sk-funding-logos"> + <img src="{{ pathto('_static/probabl.png', 1) }}" title="Probabl"> + </div> + <p>Enterprise-grade solutions and services</p> + </a> + </div> + </div> +</div> diff --git a/doc/templates/index.html b/doc/templates/index.html index b208e2f9981d2..55b7a80883fd6 100644 --- a/doc/templates/index.html +++ b/doc/templates/index.html @@ -199,6 +199,47 @@ <h4 class="sk-card-title card-title sk-vert-align" sk-align-name="title"> {% block footer %} +<div class="container-fluid sk-landing-funding py-3"> + <div class="container sk-landing-container bd-page-width"> + <div class="text-center"> + <p class="mt-2 sk-footer-funding-text"> + scikit-learn is made possible by the support of organizations and + individuals committed to open source machine learning. + </p> + </div> + <div class="row"> + <div class="col-md-4"> + <a class="sk-funding-link" href="https://probabl.ai/lp/scikit-learn"> + <div class="text-center"> + <div class="sk-funding-logos"> + <img src="_static/probabl.png" title="Probabl"> + </div> + <p>Probabl: Enterprise-grade solutions and services</p> + </div> + </a> + </div> + <div class="col-md-8"> + <a class="sk-funding-link" href="institutional_support.html#funding"> + <div class="text-center"> + <div class="sk-funding-logos"> + <img src="_static/inria-small.png" title="Inria"> + <img src="_static/czi-small.png" title="Chan Zuckerberg Initiative"> + <img src="_static/wellcome-trust-small.png" title="Wellcome Trust"> + <img src="_static/nvidia-small.png" title="NVIDIA"> + <img src="_static/nasa-small.png" title="NASA"> + <img src="_static/quansight-labs-small.png" title="Quansight Labs"> + <img src="_static/chanel-small.png" title="Chanel"> + <img src="_static/bnp-paribas-small.png" title="BNP Paribas Group"> + <img src="_static/michelin-small.png" title="Michelin"> + </div> + <p>Learn more about scikit-learn's financial support.</p> + </div> + </a> + </div> + </div> + </div> +</div> + <div class="container-fluid sk-landing-more-info py-3"> <div class="container sk-landing-container bd-page-width"> <div class="row"> @@ -282,29 +323,6 @@ <h4 class="sk-landing-call-header">Who uses scikit-learn?</h4> </div> </div> -<div class="container-fluid sk-landing-footer py-3"> - <div class="container sk-landing-container"> - <a class="sk-footer-funding-link" href="about.html#funding"> - <div class="text-center"> - <p class="mt-2 sk-footer-funding-text"> - scikit-learn development and maintenance are financially supported by - </p> - <div class="sk-footer-funding-logos"> - <img src="_static/probabl.png" title="Probabl"> - <img src="_static/inria-small.png" title="INRIA"> - <img src="_static/chanel-small.png" title="Chanel"> - <img src="_static/bnp-small.png" title="BNP Paribas Group"> - <img src="_static/microsoft-small.png" title="Microsoft"> - <img src="_static/nvidia-small.png" title="Nvidia"> - <img src="_static/quansight-labs-small.png" title="Quansight Labs"> - <img src="_static/czi-small.png" title="Chan Zuckerberg Initiative"> - <img src="_static/wellcome-trust-small.png" title="Wellcome Trust"> - </div> - </div> - </a> - </div> -</div> - {% endblock footer %} {%- block scripts_end %} From 4b5f3f91b4a1cf8760f723a132231a77831f25f1 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Tue, 5 May 2026 20:51:04 +0200 Subject: [PATCH 431/462] API Deprecate n_alphas in lasso_path and enet_path (#33855) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.linear_model/33855.api.rst | 9 ++ sklearn/linear_model/_coordinate_descent.py | 121 +++++++++++++++--- .../tests/test_coordinate_descent.py | 24 +++- 3 files changed, 132 insertions(+), 22 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33855.api.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33855.api.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33855.api.rst new file mode 100644 index 0000000000000..3ad6d0374fc3e --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33855.api.rst @@ -0,0 +1,9 @@ +- The parameter `n_alphas` has been deprecated for + :func:`linear_model.lasso_path` and :func:`linear_model.enet_path`. + This deprecation follows the same deprecation that has happened for + :class:`linear_model.ElasticNetCV` and :class:`linear_model.LassoCV`. + The parameter `alphas` now supports both integers and array-likes, removing the need + for `n_alphas`. From now on, only `alphas` should be set, either to and integer to + indicate the number of automatically generated alphas or to an array-like of values + for the regularization path. + By :user:`Christian Lorentzen <lorentzenchr>`. diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index f704f6af052cc..afbbc67308d6c 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -28,6 +28,7 @@ _raise_for_params, ) from sklearn.utils._param_validation import ( + Hidden, Interval, StrOptions, validate_params, @@ -212,8 +213,17 @@ def _alpha_grid( "X": ["array-like", "sparse matrix"], "y": ["array-like", "sparse matrix"], "eps": [Interval(Real, 0, None, closed="neither")], - "n_alphas": [Interval(Integral, 1, None, closed="left")], - "alphas": ["array-like", None], + "n_alphas": [ + Interval(Integral, 1, None, closed="left"), + Hidden(StrOptions({"deprecated"})), + ], + # TODO(1.11): remove "warn" and None options. + "alphas": [ + Interval(Integral, 1, None, closed="left"), + "array-like", + None, + Hidden(StrOptions({"warn"})), + ], "precompute": [StrOptions({"auto"}), "boolean", "array-like"], "Xy": ["array-like", None], "copy_X": ["boolean"], @@ -229,8 +239,8 @@ def lasso_path( y, *, eps=1e-3, - n_alphas=100, - alphas=None, + n_alphas="deprecated", + alphas="warn", precompute="auto", Xy=None, copy_X=True, @@ -383,13 +393,46 @@ def lasso_path( [[0. 0. 0.46915237] [0.2159048 0.4425765 0.23668876]] """ + # TODO(1.11): remove n_alphas and alphas={"warn", None}; set alphas=100 by default. + # Remove these deprecations messages and use alphas directly instead of instead of + # _alphas. + if n_alphas == "deprecated": + _alphas = 100 # the old, current, and future default;-) + else: + warnings.warn( + "'n_alphas' was deprecated in 1.9 and will be removed in 1.11. " + "'alphas' now accepts an integer value which removes the need to pass " + "'n_alphas'. The default value of 'alphas' will change from None to " + "100 in 1.11. Pass an explicit value to 'alphas' and leave 'n_alphas' " + "to its default value to silence this warning.", + FutureWarning, + ) + _alphas = n_alphas + + if isinstance(alphas, str) and alphas == "warn": + # - If n_alphas == "deprecated", both are left to their default values so we + # don't warn since the future default behavior will be the same as the + # current default behavior. + # - self.n_alphas != "deprecated", then we already warned about it and the + # warning message mentions the future alphas default, so no need to warn a + # second time. + pass + elif alphas is None: + warnings.warn( + "'alphas=None' is deprecated and will be removed in 1.11, at which " + "point the default value will be set to 100. Set 'alphas=100' " + "to silence this warning.", + FutureWarning, + ) + else: + _alphas = alphas + return enet_path( X, y, l1_ratio=1.0, eps=eps, - n_alphas=n_alphas, - alphas=alphas, + alphas=_alphas, precompute=precompute, Xy=Xy, copy_X=copy_X, @@ -407,8 +450,17 @@ def lasso_path( "y": ["array-like", "sparse matrix"], "l1_ratio": [Interval(Real, 0.0, 1.0, closed="both")], "eps": [Interval(Real, 0.0, None, closed="neither")], - "n_alphas": [Interval(Integral, 1, None, closed="left")], - "alphas": ["array-like", None], + "n_alphas": [ + Interval(Integral, 1, None, closed="left"), + Hidden(StrOptions({"deprecated"})), + ], + # TODO(1.11): remove "warn" and None options. + "alphas": [ + Interval(Integral, 1, None, closed="left"), + "array-like", + None, + Hidden(StrOptions({"warn"})), + ], "precompute": [StrOptions({"auto"}), "boolean", "array-like"], "Xy": ["array-like", None], "copy_X": ["boolean"], @@ -426,8 +478,8 @@ def enet_path( *, l1_ratio=0.5, eps=1e-3, - n_alphas=100, - alphas=None, + n_alphas="deprecated", + alphas="warn", precompute="auto", Xy=None, copy_X=True, @@ -566,7 +618,7 @@ def enet_path( ... ) >>> true_coef array([ 0. , 0. , 0. , 97.9, 45.7]) - >>> alphas, estimated_coef, _ = enet_path(X, y, n_alphas=3) + >>> alphas, estimated_coef, _ = enet_path(X, y, alphas=3) >>> alphas.shape (3,) >>> estimated_coef @@ -576,6 +628,40 @@ def enet_path( [ 0., 23.046, 88.939], [ 0., 10.637, 41.566]]) """ + # TODO(1.11): remove n_alphas and alphas={"warn", None}; set alphas=100 by default. + # Remove these deprecations messages and use alphas directly instead of instead of + # _alphas. + if n_alphas == "deprecated": + _alphas = 100 # the old, current, and future default;-) + else: + warnings.warn( + "'n_alphas' was deprecated in 1.9 and will be removed in 1.11. " + "'alphas' now accepts an integer value which removes the need to pass " + "'n_alphas'. The default value of 'alphas' will change from None to " + "100 in 1.11. Pass an explicit value to 'alphas' and leave 'n_alphas' " + "to its default value to silence this warning.", + FutureWarning, + ) + _alphas = n_alphas + + if isinstance(alphas, str) and alphas == "warn": + # - If n_alphas == "deprecated", both are left to their default values so we + # don't warn since the future default behavior will be the same as the + # current default behavior. + # - self.n_alphas != "deprecated", then we already warned about it and the + # warning message mentions the future alphas default, so no need to warn a + # second time. + pass + elif alphas is None: + warnings.warn( + "'alphas=None' is deprecated and will be removed in 1.11, at which " + "point the default value will be set to 100. Set 'alphas=100' " + "to silence this warning.", + FutureWarning, + ) + else: + _alphas = alphas + X_offset_param = params.pop("X_offset", None) X_scale_param = params.pop("X_scale", None) sample_weight = params.pop("sample_weight", None) @@ -646,7 +732,7 @@ def enet_path( copy=False, check_gram=check_input, ) - if alphas is None: + if isinstance(_alphas, Integral): # fit_intercept and sample_weight have already been dealt with in calling # methods like ElasticNet.fit. alphas = _alpha_grid( @@ -657,10 +743,10 @@ def enet_path( fit_intercept=False, positive=positive, eps=eps, - n_alphas=n_alphas, + n_alphas=_alphas, ) - elif len(alphas) > 1: - alphas = np.sort(alphas)[::-1] # make sure alphas are properly ordered + elif len(_alphas) > 1: + alphas = np.sort(_alphas)[::-1] # make sure alphas are properly ordered n_alphas = len(alphas) dual_gaps = np.empty(n_alphas) @@ -1162,7 +1248,6 @@ def fit(self, X, y, sample_weight=None, check_input=True): y[:, k], l1_ratio=self.l1_ratio, eps=None, - n_alphas=None, alphas=[self.alpha], precompute=precompute, Xy=this_Xy, @@ -1809,10 +1894,6 @@ def fit(self, X, y, sample_weight=None, **params): # Making sure alphas is properly ordered. alphas = np.tile(np.sort(self.alphas)[::-1], (n_l1_ratio, 1)) - # We want n_alphas to be the number of alphas used for each l1_ratio. - n_alphas = len(alphas[0]) - path_params.update({"n_alphas": n_alphas}) - path_params["copy_X"] = copy_X # We are not computing in parallel, we can modify X # inplace in the folds diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index 02a3d358cf732..e1e5292f48ef9 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -968,7 +968,7 @@ def test_check_input_false(): X, y, _, _ = build_dataset(n_samples=20, n_features=10) X = check_array(X, order="F", dtype="float64") y = check_array(X, order="F", dtype="float64") - clf = ElasticNet(selection="cyclic", tol=1e-7) + clf = ElasticNet(selection="cyclic", tol=1e-6) # Check that no error is raised if data is provided in the right format clf.fit(X, y, check_input=False) # With check_input=False, an exhaustive check is not made on y but its @@ -1772,4 +1772,24 @@ def test_enet_path_check_input_false(precompute): """Test enet_path works with check_input=False and various precompute settings.""" X, y = make_regression(n_samples=100, n_features=5, n_informative=2, random_state=0) X = np.asfortranarray(X) - alphas, _, _ = enet_path(X, y, n_alphas=3, check_input=False, precompute=precompute) + alphas, _, _ = enet_path(X, y, alphas=3, check_input=False, precompute=precompute) + + +# TODO(1.11): remove +@pytest.mark.parametrize("path_func", [lasso_path, enet_path]) +def test_path_function_deprecated_n_alphas(path_func): + """Check deprecation of n_alphas in favor of alphas.""" + X, y = make_regression(n_samples=9, n_features=5, n_informative=2, random_state=42) + + msg = "'n_alphas' was deprecated in 1.9 and will be removed in 1.11" + with pytest.warns(FutureWarning, match=msg): + path_func(X, y, n_alphas=5) + + msg = "'alphas=None' is deprecated and will be removed in 1.11" + with pytest.warns(FutureWarning, match=msg): + path_func(X, y, alphas=None) + + # Assert that no warning is raised when n_alphas is not used. + with warnings.catch_warnings(): + warnings.simplefilter("error") + path_func(X, y, alphas=5) From 21eb2ba4c6d21a078b802df1eba72c3973f9928d Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Tue, 5 May 2026 21:00:51 +0200 Subject: [PATCH 432/462] DOC Update Nearest Centroid DecisionBoundaryDisplay example (#33883) --- examples/neighbors/plot_nearest_centroid.py | 23 +++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/examples/neighbors/plot_nearest_centroid.py b/examples/neighbors/plot_nearest_centroid.py index 1718e213f9252..71d45a1b03460 100644 --- a/examples/neighbors/plot_nearest_centroid.py +++ b/examples/neighbors/plot_nearest_centroid.py @@ -3,14 +3,14 @@ Nearest Centroid Classification =============================== -Sample usage of Nearest Centroid classification. +Sample usage of the :ref:`nearest_centroid_classifier` with different shrink thresholds. It will plot the decision boundaries for each class. """ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause - +# %% import matplotlib.pyplot as plt import numpy as np from matplotlib.colors import ListedColormap @@ -26,25 +26,26 @@ X = iris.data[:, :2] y = iris.target -# Create color maps -cmap_light = ListedColormap(["orange", "cyan", "cornflowerblue"]) -cmap_bold = ListedColormap(["darkorange", "c", "darkblue"]) - for shrinkage in [None, 0.2]: # we create an instance of Nearest Centroid Classifier and fit the data. clf = NearestCentroid(shrink_threshold=shrinkage) clf.fit(X, y) y_pred = clf.predict(X) - print(shrinkage, np.mean(y == y_pred)) + acc = np.mean(y == y_pred) _, ax = plt.subplots() - DecisionBoundaryDisplay.from_estimator( - clf, X, cmap=cmap_light, ax=ax, response_method="predict" + disp = DecisionBoundaryDisplay.from_estimator( + clf, X, ax=ax, response_method="predict", alpha=0.5 ) # Plot also the training points - plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold, edgecolor="k", s=20) - plt.title("3-Class classification (shrink_threshold=%r)" % shrinkage) + cmap = ListedColormap(disp.multiclass_colors_) + plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap, edgecolor="k", s=20) + plt.title( + f"3-Class classification (shrink_threshold={shrinkage})\nAccuracy: {acc:.2f}" + ) plt.axis("tight") plt.show() + +# %% From e73515894a265663e8f0f83dcb55f23dc93bd3a0 Mon Sep 17 00:00:00 2001 From: Kunle <67528514+unw9527@users.noreply.github.com> Date: Tue, 5 May 2026 15:13:42 -0400 Subject: [PATCH 433/462] FIX Slice Y_norm_squared alongside Y in _parallel_pairwise (#33876) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../sklearn.metrics/33876.fix.rst | 3 +++ sklearn/metrics/pairwise.py | 11 ++++++++++- sklearn/metrics/tests/test_pairwise.py | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/33876.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/33876.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/33876.fix.rst new file mode 100644 index 0000000000000..55a452d12134e --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.metrics/33876.fix.rst @@ -0,0 +1,3 @@ +- :func:`metrics.pairwise.pairwise_distances` no longer raises an error for the + euclidean metric when called with `Y_norm_squared` and `n_jobs > 1`. + By :user:`Kunle Li <unw9527>`. diff --git a/sklearn/metrics/pairwise.py b/sklearn/metrics/pairwise.py index 959519483eb8c..02e501d13b4ab 100644 --- a/sklearn/metrics/pairwise.py +++ b/sklearn/metrics/pairwise.py @@ -1983,7 +1983,16 @@ def _parallel_pairwise(X, Y, func, n_jobs, **kwds): # allocate 2D arrays using the C-contiguity convention by default. ret = xp.empty((X.shape[0], Y.shape[0]), device=device, dtype=dtype_float).T Parallel(backend="threading", n_jobs=n_jobs)( - fd(func, ret, s, X, Y[s, ...], **kwds) + fd( + func, + ret, + s, + X, + Y[s, ...], + # Y_norm_squared for euclidean distance is a precomputed per-sample norm + # passed through kwds; slice it to match the current Y chunk. + **{k: (v[s] if k == "Y_norm_squared" else v) for k, v in kwds.items()}, + ) for s in gen_even_slices(_num_samples(Y), effective_n_jobs(n_jobs)) ) diff --git a/sklearn/metrics/tests/test_pairwise.py b/sklearn/metrics/tests/test_pairwise.py index 9cef6840343eb..8aa300b5e28d2 100644 --- a/sklearn/metrics/tests/test_pairwise.py +++ b/sklearn/metrics/tests/test_pairwise.py @@ -876,6 +876,25 @@ def test_parallel_pairwise_distances_diagonal(metric, global_dtype): assert_allclose(np.diag(distances), 0, atol=1e-10) +def test_parallel_pairwise_distances_y_norm_squared(): + """Check that Y_norm_squared is correctly sliced alongside Y. + + Non-regression test for issue #33877. + """ + rng = np.random.RandomState(42) + X = rng.rand(13, 4) + Y = rng.rand(15, 4) + Y_norm_squared = (Y**2).sum(axis=1) + + D_single = pairwise_distances( + X, Y, metric="euclidean", n_jobs=1, Y_norm_squared=Y_norm_squared + ) + D_parallel = pairwise_distances( + X, Y, metric="euclidean", n_jobs=2, Y_norm_squared=Y_norm_squared + ) + assert_allclose(D_parallel, D_single) + + @pytest.mark.filterwarnings("ignore:Could not adhere to working_memory config") def test_pairwise_distances_chunked(global_dtype): # Test the pairwise_distance helper function. From b62a8d8715a8ce54cbca463990432fec8e8a5a2e Mon Sep 17 00:00:00 2001 From: Lucy Liu <jliu176@gmail.com> Date: Wed, 6 May 2026 06:20:39 +1000 Subject: [PATCH 434/462] TST Add array API continuous metric common tests (#32793) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- sklearn/metrics/tests/test_classification.py | 146 ------------------- sklearn/metrics/tests/test_common.py | 130 +++++++++++++++++ 2 files changed, 130 insertions(+), 146 deletions(-) diff --git a/sklearn/metrics/tests/test_classification.py b/sklearn/metrics/tests/test_classification.py index 8f7cf9f1ef69a..d98c62e2068bd 100644 --- a/sklearn/metrics/tests/test_classification.py +++ b/sklearn/metrics/tests/test_classification.py @@ -3720,149 +3720,3 @@ def test_confusion_matrix_array_api(array_namespace, device_name, dtype_name): result = confusion_matrix(y_true, y_pred, labels=labels) assert get_namespace(result)[0] == get_namespace(y_pred)[0] assert array_api_device(result) == array_api_device(y_pred) - - -@pytest.mark.parametrize( - "prob_metric", [brier_score_loss, log_loss, d2_brier_score, d2_log_loss_score] -) -@pytest.mark.parametrize("str_y_true", [False, True]) -@pytest.mark.parametrize("use_sample_weight", [False, True]) -@pytest.mark.parametrize( - "array_namespace, device_name, dtype_name", - yield_namespace_device_dtype_combinations(), -) -def test_probabilistic_metrics_array_api( - prob_metric, - str_y_true, - use_sample_weight, - array_namespace, - device_name, - dtype_name, -): - """Test that :func:`brier_score_loss`, :func:`log_loss`, :func:`d2_brier_score` - and :func:`d2_log_loss_score` work correctly with the array API for binary - and multi-class inputs. - """ - xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) - sample_weight = np.array([1, 2, 3, 1]) if use_sample_weight else None - - # binary case - extra_kwargs = {} - if str_y_true: - y_true_np = np.array(["yes", "no", "yes", "no"]) - y_true_xp_or_np = np.asarray(y_true_np) - if "brier" in prob_metric.__name__: - # `brier_score_loss` and `d2_brier_score` require specifying the - # `pos_label` - extra_kwargs["pos_label"] = "yes" - else: - y_true_np = np.array([1, 0, 1, 0]) - y_true_xp_or_np = xp.asarray(y_true_np, device=device) - - y_prob_np = np.array([0.5, 0.2, 0.7, 0.6], dtype=dtype_name) - y_prob_xp = xp.asarray(y_prob_np, device=device) - metric_score_np = prob_metric( - y_true_np, y_prob_np, sample_weight=sample_weight, **extra_kwargs - ) - with config_context(array_api_dispatch=True): - metric_score_xp = prob_metric( - y_true_xp_or_np, y_prob_xp, sample_weight=sample_weight, **extra_kwargs - ) - - assert metric_score_xp == pytest.approx(metric_score_np) - - # multi-class case - if str_y_true: - y_true_np = np.array(["a", "b", "c", "d"]) - y_true_xp_or_np = np.asarray(y_true_np) - else: - y_true_np = np.array([0, 1, 2, 3]) - y_true_xp_or_np = xp.asarray(y_true_np, device=device) - - y_prob_np = np.array( - [ - [0.5, 0.2, 0.2, 0.1], - [0.4, 0.4, 0.1, 0.1], - [0.1, 0.1, 0.7, 0.1], - [0.1, 0.2, 0.6, 0.1], - ], - dtype=dtype_name, - ) - y_prob_xp = xp.asarray(y_prob_np, device=device) - metric_score_np = prob_metric(y_true_np, y_prob_np) - with config_context(array_api_dispatch=True): - metric_score_xp = prob_metric(y_true_xp_or_np, y_prob_xp) - - assert metric_score_xp == pytest.approx(metric_score_np) - - -@pytest.mark.parametrize( - "prob_metric", [brier_score_loss, log_loss, d2_brier_score, d2_log_loss_score] -) -@pytest.mark.parametrize("use_sample_weight", [False, True]) -@pytest.mark.parametrize( - "array_namespace, device_name, dtype_name", - yield_namespace_device_dtype_combinations(), -) -def test_probabilistic_metrics_multilabel_array_api( - prob_metric, - use_sample_weight, - array_namespace, - device_name, - dtype_name, -): - """Test that :func:`brier_score_loss`, :func:`log_loss`, :func:`d2_brier_score` - and :func:`d2_log_loss_score` work correctly with the array API for - multi-label inputs. - """ - xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) - sample_weight = np.array([1, 2, 3, 1]) if use_sample_weight else None - y_true_np = np.array( - [ - [0, 0, 1, 1], - [1, 0, 1, 0], - [0, 1, 0, 0], - [1, 1, 0, 1], - ], - dtype=dtype_name, - ) - y_true_xp = xp.asarray(y_true_np, device=device) - y_prob_np = np.array( - [ - [0.15, 0.27, 0.46, 0.12], - [0.33, 0.38, 0.06, 0.23], - [0.06, 0.28, 0.03, 0.63], - [0.14, 0.31, 0.26, 0.29], - ], - dtype=dtype_name, - ) - y_prob_xp = xp.asarray(y_prob_np, device=device) - metric_score_np = prob_metric(y_true_np, y_prob_np, sample_weight=sample_weight) - with config_context(array_api_dispatch=True): - metric_score_xp = prob_metric(y_true_xp, y_prob_xp, sample_weight=sample_weight) - - assert metric_score_xp == pytest.approx(metric_score_np) - - -@pytest.mark.parametrize( - "array_namespace, device_name, dtype_name", - yield_namespace_device_dtype_combinations(), -) -@pytest.mark.parametrize("prob_metric", [brier_score_loss, d2_brier_score]) -def test_pos_label_in_brier_score_metrics_array_api( - prob_metric, array_namespace, device_name, dtype_name -): - """Check `pos_label` handled correctly when labels not in {-1, 1} or {0, 1}.""" - # For 'brier_score' metrics, when `pos_label=None` and labels are not strings, - # `pos_label` defaults to the largest label. - xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) - y_true_pos_1 = xp.asarray(np.array([1, 0, 1, 0]), device=device) - # Result should be the same when we use 2's for the label instead of 1's - y_true_pos_2 = xp.asarray(np.array([2, 0, 2, 0]), device=device) - y_prob = xp.asarray(np.array([0.5, 0.2, 0.7, 0.6], dtype=dtype_name), device=device) - - with config_context(array_api_dispatch=True): - metric_pos_1 = prob_metric(y_true_pos_1, y_prob) - metric_pos_2 = prob_metric(y_true_pos_2, y_prob) - - assert metric_pos_1 == pytest.approx(metric_pos_2) diff --git a/sklearn/metrics/tests/test_common.py b/sklearn/metrics/tests/test_common.py index 84e32135c6677..1e5e69d8b0869 100644 --- a/sklearn/metrics/tests/test_common.py +++ b/sklearn/metrics/tests/test_common.py @@ -2241,6 +2241,116 @@ def check_array_api_multilabel_classification_metric( ) +def check_array_api_binary_continuous_classification_metric( + metric, array_namespace, device_name, dtype_name +): + y_true_np = np.array([1, 0, 1, 0]) + y_prob_np = np.array([0.5, 0.2, 0.7, 0.6], dtype=dtype_name) + + check_array_api_metric( + metric, + array_namespace, + device_name, + dtype_name, + a_np=y_true_np, + b_np=y_prob_np, + sample_weight=None, + ) + + sample_weight = np.array([1, 2, 3, 1], dtype=dtype_name) + check_array_api_metric( + metric, + array_namespace, + device_name, + dtype_name, + a_np=y_true_np, + b_np=y_prob_np, + sample_weight=sample_weight, + ) + + +def check_array_api_multiclass_continuous_classification_metric( + metric, array_namespace, device_name, dtype_name +): + y_true_np = np.array([0, 1, 2, 3]) + y_prob_np = np.array( + [ + [0.5, 0.2, 0.2, 0.1], + [0.4, 0.4, 0.1, 0.1], + [0.1, 0.1, 0.7, 0.1], + [0.1, 0.2, 0.6, 0.1], + ], + dtype=dtype_name, + ) + + check_array_api_metric( + metric, + array_namespace, + device_name, + dtype_name, + a_np=y_true_np, + b_np=y_prob_np, + sample_weight=None, + ) + + sample_weight = np.array([1, 2, 3, 1], dtype=dtype_name) + + check_array_api_metric( + metric, + array_namespace, + device_name, + dtype_name, + a_np=y_true_np, + b_np=y_prob_np, + sample_weight=sample_weight, + ) + + +def check_array_api_multilabel_continuous_classification_metric( + metric, array_namespace, device, dtype_name +): + y_true_np = np.array( + [ + [0, 0, 1, 1], + [1, 0, 1, 0], + [0, 1, 0, 0], + [1, 1, 0, 1], + ], + dtype=dtype_name, + ) + y_prob_np = np.array( + [ + [0.15, 0.27, 0.46, 0.12], + [0.33, 0.38, 0.06, 0.23], + [0.06, 0.28, 0.03, 0.63], + [0.14, 0.31, 0.26, 0.29], + ], + dtype=dtype_name, + ) + + check_array_api_metric( + metric, + array_namespace, + device, + dtype_name, + a_np=y_true_np, + b_np=y_prob_np, + sample_weight=None, + ) + + sample_weight = np.array([1, 2, 3, 1], dtype=dtype_name) + + check_array_api_metric( + metric, + array_namespace, + device, + dtype_name, + a_np=y_true_np, + b_np=y_prob_np, + sample_weight=sample_weight, + ) + + def check_array_api_regression_metric(metric, array_namespace, device_name, dtype_name): func_name = metric.func.__name__ if isinstance(metric, partial) else metric.__name__ if func_name == "mean_poisson_deviance" and sp_version < parse_version("1.14.0"): @@ -2426,6 +2536,26 @@ def check_array_api_metric_pairwise(metric, array_namespace, device_name, dtype_ check_array_api_multiclass_classification_metric, check_array_api_multilabel_classification_metric, ], + brier_score_loss: [ + check_array_api_binary_continuous_classification_metric, + check_array_api_multiclass_continuous_classification_metric, + check_array_api_multilabel_continuous_classification_metric, + ], + log_loss: [ + check_array_api_binary_continuous_classification_metric, + check_array_api_multiclass_continuous_classification_metric, + check_array_api_multilabel_continuous_classification_metric, + ], + d2_brier_score: [ + check_array_api_binary_continuous_classification_metric, + check_array_api_multiclass_continuous_classification_metric, + check_array_api_multilabel_continuous_classification_metric, + ], + d2_log_loss_score: [ + check_array_api_binary_continuous_classification_metric, + check_array_api_multiclass_continuous_classification_metric, + check_array_api_multilabel_continuous_classification_metric, + ], mean_tweedie_deviance: [check_array_api_regression_metric], partial(mean_tweedie_deviance, power=-0.5): [check_array_api_regression_metric], partial(mean_tweedie_deviance, power=1.5): [check_array_api_regression_metric], From ba017b333e63f6dab0a23681bea2f6a0382de26d Mon Sep 17 00:00:00 2001 From: Ralf Gommers <ralf.gommers@gmail.com> Date: Wed, 6 May 2026 13:51:39 +0200 Subject: [PATCH 435/462] CI: remove Python 3.13t (free-threaded) wheel build jobs (#33934) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .github/workflows/wheels.yml | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index cdd3ae1957982..4fdd7426d9371 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -69,10 +69,6 @@ jobs: - os: windows-latest python: 313 platform_id: win_amd64 - - os: windows-latest - python: 313t - platform_id: win_amd64 - cibw_enable: cpython-freethreading - os: windows-latest python: 314 platform_id: win_amd64 @@ -90,10 +86,6 @@ jobs: - os: windows-11-arm python: 313 platform_id: win_arm64 - - os: windows-11-arm - python: 313t - platform_id: win_arm64 - cibw_enable: cpython-freethreading - os: windows-11-arm python: 314 platform_id: win_arm64 @@ -114,11 +106,6 @@ jobs: python: 313 platform_id: manylinux_x86_64 manylinux_image: manylinux_2_28 - - os: ubuntu-latest - python: 313t - platform_id: manylinux_x86_64 - manylinux_image: manylinux_2_28 - cibw_enable: cpython-freethreading - os: ubuntu-latest python: 314 platform_id: manylinux_x86_64 @@ -141,11 +128,6 @@ jobs: python: 313 platform_id: manylinux_aarch64 manylinux_image: manylinux_2_28 - - os: ubuntu-24.04-arm - python: 313t - platform_id: manylinux_aarch64 - manylinux_image: manylinux_2_28 - cibw_enable: cpython-freethreading - os: ubuntu-24.04-arm python: 314 platform_id: manylinux_aarch64 @@ -165,10 +147,6 @@ jobs: - os: macos-15-intel python: 313 platform_id: macosx_x86_64 - - os: macos-15-intel - python: 313t - platform_id: macosx_x86_64 - cibw_enable: cpython-freethreading - os: macos-15-intel python: 314 platform_id: macosx_x86_64 @@ -186,10 +164,6 @@ jobs: - os: macos-14 python: 313 platform_id: macosx_arm64 - - os: macos-14 - python: 313t - platform_id: macosx_arm64 - cibw_enable: cpython-freethreading - os: macos-14 python: 314 platform_id: macosx_arm64 @@ -213,7 +187,6 @@ jobs: - name: Build and test wheels env: - CIBW_ENABLE: ${{ matrix.cibw_enable }} CIBW_ENVIRONMENT: SKLEARN_SKIP_NETWORK_TESTS=1 CIBW_BUILD: cp${{ matrix.python }}-${{ matrix.platform_id }} CIBW_ARCHS: all From 87d7676e63c43bbea6d7298df19e9a857fcdf466 Mon Sep 17 00:00:00 2001 From: alexshacked <al.shacked@gmail.com> Date: Wed, 6 May 2026 16:18:07 +0300 Subject: [PATCH 436/462] TST __array_function__ not called in cross_validate and permutation_importance (#18292) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- .../inspection/tests/test_permutation_importance.py | 10 ++++++++++ sklearn/model_selection/tests/test_validation.py | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/sklearn/inspection/tests/test_permutation_importance.py b/sklearn/inspection/tests/test_permutation_importance.py index d3015488dd03d..c09daee20dbd9 100644 --- a/sklearn/inspection/tests/test_permutation_importance.py +++ b/sklearn/inspection/tests/test_permutation_importance.py @@ -24,6 +24,7 @@ from sklearn.pipeline import make_pipeline from sklearn.preprocessing import KBinsDiscretizer, OneHotEncoder, StandardScaler, scale from sklearn.utils._testing import _convert_container +from sklearn.utils.estimator_checks import _NotAnArray @pytest.mark.parametrize("n_jobs", [1, 2]) @@ -538,3 +539,12 @@ def test_permutation_importance_max_samples_error(): with pytest.raises(ValueError, match=err_msg): permutation_importance(clf, X, y, max_samples=5) + + +def test_permutation_importance_array_function_not_called(): + """Check that `__array_function__` (NEP18) is not called.""" + X = _NotAnArray([[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4]]) + y = _NotAnArray([1, 1, 1, 2, 2, 2, 1, 1]) + estimator = LogisticRegression(random_state=0) + estimator.fit(X, y) + permutation_importance(estimator, X, y, n_repeats=2, random_state=0) diff --git a/sklearn/model_selection/tests/test_validation.py b/sklearn/model_selection/tests/test_validation.py index bd3cf604b0cdd..19a9f47f384e8 100644 --- a/sklearn/model_selection/tests/test_validation.py +++ b/sklearn/model_selection/tests/test_validation.py @@ -95,6 +95,7 @@ assert_array_almost_equal, assert_array_equal, ) +from sklearn.utils.estimator_checks import _NotAnArray from sklearn.utils.fixes import COO_CONTAINERS, CSR_CONTAINERS from sklearn.utils.validation import _num_samples @@ -389,6 +390,14 @@ def test_cross_validate_invalid_scoring_param(): cross_validate(estimator, X, y, scoring={"foo": multiclass_scorer}) +def test_cross_validate_array_function_not_called(): + """Check that `__array_function__` (NEP18) is not called.""" + X = _NotAnArray([[1, 1], [1, 2], [1, 3], [1, 4], [2, 1], [2, 2], [2, 3], [2, 4]]) + y = _NotAnArray([1, 1, 1, 2, 2, 2, 1, 1]) + estimator = LogisticRegression(random_state=0) + cross_validate(estimator, X, y, cv=2) + + def test_cross_validate_nested_estimator(): # Non-regression test to ensure that nested # estimators are properly returned in a list From 2bd486131ffc0835635354b17dd1c8cdefa49af8 Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Wed, 6 May 2026 17:11:53 +0200 Subject: [PATCH 437/462] DOC fix colors and add support vectors in SVC with iris dataset example (#33892) --- examples/svm/plot_iris_svc.py | 39 ++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/examples/svm/plot_iris_svc.py b/examples/svm/plot_iris_svc.py index 77259f9d1ea2c..cb16b69b85f91 100644 --- a/examples/svm/plot_iris_svc.py +++ b/examples/svm/plot_iris_svc.py @@ -9,8 +9,8 @@ - Sepal length - Sepal width -This example shows how to plot the decision surface for four SVM classifiers -with different kernels. +This example shows how to plot the decision surface and the support vectors for +four SVM classifiers with different kernels. The linear models ``LinearSVC()`` and ``SVC(kernel='linear')`` yield slightly different decision boundaries. This can be a consequence of the following @@ -27,7 +27,7 @@ flexible non-linear decision boundaries with shapes that depend on the kind of kernel and its parameters. -.. NOTE:: while plotting the decision function of classifiers for toy 2D +.. NOTE:: While plotting the decision function of classifiers for toy 2D datasets can help get an intuitive understanding of their respective expressive power, be aware that those intuitions don't always generalize to more realistic high-dimensional problems. @@ -38,18 +38,19 @@ # SPDX-License-Identifier: BSD-3-Clause import matplotlib.pyplot as plt +import numpy as np from sklearn import datasets, svm from sklearn.inspection import DecisionBoundaryDisplay -# import some data to play with +# Import some data to play with. iris = datasets.load_iris() -# Take the first two features. We could avoid this by using a two-dim dataset +# Take the first two features. We could avoid this by using a two-dim dataset. X = iris.data[:, :2] y = iris.target -# we create an instance of SVM and fit out data. We do not scale our -# data since we want to plot the support vectors +# We create an instance of SVM and fit out data. We do not scale our +# data since we want to plot the support vectors. C = 1.0 # SVM regularization parameter models = ( svm.SVC(kernel="linear", C=C), @@ -59,7 +60,7 @@ ) models = (clf.fit(X, y) for clf in models) -# title for the plots +# Title for the plots titles = ( "SVC with linear kernel", "LinearSVC (linear kernel)", @@ -71,20 +72,34 @@ fig, sub = plt.subplots(2, 2) plt.subplots_adjust(wspace=0.4, hspace=0.4) -X0, X1 = X[:, 0], X[:, 1] - for clf, title, ax in zip(models, titles, sub.flatten()): disp = DecisionBoundaryDisplay.from_estimator( clf, X, response_method="predict", - cmap=plt.cm.coolwarm, + multiclass_colors="coolwarm", alpha=0.8, ax=ax, xlabel=iris.feature_names[0], ylabel=iris.feature_names[1], ) - ax.scatter(X0, X1, c=y, cmap=plt.cm.coolwarm, s=20, edgecolors="k") + + # Plot the support vectors. + # For LinearSVC we compute the support vectors from the decision function, see + # https://scikit-learn.org/dev/auto_examples/svm/plot_linearsvc_support_vectors.html + if hasattr(clf, "support_"): + support_vector_indices = clf.support_ + else: + decision_function = clf.decision_function(X) + support_vector_indices = (np.abs(decision_function) <= 1 + 1e-15).nonzero()[0] + ax.scatter( + X[support_vector_indices, 0], + X[support_vector_indices, 1], + c=y[support_vector_indices], + cmap=plt.cm.coolwarm, + edgecolors="k", + ) + ax.set_xticks(()) ax.set_yticks(()) ax.set_title(title) From 97d6cbd74a638db488a66f2dfe5d45a5221e807a Mon Sep 17 00:00:00 2001 From: Anne Beyer <anne.beyer@mailbox.org> Date: Wed, 6 May 2026 17:13:45 +0200 Subject: [PATCH 438/462] DOC fix colors and add support vectors in SVM with custom kernel example (#33891) Co-authored-by: Christian Lorentzen <lorentzen.ch@gmail.com> --- examples/svm/plot_custom_kernel.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/examples/svm/plot_custom_kernel.py b/examples/svm/plot_custom_kernel.py index d3816849f73b8..857d18e560837 100644 --- a/examples/svm/plot_custom_kernel.py +++ b/examples/svm/plot_custom_kernel.py @@ -3,8 +3,8 @@ SVM with custom kernel ====================== -Simple usage of Support Vector Machines to classify a sample. It will -plot the decision surface and the support vectors. +Simple usage of :ref:`svm` classifier with a custom kernel. It will +plot the decision surface and highlight the support vectors. """ @@ -17,10 +17,10 @@ from sklearn import datasets, svm from sklearn.inspection import DecisionBoundaryDisplay -# import some data to play with +# Import some data to play with. iris = datasets.load_iris() -X = iris.data[:, :2] # we only take the first two features. We could -# avoid this ugly slicing by using a two-dim dataset +X = iris.data[:, :2] # We only take the first two features. We could +# avoid this ugly slicing by using a two-dim dataset. Y = iris.target @@ -36,9 +36,7 @@ def my_kernel(X, Y): return np.dot(np.dot(X, M), Y.T) -h = 0.02 # step size in the mesh - -# we create an instance of SVM and fit out data. +# We create an instance of SVC with that kernel and fit it on the data. clf = svm.SVC(kernel=my_kernel) clf.fit(X, Y) @@ -46,15 +44,23 @@ def my_kernel(X, Y): DecisionBoundaryDisplay.from_estimator( clf, X, - cmap=plt.cm.Paired, + multiclass_colors="Paired", ax=ax, response_method="predict", plot_method="pcolormesh", shading="auto", + alpha=0.5, ) -# Plot also the training points -plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Paired, edgecolors="k") +# Plot the training points +plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Paired) +# Highlight the support vectors +plt.scatter( + X[clf.support_, 0], + X[clf.support_, 1], + facecolor="none", + edgecolors="k", +) plt.title("3-Class classification using Support Vector Machine with custom kernel") plt.axis("tight") plt.show() From 73a9a9ca866be88a1af005163768b6b0258e23b2 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Wed, 6 May 2026 17:27:06 +0200 Subject: [PATCH 439/462] DOC data interoperability and pandas/polars output for transformers (#33788) --- doc/data_interoperability.rst | 33 ++++ doc/developers/develop.rst | 5 +- doc/faq.rst | 3 +- doc/modules/df_output_transform.rst | 142 +++++++++++++++++- .../plot_release_highlights_1_0_0.py | 2 + .../plot_release_highlights_1_1_0.py | 2 + sklearn/_config.py | 10 +- .../preprocessing/_function_transformer.py | 5 +- sklearn/utils/_set_output.py | 5 +- 9 files changed, 190 insertions(+), 17 deletions(-) diff --git a/doc/data_interoperability.rst b/doc/data_interoperability.rst index 82cf19a67da26..114352a99a316 100644 --- a/doc/data_interoperability.rst +++ b/doc/data_interoperability.rst @@ -2,6 +2,39 @@ Data Interoperability ===================== +.. currentmodule:: sklearn + +Scikit-learn handles four kinds of data for :term:`X` as used in `fit(X, y)`, `fit(X)`, +`fit_transform(X)` and `transform(X)` as well as :term:`Xt` as returned by +`transform(X)` and `fit_transform(X)`: + +- :term:`array-like` objects + + In `fit(X)` and `transform(X)`, array-like `X` is converted to a numpy ndarray by + calling `numpy.asarray` upon them. + The returned `Xt` of `transform` and `fit_transform` is also a numpy ndarray or it + is a sparse matrix or sparse array, see next bullet. +- :term:`sparse matrices <sparse matrix>` and sparse arrays + + Many estimators can deal with sparse `X`, some cannot and will raise an error. + For instance, :class:`linear_model.LogisticRegression` can be fit on sparse `X`, + :class:`isotonic.IsotonicRegression` can not. + + Some transformers return sparse `Xt` from `transform` and `fit_transform`. + Most often, it can be controlled by a `sparse_output` parameter as in + :class:`preprocessing.SplineTransformer`. + + To control whether it returns a sparse matrix or a sparse array, use + `sparse_interface` in :func:`config_context` or :func:`set_config`. + This also controls whether sparse attributes are sparse matrices or sparse arrays. +- tabular data: pandas and polars dataframes + + See :ref:`df_output_transform`. +- Array API compliant arrays + + Very importantly, this includes arrays on the GPU, see :ref:`array_api`. + + .. toctree:: :maxdepth: 2 diff --git a/doc/developers/develop.rst b/doc/developers/develop.rst index 4b19fbabecd55..a8215a5a978b5 100644 --- a/doc/developers/develop.rst +++ b/doc/developers/develop.rst @@ -583,8 +583,9 @@ keyword arguments to its super class. Super classes' `__init_subclass__` should For transformers that return multiple arrays in `transform`, auto wrapping will only wrap the first array and not alter the other arrays. -See :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` -for an example on how to use the API. +Refer to the :ref:`user guide <df_output_transform>` for more details +and :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` for an +example on how to use the API. .. _developer_api_check_is_fitted: diff --git a/doc/faq.rst b/doc/faq.rst index 95cd7ae5e18d6..7aa5558db528e 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -196,8 +196,7 @@ Does scikit-learn work natively with various types of dataframes? Scikit-learn has limited support for :class:`pandas.DataFrame` and :class:`polars.DataFrame`. Scikit-learn estimators can accept both these dataframe types as input, and scikit-learn transformers can output dataframes using the `set_output` -API. For more details, refer to -:ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py`. +API. For more details, refer to :ref:`df_output_transform`. However, the internal computations in scikit-learn estimators rely on numerical operations that are more efficiently performed on homogeneous data structures such as diff --git a/doc/modules/df_output_transform.rst b/doc/modules/df_output_transform.rst index 017e1de632e66..a3d35adb93a19 100644 --- a/doc/modules/df_output_transform.rst +++ b/doc/modules/df_output_transform.rst @@ -1,8 +1,140 @@ .. _df_output_transform: -===================================================== -Pandas/Polars Output for Transformers with set_output -===================================================== +=========================================================== +Pandas/Polars Output for Transformers with `set_output` API +=========================================================== -See `SLEP018 <https://scikit-learn-enhancement-proposals.readthedocs.io/en/latest/slep018/proposal.html>`__ -and :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py`. +.. currentmodule:: sklearn + +This part of the user guide explains how scikit-learn supports tabular data. + + +Propagation of Feature Names +============================ + +By default, scikit-learn :term:`transformers` (estimators with a :meth:`transform` +method) return numpy arrays (sometimes also sparse arrays). Because numpy arrays do +not provide names for the indices of axes/dimensions, prior to version 1.0 +the :class:`pipeline.Pipeline` did not know how to propagate feature names: + +- The single step estimators did not know how to handle incoming feature names. +- The pipeline did not know how to pass feature names from step to step. + +In practice, a lot of use cases start with tabular data like a `pandas dataframe +<https://pandas.pydata.org/docs/user_guide/dsintro.html#dataframe>`_ or a +`polars dataframe <https://docs.pola.rs/api/python/stable/reference/dataframe/index.html>`__ +which have column/feature names. + +A first step to support this important use case was made by the addition of the +:class:`compose.ColumnTransformer` in :ref:`version 0.20 <changes_0_20>`. +It acts as a gateway to apply different estimators on the different features. Most +notably it understands incoming feature names. + +It was then properly solved by `SLEP007: Feature names, their generation and the API +<https://scikit-learn-enhancement-proposals.readthedocs.io/en/latest/slep007/proposal.html>`__ +and fully implemented in :ref:`version 1.1 <release_notes_1_1>`, see +the :ref:`release highlights 1.0 <feature_names_in_release_highlights_1_0_0>` and +:ref:`release highlights 1.1 <get_feature_names_out_release_highlights_1_1_0>`. +When an estimator is passed a dataframe during :term:`fit`, the estimator will +set a `feature_names_in_` attribute containing the feature names. It understands pandas +dataframes as well as dataframes with the `Python dataframe interchange protocol +<https://data-apis.org/dataframe-protocol/latest/index.html>`__ `__dataframe__`. +Furthermore, fitted estimators have the method :meth:`get_feature_names_out`. The +`get_feature_names_out` of a transformer returns⸺you guessed it⸺the feature names of +what `transform` returns. + + +Introducing the `set_output` API +================================ + +A further major step to support dataframes in a "dataframe in, dataframe out" fashion was +`SLEP018 <https://scikit-learn-enhancement-proposals.readthedocs.io/en/latest/slep018/proposal.html>`__, +implemented for pandas dataframes in :ref:`version 1.2 <release_notes_1_2>` and for +polars dataframes in :ref:`version 1.4 <release_notes_1_4>`. It introduced the +`set_output` API to configure transformers to output pandas or polars DataFrames. +The output of transformers can be configured per estimator by calling +the :meth:`set_output` method or globally, by setting `set_config(transform_output="pandas")`. +Set it to `"polars"` instead of `"pandas"` if you want the same thing to happen but with +polars DataFrames. + +The usage is basically as follows:: + + >>> import numpy as np + >>> import pandas as pd + >>> from sklearn.compose import ColumnTransformer + >>> from sklearn.pipeline import make_pipeline + >>> from sklearn.preprocessing import OneHotEncoder + >>> from sklearn.linear_model import LinearRegression + + >>> X = pd.DataFrame( + ... {"animals": ["cat", "cat", "dog", "dog"], "numeric": np.linspace(-1, 1, 4)} + ... ) + >>> y = np.array([-1.5, 0, 0.1, 1.0]) + >>> ct = ColumnTransformer( + ... [("categorical", OneHotEncoder(sparse_output=False), ["animals"])], + ... remainder="passthrough", + ... ) + >>> model = make_pipeline(ct, LinearRegression()).fit(X, y) + >>> model.feature_names_in_ + array(['animals', 'numeric'], dtype=object) + >>> model[0].get_feature_names_out() + array(['categorical__animals_cat', 'categorical__animals_dog', + 'remainder__numeric'], dtype=object) + >>> model[0].transform(X) + array([[ 1. , 0. , -1. ], + [ 1. , 0. , -0.33333333], + [ 0. , 1. , 0.33333333], + [ 0. , 1. , 1. ]]) + +Now the same, but with pandas set as output:: + + >>> from sklearn import set_config + >>> set_config(transform_output="pandas") + >>> model[0].transform(X) + c... + +.. raw:: html + + <table border="1" class="dataframe"> + <thead> + <tr style="text-align: right;"> + <th></th> + <th>categorical__animals_cat</th> + <th>categorical__animals_dog</th> + <th>remainder__numeric</th> + </tr> + </thead> + <tbody> + <tr> + <th>0</th> + <td>1.0</td> + <td>0.0</td> + <td>-1.000000</td> + </tr> + <tr> + <th>1</th> + <td>1.0</td> + <td>0.0</td> + <td>-0.333333</td> + </tr> + <tr> + <th>2</th> + <td>0.0</td> + <td>1.0</td> + <td>0.333333</td> + </tr> + <tr> + <th>3</th> + <td>0.0</td> + <td>1.0</td> + <td>1.000000</td> + </tr> + </tbody> + </table> + +To return to the default, simply run:: + + >>> set_config(transform_output="default") + +A more detailed example can be found in +:ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py`. diff --git a/examples/release_highlights/plot_release_highlights_1_0_0.py b/examples/release_highlights/plot_release_highlights_1_0_0.py index 03213076b326e..c9b0da81cd8f8 100644 --- a/examples/release_highlights/plot_release_highlights_1_0_0.py +++ b/examples/release_highlights/plot_release_highlights_1_0_0.py @@ -136,6 +136,8 @@ # :scale: 50% ############################################################################## +# .. _feature_names_in_release_highlights_1_0_0: +# # Feature Names Support # -------------------------------------------------------------------------- # When an estimator is passed a `pandas' dataframe diff --git a/examples/release_highlights/plot_release_highlights_1_1_0.py b/examples/release_highlights/plot_release_highlights_1_1_0.py index fdb11f887f3db..2b5377466f9fb 100644 --- a/examples/release_highlights/plot_release_highlights_1_1_0.py +++ b/examples/release_highlights/plot_release_highlights_1_1_0.py @@ -59,6 +59,8 @@ # :ref:`sphx_glr_auto_examples_ensemble_plot_hgbt_regression.py` # %% +# .. _get_feature_names_out_release_highlights_1_1_0: +# # `get_feature_names_out` Available in all Transformers # ----------------------------------------------------- # :term:`get_feature_names_out` is now available in all transformers, thereby diff --git a/sklearn/_config.py b/sklearn/_config.py index e2b02275c33a5..f460323592210 100644 --- a/sklearn/_config.py +++ b/sklearn/_config.py @@ -155,8 +155,9 @@ def set_config( transform_output : str, default=None Configure output of `transform` and `fit_transform`. - See :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` - for an example on how to use the API. + Refer to the :ref:`user guide <df_output_transform>` for more details + and :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` for an + example on how to use the API. - `"default"`: Default output format of a transformer - `"pandas"`: DataFrame output @@ -335,8 +336,9 @@ def config_context( transform_output : str, default=None Configure output of `transform` and `fit_transform`. - See :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` - for an example on how to use the API. + Refer to the :ref:`user guide <df_output_transform>` for more details + and :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` for an + example on how to use the API. - `"default"`: Default output format of a transformer - `"pandas"`: DataFrame output diff --git a/sklearn/preprocessing/_function_transformer.py b/sklearn/preprocessing/_function_transformer.py index 58f4a7367213f..818bfb890727b 100644 --- a/sklearn/preprocessing/_function_transformer.py +++ b/sklearn/preprocessing/_function_transformer.py @@ -394,8 +394,9 @@ def __sklearn_tags__(self): def set_output(self, *, transform=None): """Set output container. - See :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` - for an example on how to use the API. + Refer to the :ref:`user guide <df_output_transform>` for more details + and :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` for an + example on how to use the API. Parameters ---------- diff --git a/sklearn/utils/_set_output.py b/sklearn/utils/_set_output.py index 46c3aa07f2524..ad2ae60078352 100644 --- a/sklearn/utils/_set_output.py +++ b/sklearn/utils/_set_output.py @@ -408,8 +408,9 @@ def __init_subclass__(cls, auto_wrap_output_keys=("transform",), **kwargs): def set_output(self, *, transform=None): """Set output container. - See :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` - for an example on how to use the API. + Refer to the :ref:`user guide <df_output_transform>` for more details + and :ref:`sphx_glr_auto_examples_miscellaneous_plot_set_output.py` for an + example on how to use the API. Parameters ---------- From 127caa00e19aa85a2747adcb052b2694a0e31647 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Thu, 7 May 2026 00:21:16 +0200 Subject: [PATCH 440/462] DOC change fix to enh of 32828 and 32747 (#33937) --- .../{32828.fix.rst => 32828.enhancement.rst} | 0 doc/whats_new/v1.8.rst | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename doc/whats_new/upcoming_changes/sklearn.linear_model/{32828.fix.rst => 32828.enhancement.rst} (100%) diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/32828.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/32828.enhancement.rst similarity index 100% rename from doc/whats_new/upcoming_changes/sklearn.linear_model/32828.fix.rst rename to doc/whats_new/upcoming_changes/sklearn.linear_model/32828.enhancement.rst diff --git a/doc/whats_new/v1.8.rst b/doc/whats_new/v1.8.rst index db70bb46f408b..a0f0ccba40a93 100644 --- a/doc/whats_new/v1.8.rst +++ b/doc/whats_new/v1.8.rst @@ -332,7 +332,7 @@ other people in the wider Scientific Python and CPython ecosystem, for example `eta0` is not used by the default learning rate "optimal" of those two estimators. By :user:`Christian Lorentzen <lorentzenchr>`. :pr:`31933` -- |Fix| :class:`linear_model.LogisticRegressionCV` is able to handle CV splits where +- |Enhancement| :class:`linear_model.LogisticRegressionCV` is able to handle CV splits where some class labels are missing in some folds. Before, it raised an error whenever a class label were missing in a fold. By :user:`Christian Lorentzen <lorentzenchr>`. :pr:`32747` From 8c62b6b66a95f1a0ce7e672929adddbffcd4d26f Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Thu, 7 May 2026 10:34:43 +0200 Subject: [PATCH 441/462] ENH add narwhals as dependency (#31127) Co-authored-by: Marco Gorelli <33491632+MarcoGorelli@users.noreply.github.com> --- README.rst | 2 + asv_benchmarks/asv.conf.json | 1 + build_tools/circle/doc_environment.yml | 1 + build_tools/circle/doc_linux-64_conda.lock | 148 +++++------ .../doc_min_dependencies_environment.yml | 1 + .../doc_min_dependencies_linux-64_conda.lock | 121 ++++----- build_tools/github/debian_32bit_lock.txt | 2 + .../github/debian_32bit_requirements.txt | 1 + ...a_forge_cuda_array-api_linux-64_conda.lock | 115 ++++---- ...ge_cuda_array-api_linux-64_environment.yml | 1 + ...latest_conda_forge_mkl_linux-64_conda.lock | 139 +++++----- ...t_conda_forge_mkl_linux-64_environment.yml | 1 + ..._conda_forge_mkl_no_openmp_environment.yml | 1 + ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 9 +- .../pylatest_conda_forge_osx-arm64_conda.lock | 9 +- ...test_conda_forge_osx-arm64_environment.yml | 1 + .../pylatest_free_threaded_environment.yml | 1 + ...pylatest_free_threaded_linux-64_conda.lock | 20 +- ...latest_pip_openblas_pandas_environment.yml | 1 + ...st_pip_openblas_pandas_linux-64_conda.lock | 10 +- ...pylatest_pip_scipy_dev_linux-64_conda.lock | 7 +- .../pymin_conda_forge_arm_environment.yml | 1 + ...n_conda_forge_arm_linux-aarch64_conda.lock | 9 +- ...pymin_conda_forge_openblas_environment.yml | 1 + ..._openblas_min_dependencies_environment.yml | 3 +- ...nblas_min_dependencies_linux-64_conda.lock | 177 +++++++------ ...forge_openblas_ubuntu_2204_environment.yml | 1 + ...e_openblas_ubuntu_2204_linux-64_conda.lock | 38 +-- ...min_conda_forge_openblas_win-64_conda.lock | 9 +- build_tools/github/ubuntu_atlas_lock.txt | 2 + .../github/ubuntu_atlas_requirements.txt | 1 + .../update_environments_and_lock_files.py | 7 + doc/conf.py | 1 + doc/developers/development_setup.rst | 2 +- doc/developers/maintainer.rst.template | 2 +- .../custom-top-level/31127.enhancement.rst | 9 + maint_tools/bump-dependencies-versions.py | 1 + pyproject.toml | 5 +- sklearn/_min_dependencies.py | 4 +- sklearn/compose/_column_transformer.py | 12 +- .../compose/tests/test_column_transformer.py | 54 ++-- .../gradient_boosting.py | 48 +--- sklearn/tests/test_base.py | 6 +- sklearn/utils/_indexing.py | 247 +++++------------- sklearn/utils/fixes.py | 12 - sklearn/utils/tests/test_indexing.py | 68 ++--- sklearn/utils/tests/test_validation.py | 58 ++-- sklearn/utils/validation.py | 52 +--- 48 files changed, 658 insertions(+), 764 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/custom-top-level/31127.enhancement.rst diff --git a/README.rst b/README.rst index bfd5bf71da8d3..d88ab46cd6aff 100644 --- a/README.rst +++ b/README.rst @@ -34,6 +34,7 @@ .. |NumPyMinVersion| replace:: 1.24.1 .. |SciPyMinVersion| replace:: 1.10.0 .. |JoblibMinVersion| replace:: 1.3.0 +.. |NarwhalsMinVersion| replace:: 2.0.1 .. |ThreadpoolctlMinVersion| replace:: 3.2.0 .. |MatplotlibMinVersion| replace:: 3.6.1 .. |Scikit-ImageMinVersion| replace:: 0.22.0 @@ -68,6 +69,7 @@ scikit-learn requires: - Python (>= |PythonMinVersion|) - NumPy (>= |NumPyMinVersion|) - SciPy (>= |SciPyMinVersion|) +- Narwhals (>= |NarwhalsMinVersion|) - joblib (>= |JoblibMinVersion|) - threadpoolctl (>= |ThreadpoolctlMinVersion|) diff --git a/asv_benchmarks/asv.conf.json b/asv_benchmarks/asv.conf.json index 8da45b58b27bc..00aee64ce0d75 100644 --- a/asv_benchmarks/asv.conf.json +++ b/asv_benchmarks/asv.conf.json @@ -70,6 +70,7 @@ "scipy": ["1.14.0"], "cython": ["3.1.2"], "joblib": ["1.3.2"], + "narwhals": ["2.0.1"], "threadpoolctl": ["3.2.0"], "pandas": ["2.2.2"] }, diff --git a/build_tools/circle/doc_environment.yml b/build_tools/circle/doc_environment.yml index 27a63592e5bbe..32400419e0343 100644 --- a/build_tools/circle/doc_environment.yml +++ b/build_tools/circle/doc_environment.yml @@ -10,6 +10,7 @@ dependencies: - scipy - cython - joblib + - narwhals - threadpoolctl - matplotlib - pandas diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index 8c2688595e6d5..cd2a8e36e4f1b 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: f7007183330647b43c31a485b766a37201f3827f99e12ab6d756823013915178 +# input_hash: 4b12513912fca83ea30e42ca19b201d8c46abb3f039e637f03ebba1cbd7d3f25 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -45,6 +45,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda#7af961ef4aa2c1136e11dd43ded245ab +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -95,66 +96,48 @@ https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#34672 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-3.0.1-hc31b594_0.conda#d21cf8ca2e3e175299022c6f29d5ace7 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-3.0.2-hc31b594_0.conda#53b70d577abebd6fbfe21849e27c309b https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h6705ce6_0.conda#42c424ab163c576c7fb5981f7fb379cf +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h0d30a3d_1.conda#6016ea5ee9e986bc683879408cc87529 https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-h174a0a3_1.conda#850f48943d6b4589800a303f0de6a816 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c -https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h50e9bb6_24.conda#91b0f19212d79a1a4dca034aac729e4f -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b -https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 -https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b -https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/openjph-0.27.0-h8d634f6_0.conda#8397bb8cf4b370f5df7d7ee3d80ea977 -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 -https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 -https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda#755b096086851e1193f3b10347415d7c https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/noarch/attrs-26.1.0-pyhcf101f3_0.conda#c6b0543676ecb1fb2d7643941fe375f2 https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.4.0-py314h680f03e_0.conda#b712198b257f378e9bd8cde277218296 +https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2#576d629e47797577ab0f1b351297ef4a -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/click-8.3.3-pyhc90fa1f_0.conda#2266262ce8a425ecb6523d765f79b303 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/noarch/defusedxml-0.7.1-pyhd8ed1ab_0.tar.bz2#961b3a227b437d82ad7054484cfa71b2 https://conda.anaconda.org/conda-forge/noarch/docutils-0.22.4-pyhd8ed1ab_0.conda#d6bd3cd217e62bbd7efe67ff224cd667 https://conda.anaconda.org/conda-forge/noarch/doit-0.37.0-pyhcf101f3_0.conda#37b3d4c558f2bb2b5378c43f4d6f1fb5 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h6b77fdb_24.conda#491f76c26b2d032b21ba0b79cc324c4f -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h8a413ad_24.conda#ea3921760f33250a1c12926fce1660eb +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h50e9bb6_24.conda#91b0f19212d79a1a4dca034aac729e4f +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac @@ -164,23 +147,22 @@ https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda#12 https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda#89bf346df77603055d3c8fe5811691e6 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b965c999135d43a3d0f7bd7d024e26a -https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 -https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 +https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 +https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.27.0-h8d634f6_0.conda#8397bb8cf4b370f5df7d7ee3d80ea977 https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.12.1.2-pyhd8ed1ab_0.conda#dc702b2fae7ebe770aff3c83adb16b63 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -214,25 +196,24 @@ https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_1.co https://conda.anaconda.org/conda-forge/noarch/webcolors-25.10.0-pyhd8ed1ab_0.conda#6639b6b0d8b5a284f027a2003669aa65 https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_3.conda#2841eb5bfc75ce15e9a0054b98dcd64d https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.9.0-pyhd8ed1ab_0.conda#2f1ed718fcd829c184a6d4f0f2e07409 -https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e +https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h41580af_10.conda#755b096086851e1193f3b10347415d7c https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda#e1c36c6121a7c9c76f2f148f1e83b983 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 https://conda.anaconda.org/conda-forge/noarch/bleach-6.3.0-pyhcf101f3_1.conda#7c5ebdc286220e8021bf55e6384acd67 -https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2#9b347a7ec10940d3f7941ff6c460b551 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda#cf45f4278afd6f4e6d03eda0f435d527 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h6b77fdb_24.conda#491f76c26b2d032b21ba0b79cc324c4f +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h8a413ad_24.conda#ea3921760f33250a1c12926fce1660eb https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda#0ba6225c279baf7ea9473a62ea0ec9ae https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d @@ -240,14 +221,18 @@ https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#61 https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda#b38fe4e78ee75def7e599843ef4c1ab0 https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_2.conda#fd312693df06da3578383232528c468d https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 -https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 -https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 +https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 +https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda#b97e84d1553b4a1c765b87fff83453ad +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_1.conda#e51f1e4089cad105b6cac64bd8166587 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b https://conda.anaconda.org/conda-forge/noarch/plotly-6.6.0-pyhd8ed1ab_0.conda#3e9427ee186846052e81fadde8ebe96a https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 @@ -256,71 +241,86 @@ https://conda.anaconda.org/conda-forge/noarch/python-json-logger-3.2.1-pyh332efc https://conda.anaconda.org/conda-forge/noarch/referencing-0.37.0-pyhcf101f3_0.conda#870293df500ca7e18bedefa5838a22ab https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_1.conda#36de09a8d3e5d5e6f4ee63af49e59706 https://conda.anaconda.org/conda-forge/noarch/rfc3987-syntax-1.1.0-pyhe01879c_1.conda#7234f99325263a5af6d4cd195035e8f2 -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyhc90fa1f_1.conda#17b43cee5cc84969529d5d0b0309b2cb https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.4.0-pyhd8ed1ab_0.conda#f1acf5fdefa8300de697982bcb1761c9 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/noarch/anyio-4.13.0-pyhcf101f3_0.conda#af2df4b9108808da3dc76710fe50eae2 https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-25.1.0-py314h5bd0f2a_2.conda#3cca1b74b2752917b5b65b81f61f0553 https://conda.anaconda.org/conda-forge/noarch/arrow-1.4.0-pyhcf101f3_0.conda#85c4f19f377424eafc4ed7911b291642 https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda#f11a319b9700b203aa14c295858782b6 -https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 -https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f +https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.1.0-pyhd8ed1ab_0.conda#e3bffa82b874f8b9a2631bddb3869529 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda#7b8bace4943e0dc345fc45938826f2b8 -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.4-pyhcf101f3_0.conda#e81089ba496151ed0bfe3e9cb196ca11 -https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.5-pyhcf101f3_0.conda#7b2c96c18996e40ff846045e89b7d01e +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 +https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 +https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e +https://conda.anaconda.org/conda-forge/linux-64/tbb-2023.0.0-h51de99f_1.conda#6383c1684badc0d94408b12850cf07f1 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b -https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e +https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 +https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.conda#0b0154421989637d424ccf0f104be51a https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.1-pyhcf101f3_0.conda#4552b601cf622dea2bb5075baccc2c5b -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.2-pyhcf101f3_0.conda#ffe2104d16bc6896d9a09c3c95f2b9b6 +https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda#082985717303dab433c976986c674b35 -https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 https://conda.anaconda.org/conda-forge/noarch/towncrier-25.8.0-pyhd8ed1ab_0.conda#3e0e8e44292bdac62f7bcbf0450b5cc7 +https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda#8368d58342d0825f0843dc6acdd0c483 https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 -https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 +https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda#bf42ee94c750c0b2e7e998b79ac299ea https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.1-pyhbbac1ac_0.conda#d8f030e3730713c93a358fdb46f08281 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 +https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 +https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda#2bce0d047658a91b99441390b9b27045 https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py314h2730e07_3.conda#8664abf57c0ab721522b72879a101d6c https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 -https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.17.1-pyhcf101f3_0.conda#2bce0d047658a91b99441390b9b27045 +https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.1-pyhcf101f3_0.conda#0bfbcb99dbf7d3b833cbca0ea5273fc2 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py314hb4ffadd_0.conda#41ee6fe2a848876bc9f524c5a500b85b https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 -https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.17.0-pyhcf101f3_0.conda#d79a87dcfa726bcea8e61275feed6f83 +https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.9-py314h1194b4b_0.conda#11a821746ad11e642fcc615c3d66aa44 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 https://conda.anaconda.org/conda-forge/linux-64/statsmodels-0.14.6-py314hc02f841_0.conda#224e6e308b3df5c0c99d8ca5244bb34c https://conda.anaconda.org/conda-forge/noarch/tifffile-2026.5.2-pyhd8ed1ab_0.conda#acb237de455d7fbac79afc8a33eb43c0 -https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.28.0-pyhcf101f3_0.conda#a63877cb23de826b1620d3adfccc4014 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.9-py314hdafbbf9_0.conda#2046de06d7f4149a29c5d0e2cc26d6dd https://conda.anaconda.org/conda-forge/linux-64/scikit-image-0.26.0-np2py314hda1ea4c_0.conda#50d6faa367ca045c438d3bb25315b476 https://conda.anaconda.org/conda-forge/noarch/seaborn-base-0.13.2-pyhd8ed1ab_3.conda#fd96da444e81f9e6fcaac38590f3dd42 diff --git a/build_tools/circle/doc_min_dependencies_environment.yml b/build_tools/circle/doc_min_dependencies_environment.yml index 9d23aedf93b1f..38fd8d5e394e1 100644 --- a/build_tools/circle/doc_min_dependencies_environment.yml +++ b/build_tools/circle/doc_min_dependencies_environment.yml @@ -10,6 +10,7 @@ dependencies: - scipy=1.10.0 # min - cython=3.1.2 # min - joblib + - narwhals - threadpoolctl - matplotlib=3.6.1 # min - pyamg=5.0.0 # min diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index 809c5fccfe28d..e861b15c62c8c 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: e0e4e2867718dacb1dd2b73cc3d277f941cbc79163f0a0f5f7fa23098d0b45b5 +# input_hash: 9895cebc3b59336319819bf179c2dcdfcc3c51ee7a8841807f6c9dccaf2d76a0 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -48,6 +48,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68 https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -102,85 +103,69 @@ https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.1-hac33072_0.conda#34672 https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c2fae981fd2afd00812c92ac47d023d https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 -https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-3.0.1-hc31b594_0.conda#d21cf8ca2e3e175299022c6f29d5ace7 +https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-3.0.2-hc31b594_0.conda#53b70d577abebd6fbfe21849e27c309b https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h6705ce6_0.conda#42c424ab163c576c7fb5981f7fb379cf +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h0d30a3d_1.conda#6016ea5ee9e986bc683879408cc87529 https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-h174a0a3_1.conda#850f48943d6b4589800a303f0de6a816 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/libzopfli-1.0.3-h9c3ff4c_0.tar.bz2#c66fe2d123249af7651ebde8984c51c2 +https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c -https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h50e9bb6_24.conda#91b0f19212d79a1a4dca034aac729e4f -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.88.1-h040f060_0.conda#55e7cea32f68a173635bcd4ea3d6e02c -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 -https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b -https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 -https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b -https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee -https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/openjph-0.27.0-h8d634f6_0.conda#8397bb8cf4b370f5df7d7ee3d80ea977 -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f -https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 -https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda#def531a3ac77b7fb8c21d17bb5d0badb https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 https://conda.anaconda.org/conda-forge/linux-64/backports.zstd-1.4.0-py311h6b1f9c4_0.conda#aa8c3009fd8903bebdcb22fbcb4c0dea +https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py311h66f275b_1.conda#86daecb8e4ed1042d5dc6efbe0152590 -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/click-8.3.3-pyhc90fa1f_0.conda#2266262ce8a425ecb6523d765f79b303 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/noarch/docutils-0.21.2-pyhd8ed1ab_1.conda#24c1ca34138ee57de72a943237cde4cc https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 -https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h6b77fdb_24.conda#491f76c26b2d032b21ba0b79cc324c4f -https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h8a413ad_24.conda#ea3921760f33250a1c12926fce1660eb +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 +https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h50e9bb6_24.conda#91b0f19212d79a1a4dca034aac729e4f +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.88.1-hcfc306f_1.conda#ff216b19c24f3a46e9d17ebcf2f96390 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 -https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 +https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 +https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.27.0-h8d634f6_0.conda#8397bb8cf4b370f5df7d7ee3d80ea977 https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e https://conda.anaconda.org/conda-forge/linux-64/psutil-7.2.2-py311haee01d2_0.conda#2ed8f6fe8b51d8e19f7621941f7bb95f -https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac @@ -198,58 +183,74 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b53 https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda#73b44a114241e564deb5846e7394bf19 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py311h49ec1c0_0.conda#2889f0c0b6a6d7a37bd64ec60f4cc210 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e https://conda.anaconda.org/conda-forge/noarch/zipp-3.23.1-pyhcf101f3_0.conda#e1c36c6121a7c9c76f2f148f1e83b983 https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1ab_1.conda#74ac5069774cdbc53910ec4d631a3999 -https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.1-py311h3778330_0.conda#dd214022a8f01bc2ebed383dfdc8deea -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d -https://conda.anaconda.org/conda-forge/linux-64/glib-2.88.1-h5110415_0.conda#2ec5e3e179440179c28c974c8c3fe984 -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h6b77fdb_24.conda#491f76c26b2d032b21ba0b79cc324c4f +https://conda.anaconda.org/conda-forge/linux-64/glib-2.88.1-h435ced3_1.conda#7d844a122c6cf1d8d2fb024f85757225 +https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h8a413ad_24.conda#ea3921760f33250a1c12926fce1660eb https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-8.8.0-pyhcf101f3_0.conda#080594bf4493e6bae2607e65390c520a https://conda.anaconda.org/conda-forge/noarch/importlib_resources-7.1.0-pyhd8ed1ab_0.conda#0ba6225c279baf7ea9473a62ea0ec9ae https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.4-default_h99862b1_0.conda#fe7972688e6e3dd9b97d1fcce2d88235 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 +https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/plotly-5.18.0-pyhd8ed1ab_0.conda#9f6a8664f1fe752f79473eeb9bf33a60 +https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/noarch/wheel-0.47.0-pyhd8ed1ab_0.conda#d0e3b2f0030cf4fca58bde71d246e94c +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e -https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 -https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f +https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.11-h29cf534_0.conda#1e0e854b77451ac918b4a68f28932b1d +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.1.0-pyhd8ed1ab_0.conda#e3bffa82b874f8b9a2631bddb3869529 https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.5-pyhd8ed1ab_0.conda#4c8327180586e7b1cd8b6815fc8827f1 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.4-default_h99862b1_0.conda#fe7972688e6e3dd9b97d1fcce2d88235 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 -https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda#d53ffc0edc8eabf4253508008493c5bc -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh8b19718_0.conda#35870d32aed92041d31cbb15e822dca3 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e +https://conda.anaconda.org/conda-forge/linux-64/tbb-2023.0.0-h51de99f_1.conda#6383c1684badc0d94408b12850cf07f1 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 +https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 +https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 +https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda#d53ffc0edc8eabf4253508008493c5bc +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 +https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.11-h6d08254_0.conda#971da16e7fc43161329213557688d315 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 -https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.conda#820b6a1ddf590fba253f8204f7200d82 +https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 -https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h0c412b5_8.conda#80e27e7982af989ebc2e0f0d57c75ea7 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 diff --git a/build_tools/github/debian_32bit_lock.txt b/build_tools/github/debian_32bit_lock.txt index 2791202438166..f2a579708302a 100644 --- a/build_tools/github/debian_32bit_lock.txt +++ b/build_tools/github/debian_32bit_lock.txt @@ -18,6 +18,8 @@ meson==1.11.1 # via meson-python meson-python==0.19.0 # via -r build_tools/github/debian_32bit_requirements.txt +narwhals==2.20.0 + # via -r build_tools/github/debian_32bit_requirements.txt ninja==1.13.0 # via -r build_tools/github/debian_32bit_requirements.txt packaging==26.2 diff --git a/build_tools/github/debian_32bit_requirements.txt b/build_tools/github/debian_32bit_requirements.txt index 04c8ed569a900..ff766724ab5ae 100644 --- a/build_tools/github/debian_32bit_requirements.txt +++ b/build_tools/github/debian_32bit_requirements.txt @@ -3,6 +3,7 @@ # build_tools/update_environments_and_lock_files.py cython joblib +narwhals threadpoolctl pytest pytest-xdist diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 05c2c6aac09ee..2ee3c9a59fbeb 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: ae929270db8c178cbc2f0b81101682a5018610a1b61b163166d21e8184d423b6 +# input_hash: b90518da6466f9a8f061a1db617a369a22dcc6660cffa561889a7caaa46b4532 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/cuda-version-12.9-h4f385c5_3.conda#b6d5d7f1c171cbd228ea06b556cfa859 https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 @@ -59,6 +59,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb9d3cd8_0.conda#db https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c @@ -124,7 +125,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.cond https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-h692f434_1.conda#14260392d0b491c537b5e26e9a506fff https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.6-hedf47ba_0.conda#d66e791d7524770340296e9d34e7f324 https://conda.anaconda.org/conda-forge/linux-64/cuda-cudart-dev-12.9.79-h5888daf_0.conda#ba38a7c3b4c14625de45784b773f0c71 https://conda.anaconda.org/conda-forge/linux-64/cuda-cuobjdump-12.9.82-hffce074_1.conda#55a83761db33f82d92d7d7a4a61662e5 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca @@ -135,15 +136,15 @@ https://conda.anaconda.org/conda-forge/linux-64/libcublas-12.9.1.4-h676940d_1.co https://conda.anaconda.org/conda-forge/linux-64/libcurand-dev-10.3.10.19-h676940d_1.conda#fc716aaff5af15b80ccbd28b3e67672c https://conda.anaconda.org/conda-forge/linux-64/libcusparse-12.5.10.65-hecca717_2.conda#890ebfaad48c887d3d82847ec9d6bc79 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h6705ce6_0.conda#42c424ab163c576c7fb5981f7fb379cf +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h0d30a3d_1.conda#6016ea5ee9e986bc683879408cc87529 https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 https://conda.anaconda.org/rapidsai/linux-64/librmm-26.04.00-cuda12_260408_48b36cc6.conda#815e224bae37f1bf6491fe3145adbda2 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h7d032f7_2.conda#b6e326fbe1e3948da50ec29cee0380db https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 @@ -154,12 +155,22 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.co https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.6.0-h9b893ba_1.conda#cd4946050ecfcb3c6fd09106ae6a261e https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.12-h4bacb7b_1.conda#7bc920933e5fb225aba86a788164a8f1 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 +https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 +https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 https://conda.anaconda.org/conda-forge/linux-64/cuda-nvcc-impl-12.9.86-h85509e4_2.conda#67458d2685e7503933efa550f3ee40f3 +https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.4-pyhc364b38_0.conda#42d4610b52102122741f9bf68f2866ed https://conda.anaconda.org/conda-forge/linux-64/cuda-profiler-api-12.9.79-h7938cbb_1.conda#90d09865fb37d11d510444e34ebe6a09 +https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c +https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 +https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 +https://conda.anaconda.org/conda-forge/noarch/filelock-3.29.0-pyhd8ed1ab_0.conda#8fa8358d022a3a9bd101384a808044c6 https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 +https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.4.0-pyhd8ed1ab_0.conda#2c11aa96ea85ced419de710c1c3a78ff +https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 +https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 https://conda.anaconda.org/conda-forge/linux-64/libcublas-dev-12.9.1.4-h676940d_1.conda#f90f4ff087ac29005c6989ea0fb2735a https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.conda#a178a1f3642521f104ecceeefa138d01 @@ -172,12 +183,32 @@ https://conda.anaconda.org/conda-forge/linux-64/libcusparse-dev-12.5.10.65-hecca https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-only-26.04.00-cuda12_260408_b01e3028.conda#4c79a5c4309aa770d00749683f941c70 https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b +https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde +https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa +https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b +https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b +https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.595.45-pyhd8ed1ab_1.conda#dc8587ae654e96031728802016e8258c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 +https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f +https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e +https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 +https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 +https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c +https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd +https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 +https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f +https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 +https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 +https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py314h5bd0f2a_0.conda#dc1ff1e915ab35a06b6fa61efae73ab5 +https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/ucx-1.20.0-hbe80e26_1.conda#ffdaec09a7c09710040eb9e613f8c531 +https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py314h5bd0f2a_0.conda#494fdf358c152f9fdd0673c128c2f3dd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 @@ -187,16 +218,12 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h2d2dd48_2.con https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-he9ea9c5_1.conda#8e77514673f5773b40ff8953583938b6 https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 -https://conda.anaconda.org/conda-forge/noarch/cuda-pathfinder-1.5.4-pyhc364b38_0.conda#42d4610b52102122741f9bf68f2866ed -https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 -https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd -https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 -https://conda.anaconda.org/conda-forge/noarch/filelock-3.29.0-pyhd8ed1ab_0.conda#8fa8358d022a3a9bd101384a808044c6 -https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.4.0-pyhd8ed1ab_0.conda#2c11aa96ea85ced419de710c1c3a78ff -https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e +https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.6-py314h7ea930b_0.conda#a8841fd311da95db72916f58eff3f5a6 +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libcusolver-dev-11.7.5.82-h676940d_2.conda#0fe12e558abf507458bcec839e29778d https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 @@ -206,30 +233,16 @@ https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.cond https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.49.00-cuda12_260408_8d47a9ff.conda#b8ddfc6e13aa7b755392fe8cb6f9250a https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 -https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde -https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 -https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b -https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.595.45-pyhd8ed1ab_1.conda#dc8587ae654e96031728802016e8258c https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 -https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f -https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 -https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 -https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 -https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 -https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd -https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 -https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f -https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0fc809fa4c4d85e959ce4ab6e1de800 -https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 -https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py314h5bd0f2a_0.conda#dc1ff1e915ab35a06b6fa61efae73ab5 -https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d -https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py314h5bd0f2a_0.conda#494fdf358c152f9fdd0673c128c2f3dd +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 +https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 +https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py314h2b49ec1_1.conda#090f5ddba9c3c2e167619c801c212fb6 +https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b @@ -237,54 +250,42 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 +https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h6d69fc9_5.conda#4c5c16bf1133dcfe100f33dd4470998e https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e -https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.6-py314h7ea930b_0.conda#a8841fd311da95db72916f58eff3f5a6 -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 +https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.conda#8d3dbe5292af711edd6df92c68e55a89 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 -https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 -https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 -https://conda.anaconda.org/conda-forge/linux-64/triton-3.6.0-cuda129py314h2b49ec1_1.conda#090f5ddba9c3c2e167619c801c212fb6 -https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 +https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e +https://conda.anaconda.org/conda-forge/linux-64/tbb-2023.0.0-h51de99f_1.conda#6383c1684badc0d94408b12850cf07f1 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f -https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h4c8aef7_3.conda#798a499cf76e530a992365d557ba5827 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 -https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.conda#8d3dbe5292af711edd6df92c68e55a89 https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 -https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 +https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 -https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 https://conda.anaconda.org/conda-forge/linux-64/libarrow-24.0.0-ha7f89c6_0_cpu.conda#8aeb79715524b48267068fb0fd185956 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 -https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-24.0.0-h53684a4_0_cpu.conda#73e0aeaa603ff40128e75435a3c5ac77 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml index 0a984b9ca6148..b88106d21a2b2 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_environment.yml @@ -11,6 +11,7 @@ dependencies: - scipy - cython - joblib + - narwhals - threadpoolctl - matplotlib - pandas diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock index a92191295d04b..165e7dc4e42cf 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 8ce26fc3e7f7c42668742c679f3353940cac0b6a9ba3bda1f28086a5048ba326 +# input_hash: f255677497ab26f3ca2b58ac4398205e2ddb89e38d8a3d0c9a4eb812fdbe26ef @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -44,6 +44,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda# https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c @@ -95,20 +96,20 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.cond https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.26.3-h692f434_1.conda#14260392d0b491c537b5e26e9a506fff https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.6-hedf47ba_0.conda#d66e791d7524770340296e9d34e7f324 https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-hac33072_2.conda#c94a5994ef49749880a8139cf9afcbe1 https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h6705ce6_0.conda#42c424ab163c576c7fb5981f7fb379cf +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h0d30a3d_1.conda#6016ea5ee9e986bc683879408cc87529 https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-6.33.5-h2b00c02_0.conda#11ac478fa72cf12c214199b8a96523f4 https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2025.11.05-h0dc7533_1.conda#ced7f10b6cfb4389385556f47c0ad949 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.22.0-h7d032f7_2.conda#b6e326fbe1e3948da50ec29cee0380db https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 +https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 @@ -117,41 +118,21 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.6.0-h9b893ba_1.conda#cd4946050ecfcb3c6fd09106ae6a261e https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.12-h4bacb7b_1.conda#7bc920933e5fb225aba86a788164a8f1 -https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 -https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 -https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda#c3cc2864f82a944bc90a7beb4d3b0e88 -https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b -https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa -https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.14.1-h3d65ac4_0.conda#fa4e76aac348ef9c27e72c79b02833fc -https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df -https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 -https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c -https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 -https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h2d2dd48_2.conda#675ea6d90900350b1dcfa8231a5ea2dd -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-he9ea9c5_1.conda#8e77514673f5773b40ff8953583938b6 -https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.4.0-py314h680f03e_0.conda#b712198b257f378e9bd8cde277218296 +https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h1807b08_0.conda#866fd3d25b767bccb4adc8476f4035cd +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/filelock-3.29.0-pyhd8ed1ab_0.conda#8fa8358d022a3a9bd101384a808044c6 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.4.0-pyhd8ed1ab_0.conda#2c11aa96ea85ced419de710c1c3a78ff https://conda.anaconda.org/conda-forge/linux-64/greenlet-3.5.0-py314h42812f9_0.conda#d92bd1c6aa279f0c2e9add8aa5a8c846 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e @@ -159,30 +140,29 @@ https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 -https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 -https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 -https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda#c3cc2864f82a944bc90a7beb4d3b0e88 +https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1.conda#9a17c4307d23318476d7fbf0fedc0cde https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db -https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 +https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 +https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.14.1-h3d65ac4_0.conda#fa4e76aac348ef9c27e72c79b02833fc +https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd +https://conda.anaconda.org/conda-forge/linux-64/orc-2.3.0-h21090e2_0.conda#8027fce94fdfdf2e54f9d18cbae496df https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f -https://conda.anaconda.org/conda-forge/linux-64/playwright-1.59.1-h5585027_0.conda#3ec4a57c54725b9be3cad126ccbad2c0 +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e -https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac +https://conda.anaconda.org/conda-forge/linux-64/re2-2025.11.05-h5301d42_1.conda#66a715bc01c77d43aca1f9fcb13dde3c https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda#3339e3b65d58accf4ca4fb8748ab16b3 https://conda.anaconda.org/conda-forge/noarch/text-unidecode-1.3-pyhd8ed1ab_2.conda#23b4ba5619c4752976eb7ba1f5acb7e8 @@ -192,6 +172,40 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b53 https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py314h5bd0f2a_0.conda#dc1ff1e915ab35a06b6fa61efae73ab5 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py314h5bd0f2a_0.conda#494fdf358c152f9fdd0673c128c2f3dd +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h2d2dd48_2.conda#675ea6d90900350b1dcfa8231a5ea2dd +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-he9ea9c5_1.conda#8e77514673f5773b40ff8953583938b6 +https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e +https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab +https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 +https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 +https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d +https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 +https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 +https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 +https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 +https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py314h8ec4b1a_0.conda#76c4757c0ec9d11f969e8eb44899307b +https://conda.anaconda.org/conda-forge/linux-64/playwright-1.59.1-h5585027_0.conda#3ec4a57c54725b9be3cad126ccbad2c0 +https://conda.anaconda.org/conda-forge/linux-64/prometheus-cpp-1.3.0-ha5d0236_0.conda#a83f6a2fdc079e643237887a37460668 +https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff +https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.1-pyhd8ed1ab_0.conda#eadf0f76d9121a6297be754e9d7cc099 +https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 +https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 +https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 +https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda#a4059bc12930bddeb41aef71537ffaed +https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.6-hb03c661_0.conda#4d1fc190b99912ed557a8236e958c559 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda#2ccd714aa2242315acaf0a67faea780b @@ -199,65 +213,52 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda#17dcc85db3c7886650b8908b183d6876 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 +https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h6d69fc9_5.conda#4c5c16bf1133dcfe100f33dd4470998e https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e -https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab -https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 -https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 -https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d -https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 -https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff -https://conda.anaconda.org/conda-forge/noarch/pyee-13.0.1-pyhd8ed1ab_0.conda#eadf0f76d9121a6297be754e9d7cc099 -https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 -https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 -https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.4-h4df99d1_100.conda#e4e60721757979d01d3964122f674959 -https://conda.anaconda.org/conda-forge/noarch/python-slugify-8.0.4-pyhd8ed1ab_1.conda#a4059bc12930bddeb41aef71537ffaed -https://conda.anaconda.org/conda-forge/linux-64/tbb-2022.3.0-hb700be7_2.conda#8f7278ca5f7456a974992a8b34284737 -https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.15.0-h396c80c_0.conda#edd329d7d3a4ab45dcf905899a7a6115 +https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 +https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d +https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.59.0-pyhcf101f3_0.conda#313ba7b8e2a4fed359c935202853932c +https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e +https://conda.anaconda.org/conda-forge/linux-64/tbb-2023.0.0-h51de99f_1.conda#6383c1684badc0d94408b12850cf07f1 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f -https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h4c8aef7_3.conda#798a499cf76e530a992365d557ba5827 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac -https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 -https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d -https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.59.0-pyhcf101f3_0.conda#313ba7b8e2a4fed359c935202853932c -https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e +https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 +https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd -https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 -https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 +https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 https://conda.anaconda.org/conda-forge/linux-64/libarrow-24.0.0-ha7f89c6_0_cpu.conda#8aeb79715524b48267068fb0fd185956 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 -https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 -https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e +https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-24.0.0-h53684a4_0_cpu.conda#73e0aeaa603ff40128e75435a3c5ac77 https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/linux-64/libparquet-24.0.0-h7376487_0_cpu.conda#c828cca50cd3a7c53d12ce8f0872c6ec https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h7058990_103.conda#2df90510834746b1f52c5299bc99a81f https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 -https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_environment.yml b/build_tools/github/pylatest_conda_forge_mkl_linux-64_environment.yml index 52d3909e69b9e..04eea5a2eda06 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_environment.yml +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_environment.yml @@ -10,6 +10,7 @@ dependencies: - scipy - cython - joblib + - narwhals - threadpoolctl - matplotlib - pandas diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_environment.yml b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_environment.yml index beffbfec1753b..0ed7bccb07df0 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_environment.yml +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_environment.yml @@ -10,6 +10,7 @@ dependencies: - scipy - cython - joblib + - narwhals - threadpoolctl - matplotlib - pandas diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index ab0353214a469..4f1b21398254a 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: osx-64 -# input_hash: 262fddb7141c0c7e6efbe8b721d4175e7b7ee34fa4ed3e1e2fed9057463df129 +# input_hash: f1398e3b2f729d0642186ecb7999520190456ce9bfab584f3b12019c5374a520 @EXPLICIT https://conda.anaconda.org/conda-forge/osx-64/mkl-include-2023.2.0-h694c41f_50502.conda#f394610725ab086080230c5d8fd96cd4 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 @@ -31,7 +31,7 @@ https://conda.anaconda.org/conda-forge/osx-64/libbrotlidec-1.2.0-h8616949_1.cond https://conda.anaconda.org/conda-forge/osx-64/libbrotlienc-1.2.0-h8616949_1.conda#12a58fd3fc285ce20cf20edf21a0ff8f https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda#5a088b358e37ccb4f4e5c573ff37a9f9 https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.58-he930e7c_0.conda#9744d43d5200f284260637304a069ddd -https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.53.0-h8f8c405_0.conda#f2bb6692dfb33a1bbce746aa812a9a5b +https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.53.1-h8f8c405_0.conda#9273c877f78b7486b0dfdd9268327a79 https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.17.0-hf1f96e2_0.conda#bbeca862892e2898bdb45792a61c4afc https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.3-h7a90416_0.conda#c74ae93cd7876e3a9c4b5569d5e29e34 https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda#afda563484aa0017278866707807a335 @@ -42,7 +42,7 @@ https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda#6e6efb7 https://conda.anaconda.org/conda-forge/osx-64/zlib-ng-2.3.3-h8bce59a_1.conda#b3ecb6480fd46194e3f7dd0ff4445dff https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109b184d680772e3122f40136d5ca https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf -https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.4-h894318c_0.conda#5c38d938a042bf6cc8605cbaf8a9d769 +https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.6-h894318c_0.conda#8ae9dfcda989b435223605126a97a963 https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.3-h58fbd8d_0.conda#27515b8ab8bf4abd8d3d90cf11212411 https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda#9a5cb96e43f5c2296690186e15b3296f https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 @@ -61,9 +61,10 @@ https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.co https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h52bb76a_0.conda#46e628da6e796c948fa8ec9d6d10bda3 https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock index f62613232b922..9c28d4790b1b0 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: osx-arm64 -# input_hash: d46bd759507c1840244b89fad70be8f2ef116029a21e0229b0568103b6759398 +# input_hash: 072330962b0e84b395b4cef158ee9e0efdbcfc144c0a87ce34d8ede33c046c59 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/libgfortran-devel_osx-arm64-14.3.0-hc965647_1.conda#c1b69e537b3031d0f5af780b432ce511 https://conda.anaconda.org/conda-forge/noarch/nomkl-1.0-h5ca1d4c_0.tar.bz2#9a66894dfd07c4510beb6b3f9672ccc0 @@ -40,7 +40,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.2.0-hc919400_1.c https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda#9f7810b7c0a731dbc84d46d6005890ef https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda#58b2c5aee0ad58549bf92baead9baead https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.58-h132b30e_0.conda#2259ae0949dbe20c0665850365109b27 -https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.0-h1b79a29_0.conda#8423c008105df35485e184066cad4566 +https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.1-h1b79a29_0.conda#6681822ea9d362953206352371b6a904 https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.17.0-hdb1d25a_0.conda#af523aae2eca6dfa1c8eec693f5b9a79 https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.3-h6967ea9_0.conda#6c8292c2ee808aeef2406083beaa6da7 https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda#175809cc57b2c67f27a0f238bd7f069d @@ -54,7 +54,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.2-h8088a28_2.conda#f1c https://conda.anaconda.org/conda-forge/osx-arm64/zlib-ng-2.3.3-hed4e4f5_1.conda#d99c2a23a31b0172e90f456f580b695e https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab136e4c34e97f34fb621d2592a393d8 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c -https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.4-h414bf82_0.conda#c6f4bfb11893878780f4b3eae6432e43 +https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.6-h414bf82_0.conda#1628795893a799313a719264fd7f2227 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.3-hdfa99f5_0.conda#e98ba7b5f09a5f450eca083d5a1c4649 https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda#92df6107310b1fff92c4cc84f0de247b https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.33.5-h4a5acfd_0.conda#b839e3295b66434f20969c8b940f056a @@ -82,10 +82,11 @@ https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ce https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.4.0-h169892a_0.conda#2845c3a1d0d8da1db92aba8323892475 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hd9e9057_0.conda#4b5d3a91320976eec71678fad1e3569b https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pybind11-global-3.0.1-pyhc7ab6ef_0.conda#fe10b422ce8b5af5dab3740e4084c3f9 https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_environment.yml b/build_tools/github/pylatest_conda_forge_osx-arm64_environment.yml index f5bb0206a9fa6..ceeab1a46d216 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_environment.yml +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_environment.yml @@ -10,6 +10,7 @@ dependencies: - scipy - cython - joblib + - narwhals - threadpoolctl - matplotlib - pandas diff --git a/build_tools/github/pylatest_free_threaded_environment.yml b/build_tools/github/pylatest_free_threaded_environment.yml index a6bd1d1f653ba..38660db5ea287 100644 --- a/build_tools/github/pylatest_free_threaded_environment.yml +++ b/build_tools/github/pylatest_free_threaded_environment.yml @@ -10,6 +10,7 @@ dependencies: - numpy - scipy - joblib + - narwhals - threadpoolctl - pytest - pytest-run-parallel diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index 56effda9f149f..2138f1e889158 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 7f842ff628171ca53fc79777d1a71909440a7c3af69979c721418352753a843a +# input_hash: dfa4c0cdd5a3e5cc983ff3ccbf680082d433b6249fd8b1639d9dbccb230466b3 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#3251796e09870c978e0f69fa05e38fb6 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 @@ -17,31 +17,29 @@ https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a3 https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.6-hedf47ba_0.conda#d66e791d7524770340296e9d34e7f324 https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-hf9ea5aa_0_cp314t.conda#f9c864fd19f2e57a6624520c63262a16 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_0.conda#de1699ede4f26f116d44653d95228453 https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.conda#cc2fcbfdf0628b5ad05b319866187bbc https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/setuptools-82.0.1-pyh332efcf_0.conda#8e194e7b992f99a5015edbd4ebd38efd @@ -50,10 +48,12 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b53 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314hd4f4903_0.conda#ee2b2bb9e96a9cd64d68492842559adf +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-freethreading-3.14.4-h92d6c8b_0.conda#431c21b61666866b1b4cb3252974642c https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314hd4f4903_0.conda#ee2b2bb9e96a9cd64d68492842559adf https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314h529d2a9_0.conda#c09dd94be0e88aca25c60fb53d5c8e45 https://conda.anaconda.org/conda-forge/noarch/pytest-run-parallel-0.8.2-pyhd8ed1ab_0.conda#288250b7e539cddf52f39616deae278d +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314h529d2a9_0.conda#c09dd94be0e88aca25c60fb53d5c8e45 diff --git a/build_tools/github/pylatest_pip_openblas_pandas_environment.yml b/build_tools/github/pylatest_pip_openblas_pandas_environment.yml index d07aa8a284181..7351905714d16 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_environment.yml +++ b/build_tools/github/pylatest_pip_openblas_pandas_environment.yml @@ -12,6 +12,7 @@ dependencies: - scipy - cython - joblib + - narwhals - threadpoolctl - matplotlib - pandas diff --git a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock index fdf3b63ff8821..5efc792915dda 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 379fba3287458f6d9cd98c2c5855086a7e8b681b1116f1ab22e6e7ffc97a8c78 +# input_hash: bcf549bd8b88cf3153cf032a6a1e47a965be224b7a3a61f9df80cee66c784ab2 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 @@ -16,19 +16,18 @@ https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.6-hedf47ba_0.conda#d66e791d7524770340296e9d34e7f324 https://conda.anaconda.org/conda-forge/linux-64/python-3.13.13-h6add32d_100_cp313.conda#05051be49267378d2fcd12931e319ac3 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl#sha256=3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a @@ -46,6 +45,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a9 # pip kiwisolver @ https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 # pip meson @ https://files.pythonhosted.org/packages/5e/cd/f3a881ff5e601d6bbeff63b38ee2362e1167c47d9cde03eddf8d71a4ffb0/meson-1.11.1-py3-none-any.whl#sha256=9b3a023657e393dbc5335b95c561337d49b7a458f5541e47ec44f2cc566e0d80 +# pip narwhals @ https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl#sha256=16e750ea5507d4ba6e8d03455b5f93a535e0405976561baea235bca5dc9f475d # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip numpy @ https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83 # pip packaging @ https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl#sha256=5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index cfaa37660d85d..de383cf2da563 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -16,19 +16,18 @@ https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda# https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.6-hedf47ba_0.conda#d66e791d7524770340296e9d34e7f324 https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh145f28c_0.conda#09a970fbf75e8ed1aa633827ded6aa4f +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f # pip alabaster @ https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl#sha256=fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl#sha256=3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a diff --git a/build_tools/github/pymin_conda_forge_arm_environment.yml b/build_tools/github/pymin_conda_forge_arm_environment.yml index 47fad214303ec..403c972499010 100644 --- a/build_tools/github/pymin_conda_forge_arm_environment.yml +++ b/build_tools/github/pymin_conda_forge_arm_environment.yml @@ -10,6 +10,7 @@ dependencies: - scipy - cython - joblib + - narwhals - threadpoolctl - matplotlib - pytest diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index 73c2a3984e927..a88df2667c8ed 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-aarch64 -# input_hash: b0db406e405d91cd349c3c7b460345d0d459ac3a897e3458a15f333e2c772865 +# input_hash: c0892bbe9f13a37407e7494f4250ece95a46da85c1b730d8f0ed1a7f3d2510a2 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -35,7 +35,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.co https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.conda#d5d58b2dc3e57073fe22303f5fed4db7 https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda#f51503ac45a4888bce71af9027a2ecc9 -https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.0-h022381a_0.conda#86db4036fd08bf34e991bf48a8af405d +https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.1-h022381a_0.conda#2ec1119217d8f0d086e9a62f3cb0e5ea https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42-h1022ec0_0.conda#a0b5de740d01c390bdbb46d7503c9fab https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af @@ -71,7 +71,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/wayland-1.25.0-h4f8a99f_0.c https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libsm-1.2.6-h0808dbd_0.conda#2d1409c50882819cb1af2de82e2b7208 https://conda.anaconda.org/conda-forge/linux-aarch64/zlib-ng-2.3.3-ha7cb516_1.conda#f731af71c723065d91b4c01bb822641b https://conda.anaconda.org/conda-forge/linux-aarch64/brotli-bin-1.2.0-he30d5cf_1.conda#b31f6f3a888c3f8f4c5a9dafc2575187 -https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.4-h185addb_0.conda#5ec2a8d4764a2c0f70161ce26a852dbe +https://conda.anaconda.org/conda-forge/linux-aarch64/ccache-4.13.6-h185addb_0.conda#529eb8e276a92d5d30c924e94c1b8099 https://conda.anaconda.org/conda-forge/linux-aarch64/krb5-1.22.2-hfd895c2_0.conda#d9ca108bd680ea86a963104b6b3e95ca https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype-2.14.3-h8af1aa0_0.conda#a229e22d4d8814a07702b0919d8e6701 https://conda.anaconda.org/conda-forge/linux-aarch64/libglib-2.86.4-hf53f6bf_1.conda#4ac4372fc4d7f20630a91314cdac8afd @@ -103,6 +103,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.con https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.3-h869d058_0.conda#2cffef27cb2eb9ed1e315a1e269d4335 https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.32-pthreads_h3a8cbd8_0.conda#62e1383bcaf8f5244d2598bbda509e3b https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 @@ -154,7 +155,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.3-h7d4fc67_0.conda https://conda.anaconda.org/conda-forge/linux-aarch64/libvulkan-loader-1.4.341.0-h8b8848b_0.conda#06bb91a87fb97ea09398d2e121e00c39 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/linux-aarch64/numpy-2.4.3-py311h669026d_0.conda#23c6d37dec83159283cfeee4fceebf84 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh8b19718_0.conda#35870d32aed92041d31cbb15e822dca3 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxtst-1.2.5-h57736b2_3.conda#c05698071b5c8e0da82a282085845860 https://conda.anaconda.org/conda-forge/linux-aarch64/blas-devel-3.11.0-6_h9678261_openblas.conda#64fe76410feeef76a105b2343edc4af7 diff --git a/build_tools/github/pymin_conda_forge_openblas_environment.yml b/build_tools/github/pymin_conda_forge_openblas_environment.yml index c0b5590793bd8..8cba11ebb7120 100644 --- a/build_tools/github/pymin_conda_forge_openblas_environment.yml +++ b/build_tools/github/pymin_conda_forge_openblas_environment.yml @@ -10,6 +10,7 @@ dependencies: - scipy - cython - joblib + - narwhals - threadpoolctl - matplotlib - pytest diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_environment.yml b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_environment.yml index d8fa0b1a3842e..c74c283048082 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_environment.yml +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_environment.yml @@ -10,6 +10,7 @@ dependencies: - scipy=1.10.0 # min - cython=3.1.2 # min - joblib=1.3.0 # min + - narwhals=2.0.1 # min - threadpoolctl=3.2.0 # min - matplotlib=3.6.1 # min - pyamg=5.0.0 # min @@ -23,7 +24,7 @@ dependencies: - coverage - ccache - polars=0.20.30 # min - - pyarrow=12.0.0 # min + - pyarrow=13.0.0 # min - pip - pip: - pandas==1.5.0 # min diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index 487ede81c72b7..d491bd3fd99bb 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 85d62da6957fb2aa8f14c534a934297a9946f5daea75996cc5f89c20f0a0038a +# input_hash: c0352e4c16c581d3f0312207c1fb8536322428093cf704d1ebdf12359d15f046 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -17,7 +17,6 @@ https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.con https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 -https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.2-h25fd6f3_2.conda#c2a01a08fc991620a74b32420e97868a https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 @@ -26,6 +25,7 @@ https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2f https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda#f9f81ea472684d75b9dd8d0b328cf655 https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda#b38117a3c920364aff79f870c984b4a3 +https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.1.0-hb03c661_4.conda#1d29d2e33fe59954af82ef54a8af3fe1 https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499cd8e2d4358986dbe3b30e8fe1bf6a https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 @@ -35,13 +35,14 @@ https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18. https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb +https://conda.anaconda.org/conda-forge/linux-64/libnl-3.11.0-hb9d3cd8_0.conda#db63358239cbe1ff86242406d440e44a https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7927b404672409d9917d49bff5f2d6 -https://conda.anaconda.org/conda-forge/linux-64/libnuma-2.0.18-hb03c661_3.conda#672fad24c7fedff73c684c3e9e9848b3 https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.5-hd0c01bc_1.conda#68e52064ed3897463c0e958ab5c8f91b https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2446ac1fe030c2aa6141386c1f5a6aed https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c @@ -55,13 +56,14 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xorg-libxshmfence-1.3.3-hb9d3cd8_0.conda#9a809ce9f65460195777f2f2116bae02 https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.8.23-hd590300_0.conda#cc4f06f7eedb1523f3b83fd0fb3942ff +https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.9.23-h4ab18f5_0.conda#94d61ae2b2b701008a9d52ce6bbead27 https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-h5888daf_1005.conda#d411fc29e338efb48c5fd4576d71d881 https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda#2cd94587f3a401ae05e03a6caf09539d https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2#a8832b479f93521a9e7b5b743803be51 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 -https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.0.9-h166bdaf_9.conda#61641e239f96eae2b8492dc7e755828c +https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.1.0-hb03c661_4.conda#5cb5a1c9a94a78f5b23684bcb845338d +https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hb03c661_4.conda#2e55011fa483edb8bfe3fd92e860cd79 https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 @@ -73,6 +75,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.cond https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda#8ee3cb7f64be0e8c4787f3a4dbe024e6 +https://conda.anaconda.org/conda-forge/linux-64/libudev1-257.13-hd0affe5_0.conda#2c2270f93d6f9073cbf72d821dfc7d72 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -82,94 +85,72 @@ https://conda.anaconda.org/conda-forge/linux-64/nspr-4.38-h29cc59b_0.conda#e235d https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda#7a3bff861a6583f1889021facefc08b1 https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda#c01af13bdc553d1a8fbfff6e8db075f0 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec -https://conda.anaconda.org/conda-forge/linux-64/s2n-1.3.46-h06160fa_0.conda#413d96a0b655c8f8aacc36473a2dbb04 +https://conda.anaconda.org/conda-forge/linux-64/s2n-1.4.17-he19d79f_0.conda#e25ac9bf10f8e6aa67727b1cdbe762ef +https://conda.anaconda.org/conda-forge/linux-64/snappy-1.2.2-h03e3b7b_1.conda#98b6c9dc80eb87b2519b97bcf7e578dd https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda#1c74ff8c35dcadf952a16f752ca5aa49 https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.0-h93469e0_0.conda#580a52a05f5be28ce00764149017c6d4 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.17-h862ab75_1.conda#0013fcee7acb3cfc801c5929824feb3c -https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.11-h862ab75_1.conda#6fbc9bd49434eb36d3a59c5020f4af95 -https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.16-h862ab75_1.conda#f883d61afbc95c50f7b3f62546da4235 -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d -https://conda.anaconda.org/conda-forge/linux-64/glog-0.6.0-h6f12383_0.tar.bz2#b31f3565cb84435407594e548a2fb7b2 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.7.1-h87b94db_1.conda#2d76d2cfdcfe2d5c3883d33d8be919e7 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.18-he027950_7.conda#11e5cb0b426772974f6416545baee0ce +https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.16-he027950_3.conda#adbf0c44ca88a3cded175cd809a106b6 +https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.18-he027950_7.conda#95611b325a9728ed68b8f7eef2dd3feb +https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.1.0-hb03c661_4.conda#ca4ed8015764937c81b830f7f5b68543 +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.6-hedf47ba_0.conda#d66e791d7524770340296e9d34e7f324 +https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda#ff862eebdfeb2fd048ae9dc92510baca https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 -https://conda.anaconda.org/conda-forge/linux-64/libabseil-20230125.3-cxx17_h59595ed_0.conda#d1db1b8be7c3a8983dcbbbfe4f0765de -https://conda.anaconda.org/conda-forge/linux-64/libbrotlidec-1.0.9-h166bdaf_9.conda#081aa22f4581c08e4372b0b6c2f8478e -https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.0.9-h166bdaf_9.conda#1f0a03af852a9659ed2bf08f2f1704fd +https://conda.anaconda.org/conda-forge/linux-64/libabseil-20240116.2-cxx17_he02047a_1.conda#c48fc56ec03229f294176923c3265c05 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 -https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h6705ce6_0.conda#42c424ab163c576c7fb5981f7fb379cf +https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h0d30a3d_1.conda#6016ea5ee9e986bc683879408cc87529 https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d -https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-3.21.12-hfc55251_2.conda#e3a7d4ba09b8dc939b98fef55f539220 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 -https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.18.1-h8fd135c_2.conda#bbf65f7688512872f063810623b755dc +https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.19.0-hb90f79a_1.conda#8cdb7d41faa0260875ba92414c487e2d https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318b08df404f9c9be5712aaa5a6f0bb0 -https://conda.anaconda.org/conda-forge/linux-64/rdma-core-28.9-h59595ed_1.conda#aeffb7c06b5f65e55e6c637408dc4100 -https://conda.anaconda.org/conda-forge/linux-64/re2-2023.03.02-h8c504da_0.conda#206f8fa808748f6e90599c3368a1114e -https://conda.anaconda.org/conda-forge/linux-64/snappy-1.1.10-hdb0a2a9_1.conda#78b8b85bdf1f42b8a2b3cb577d8742d1 +https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee +https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f +https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.13.27-h3870b5a_0.conda#b868db6b48436bdbda71aa8576f4a44d -https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.0.9-h166bdaf_9.conda#d47dee1856d9cb955b8076eeff304a5b -https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c -https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 -https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c -https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 -https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.88.1-h040f060_0.conda#55e7cea32f68a173635bcd4ea3d6e02c -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 -https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 -https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda#c3cc2864f82a944bc90a7beb4d3b0e88 -https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c -https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.54.3-hb20ce57_0.conda#7af7c59ab24db007dfd82e0a3a343f66 -https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 -https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b -https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee -https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/orc-1.8.4-h2f23424_0.conda#4bb92585a250e67d49b46c073d29f9dd -https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f -https://conda.anaconda.org/conda-forge/linux-64/ucx-1.14.1-h64cca9d_5.conda#39aa3b356d10d7e5add0c540945a0944 -https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 -https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.3.1-h1e03375_0.conda#3082be841420d6288bc1268a9be45b75 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.7.10-h9ab9c9b_2.conda#cf49873da2e59f876a2ad4794b05801b -https://conda.anaconda.org/conda-forge/linux-64/brotli-1.0.9-h166bdaf_9.conda#4601544b4982ba1861fa9b9c607b2c06 -https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.0.9-py311ha362b79_9.conda#ced5340f5dc6cff43a80deac8d0e398f -https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.14.10-h826b7d6_1.conda#6961646dded770513a781de4cd5c1fe1 +https://conda.anaconda.org/conda-forge/linux-64/brotli-1.1.0-hb03c661_4.conda#eaf3fbd2aa97c212336de38a51fe404e +https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.1.0-py311h1ddb823_4.conda#7138a06a7b0d11a23cfae323e6010a08 https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.conda#929471569c93acefb30282a22060dcd5 https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 +https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 +https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda#ce96f2f470d39bd96ce03945af92e280 https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 +https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c +https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 +https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.88.1-hcfc306f_1.conda#ff216b19c24f3a46e9d17ebcf2f96390 https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc -https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.12.0-hac9eb74_1.conda#0dee716254497604762957076ac76540 -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 -https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 +https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda#c3cc2864f82a944bc90a7beb4d3b0e88 +https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c +https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.25-pthreads_h413a1c8_0.conda#d172b34a443b95f86089e8229ddc9a17 +https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-4.25.3-hd5b35b9_1.conda#06def97690ef90781a91b786cb48a0a9 +https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2023.09.01-h5a48ba9_2.conda#41c69fba59d495e8cf5ffda48a607e35 +https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda#995d8c8bad2a3cc8db14675a153dec2b https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 -https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.0.1-pyhe01879c_0.conda#5f0dea40791cecf0f82882b9eea7f7c1 +https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_3.conda#fd5062942bfa1b0bd5e0d2a4397b099e -https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyh29332c3_1.conda#12c566707c80111f9799308d9e265aef https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.3.2-pyhcf101f3_0.conda#3687cc0b82a8b4c17e1f0eb7e47163d5 @@ -181,58 +162,80 @@ https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhcf101f3_3.conda#d0f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py311h49ec1c0_0.conda#73b44a114241e564deb5846e7394bf19 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d +https://conda.anaconda.org/conda-forge/linux-64/ucx-1.16.0-h209287a_5.conda#1bd6b5d51b155a3c03b6aa2702d37f3f https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py311h49ec1c0_0.conda#2889f0c0b6a6d7a37bd64ec60f4cc210 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 -https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.0-h435f46f_0.conda#c7726f96aab024855ede05e0ca6e94a0 -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.8.13-hd4f18eb_5.conda#860fb8c0efec64a4a678eb2ea066ff65 +https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-hb711507_2.conda#a0901183f08b6c7107aab109733a3c91 +https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda#b56e0c8432b56decafae7e78c5f29ba5 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.4.2-h7671281_15.conda#3b45b0da170f515de8be68155e14955a +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.8.2-he17ee6b_6.conda#4e3d1bb2ade85619ac2163e695c2cc1b +https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py311h3778330_0.conda#e32c4e7639b1c1b5680fabdaa6081e56 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.1-py311h3778330_0.conda#dd214022a8f01bc2ebed383dfdc8deea -https://conda.anaconda.org/conda-forge/linux-64/glib-2.88.1-h5110415_0.conda#2ec5e3e179440179c28c974c8c3fe984 +https://conda.anaconda.org/conda-forge/linux-64/glib-2.88.1-h435ced3_1.conda#7d844a122c6cf1d8d2fb024f85757225 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 -https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.4-default_h99862b1_0.conda#fe7972688e6e3dd9b97d1fcce2d88235 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 -https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc +https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 +https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 +https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 +https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 +https://conda.anaconda.org/conda-forge/linux-64/orc-2.0.1-h17fec99_1.conda#3bf65f0d8e7322a1cfe8b670fa35ec81 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d +https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-h9a6aba3_3.conda#b8ea447fdf62e3597cb8d2fae4eb1a90 https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 +https://conda.anaconda.org/conda-forge/linux-64/re2-2023.09.01-h7f4b329_2.conda#8f70e36268dea8eb666ef14c29bd3cda https://conda.anaconda.org/conda-forge/linux-64/sip-6.10.0-py311h1ddb823_1.conda#8012258dbc1728a96a7a72a2b3daf2ad https://conda.anaconda.org/conda-forge/noarch/wheel-0.47.0-pyhd8ed1ab_0.conda#d0e3b2f0030cf4fca58bde71d246e94c -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.3.12-he2a37c1_2.conda#44876aca9aa47da1e5e2d3f9906169ba +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda#f2ba4192d38b6cef2bb2c25029071d90 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda#b5fcc7172d22516e1f965490e65e33a4 +https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.22-hbd3ac97_10.conda#7ca4abcc98c7521c02f4e8809bbe40df +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.10.4-hcd6a914_8.conda#b81c45867558446640306507498b2c6b https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.11-h29cf534_0.conda#1e0e854b77451ac918b4a68f28932b1d -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae +https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.4-default_h99862b1_0.conda#fe7972688e6e3dd9b97d1fcce2d88235 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 +https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.62.2-h15f2491_0.conda#8dabe607748cb3d7002ad73cd06f1325 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 +https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_1.conda#7a02679229c6c2092571b4c025055440 -https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 -https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda#d53ffc0edc8eabf4253508008493c5bc -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh8b19718_0.conda#35870d32aed92041d31cbb15e822dca3 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/zstandard-0.25.0-py311haee01d2_1.conda#ca45bfd4871af957aaa5035593d5efd2 -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.20.2-h2a5cb19_18.conda#7313674073496cec938f73b71163bc31 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.6.0-h365ddd8_2.conda#22339cf124753bafda336167f80e7860 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.26.0-h26d7fe4_0.conda#7b9d4c93870fb2d644168071d4d76afb +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.9.0-20_linux64_openblas.conda#05c5862c7dc25e65ba6c471d96429dae +https://conda.anaconda.org/conda-forge/linux-64/numpy-1.24.1-py311h8e6699e_0.conda#bd7c9bf413aa9478ea5f68123e796ab1 +https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda#d53ffc0edc8eabf4253508008493c5bc +https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d +https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.27.3-hda66527_2.conda#734875312c8196feecc91f89856da612 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.9.0-20_linux64_openblas.conda#9932a1d4e9ecf2d35fb19475446e361e https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.2-py311hd18a35c_0.conda#f8e440efa026c394461a45a46cea49fc https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.11-h6d08254_0.conda#971da16e7fc43161329213557688d315 +https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.26.0-ha262f82_0.conda#89b53708fd67762b26c38c8ecc5d323d https://conda.anaconda.org/conda-forge/linux-64/polars-0.20.30-py311h00856b1_0.conda#5113e0013db6b28be897218ddf9835f9 -https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d -https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.5.0-pyhd8ed1ab_0.conda#436c165519e140cb08d246a4472a9d6a -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.10.57-h7b9373a_16.conda#54db1af780a69493a2e0675113a027f9 +https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.329-h46c3b66_9.conda#c840f07ec58dc0b06041e7f36550a539 https://conda.anaconda.org/conda-forge/linux-64/blas-2.120-openblas.conda#c8f6916a81a340650078171b1d852574 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.6.1-py311he728205_1.tar.bz2#88af4d7dc89608bfb7665a9685578800 -https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h0c412b5_8.conda#80e27e7982af989ebc2e0f0d57c75ea7 -https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-12.0.0-hc410076_9_cpu.conda#3dcb50139596ef80908e2dd9a931d84c https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 +https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.15-h0c412b5_8.conda#80e27e7982af989ebc2e0f0d57c75ea7 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-13.0.0-hbec76fc_49_cpu.conda#0e54818246f20cbd13ed6ba98a0a31bb https://conda.anaconda.org/conda-forge/linux-64/pyqt-5.15.11-py311h0580839_2.conda#59ae5d8d4bcb1371d61ec49dfb985c70 -https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-12.0.0-py311h39c9aba_9_cpu.conda#c35fe329bcc51a1a3a254c990ba8f738 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.10.0-py311h8e6699e_2.conda#29e7558b75488b2d5c7d1458be2b3b11 +https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.6.1-py311h38be061_1.tar.bz2#37d18a25f4f7fcef45ba4fb31cbe30af https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.0.0-py311hcb41070_0.conda#af2d6818c526791fb81686c554ab262b +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-13.0.0-py311h02bbc4d_49_cpu.conda#a1eeed75b982917baed517c2ed97af06 # pip pytz @ https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl#sha256=04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126 # pip pandas @ https://files.pythonhosted.org/packages/fa/fe/c81ad3991f2c6aeacf01973f1d37b1dc76c0682f312f104741602a9557f1/pandas-1.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl#sha256=e252a9e49b233ff96e2815c67c29702ac3a062098d80a170c506dff3470fd060 diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_environment.yml b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_environment.yml index 17e35387366cc..1bcead72555ac 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_environment.yml +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_environment.yml @@ -10,6 +10,7 @@ dependencies: - scipy - cython - joblib + - narwhals - threadpoolctl - pandas - pyamg diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index e2de835e0dca0..de20b0e719bfd 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: linux-64 -# input_hash: 4a7e90be8a5287a384c3d5be14b2f52f18019e1dfa2c584c5325fc7d52f0a764 +# input_hash: f06cde3a939d893ba718bc1020c1f52e5d8809bf0b8c641eb0a01d32482eaccd @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 @@ -21,6 +21,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db +https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -31,7 +32,6 @@ https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.con https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda#b2895afaf55bf96a8c8282a2e47a5de0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda#1dafce8548e38671bea82e3f5c6ce22f https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda#c80d8a3b84358cb967fa81e7075fbc8a https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e @@ -41,15 +41,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.cond https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec https://conda.anaconda.org/conda-forge/linux-64/zlib-ng-2.3.3-hceb46e0_1.conda#2aadb0d17215603a82a2a6b0afd9a4cb -https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.4-hedf47ba_0.conda#647dbec4597b31bf5a308260c53f320d +https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.6-hedf47ba_0.conda#d66e791d7524770340296e9d34e7f324 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda#89d61bc91d3f39fda0ca10fcd3c68594 -https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.0-hf4e2dac_0.conda#810d83373448da85c3f673fbcb7ad3a3 https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#cd5a90476766d53e901500df9215e927 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 -https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e -https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.32-pthreads_h6ec200e_0.conda#2e9cf6ff9a29b98a4faf627f2eb2cdb7 -https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f https://conda.anaconda.org/conda-forge/noarch/alabaster-1.0.0-pyhd8ed1ab_1.conda#1fd9696649f65fd6611fcdb4ffec738a https://conda.anaconda.org/conda-forge/noarch/babel-2.18.0-pyhcf101f3_1.conda#f1976ce927373500cc19d3c0b2c85177 @@ -66,12 +61,14 @@ https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 -https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.32-pthreads_h6ec200e_0.conda#2e9cf6ff9a29b98a4faf627f2eb2cdb7 +https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 -https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 https://conda.anaconda.org/conda-forge/noarch/pysocks-1.7.1-pyha55dd90_7.conda#461219d1a5bd61342293efa2c0c90eac @@ -87,22 +84,25 @@ https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0. https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04558c96691bed63104678757beb4f8d https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_h6ae95b6_openblas.conda#af6df8ece92110c951032683af64f1fa -https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py311h2e04523_0.conda#cfc8f864dea571677095ebae8e6f0c07 +https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda#36ae340a916635b97ac8a0655ace2a35 +https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda#881d801569b201c2e753f03c84b85e15 +https://conda.anaconda.org/conda-forge/linux-64/pillow-12.2.0-py311hf88fc01_0.conda#b4e4b0fc807b68aa1706457f2e31279d https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 https://conda.anaconda.org/conda-forge/noarch/wheel-0.47.0-pyhd8ed1ab_0.conda#d0e3b2f0030cf4fca58bde71d246e94c -https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_h1ea3ea9_openblas.conda#064f82e2cd0146b28a0bda3ca9b6fb7e +https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_h6ae95b6_openblas.conda#af6df8ece92110c951032683af64f1fa https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py311h8032f78_0.conda#138e5d98884407fcc8ccc6088574b1c7 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 +https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py311h2e04523_0.conda#cfc8f864dea571677095ebae8e6f0c07 +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh8b19718_0.conda#35870d32aed92041d31cbb15e822dca3 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e -https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 -https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-openblas.conda#81122e5749efe4c34c07471ad866eab1 -https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 +https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_h1ea3ea9_openblas.conda#064f82e2cd0146b28a0bda3ca9b6fb7e +https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py311h8032f78_0.conda#138e5d98884407fcc8ccc6088574b1c7 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 +https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py311hbe70eeb_0.conda#5ae6d73ab0bebbc892c2d46dc51e90a5 +https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-openblas.conda#81122e5749efe4c34c07471ad866eab1 +https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py311h1d5f577_1.conda#65b9997185d6db9b8be75ccb11664de5 https://conda.anaconda.org/conda-forge/noarch/numpydoc-1.10.0-pyhcf101f3_0.conda#3aa4b625f20f55cf68e92df5e5bf3c39 https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-2.0.0-pyhd8ed1ab_1.conda#16e3f039c0aa6446513e94ab18a8784b https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-devhelp-2.0.0-pyhd8ed1ab_1.conda#910f28a05c178feba832f842155cbfff diff --git a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock index cfbcc1e8ffcef..b47e814a5bea5 100644 --- a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock @@ -1,6 +1,6 @@ # Generated by conda-lock. # platform: win-64 -# input_hash: 3aaf3eda4e528698421b31452dbf3227c6c3928b2b93c666c997c928b9ad8a61 +# input_hash: feaae827995fbf38e3b1d4e04e52e22e9b2bc994c222cc772e9e30df1b0a0a73 @EXPLICIT https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2#0c96522c6bdaed4b1566d11387caaf45 https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2#34893075a5c9e55cdafac56607368fc6 @@ -32,7 +32,7 @@ https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#645 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.4.1-hfd05255_0.conda#25a127bad5470852b30b239f030ec95b https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda#8f83619ab1588b98dd99c90b0bfc5c6d https://conda.anaconda.org/conda-forge/win-64/libopenblas-0.3.32-pthreads_h877e47f_0.conda#cb7bb86e848c806cf3f0a182fcdf77da -https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.0-hf5d6505_0.conda#4152b5a8d2513fd7ae9fb9f221a5595d +https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.53.1-hf5d6505_0.conda#7fea434a17c323256acc510a041b80d7 https://conda.anaconda.org/conda-forge/win-64/libvulkan-loader-1.4.341.0-h477610d_0.conda#804880b2674119b84277d6c16b01677d https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda#f9bbae5e2537e3b06e0f7310ba76c893 https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda#dbabbd6234dea34040e631f87676292f @@ -66,13 +66,14 @@ https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.5.0-py311h275cad7_0.c https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-6_h2a8eebe_openblas.conda#56ab25cf3cbce9e3a809e3e89739b5a8 https://conda.anaconda.org/conda-forge/win-64/libclang13-22.1.4-default_ha2db4b5_0.conda#8759fc24d708cc4af95af5d86f5441d1 https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_0.conda#f9975a0177ee6cdda10c86d1db1186b0 -https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.1-h822be2e_0.conda#76f642848b6cac29977dbb8b66d4f29c +https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.1-h7ce1215_1.conda#574ba3f468b639cfaf65c0f2b04d8e9d https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-6_hd232482_openblas.conda#06d2ad5bf21e9b86c46783833b2e3c42 https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda#549845d5133100142452812feb9ba2e8 https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69bbf778a462da324489976c84cfc8c https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_0.conda#95591ca5671d2213f5b2d5aa7818420d https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 @@ -105,7 +106,7 @@ https://conda.anaconda.org/conda-forge/win-64/fonttools-4.62.1-py311h3f79411_0.c https://conda.anaconda.org/conda-forge/win-64/freetype-2.14.3-h57928b3_0.conda#507b36518b5a595edda64066c820a6ef https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/win-64/pillow-12.2.0-py311h17b8079_0.conda#80382ea49ddde54350b5ca5135be2838 -https://conda.anaconda.org/conda-forge/noarch/pip-26.0.1-pyh8b19718_0.conda#67bdec43082fd8a9cffb9484420b39a2 +https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh8b19718_0.conda#35870d32aed92041d31cbb15e822dca3 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.1-py311h9c22a71_0.conda#24047b0ff1fa264427c456e4c7f68283 https://conda.anaconda.org/conda-forge/win-64/blas-2.306-openblas.conda#8fe2bc7bfe72359526e4e94b018853a3 diff --git a/build_tools/github/ubuntu_atlas_lock.txt b/build_tools/github/ubuntu_atlas_lock.txt index 52db7c125e0ef..05ee11c0938fd 100644 --- a/build_tools/github/ubuntu_atlas_lock.txt +++ b/build_tools/github/ubuntu_atlas_lock.txt @@ -16,6 +16,8 @@ meson==1.11.1 # via meson-python meson-python==0.19.0 # via -r build_tools/github/ubuntu_atlas_requirements.txt +narwhals==2.0.1 + # via -r build_tools/github/ubuntu_atlas_requirements.txt ninja==1.13.0 # via -r build_tools/github/ubuntu_atlas_requirements.txt packaging==26.2 diff --git a/build_tools/github/ubuntu_atlas_requirements.txt b/build_tools/github/ubuntu_atlas_requirements.txt index 91569dfef2299..a1945c10595f7 100644 --- a/build_tools/github/ubuntu_atlas_requirements.txt +++ b/build_tools/github/ubuntu_atlas_requirements.txt @@ -3,6 +3,7 @@ # build_tools/update_environments_and_lock_files.py cython==3.1.2 # min joblib==1.3.0 # min +narwhals==2.0.1 # min threadpoolctl==3.2.0 # min pytest pytest-xdist diff --git a/build_tools/update_environments_and_lock_files.py b/build_tools/update_environments_and_lock_files.py index a89a4d4e91765..1181c35ec9d5f 100644 --- a/build_tools/update_environments_and_lock_files.py +++ b/build_tools/update_environments_and_lock_files.py @@ -64,6 +64,7 @@ "scipy", "cython", "joblib", + "narwhals", "threadpoolctl", "matplotlib", "pandas", @@ -187,6 +188,7 @@ def remove_from(alist, to_remove): "matplotlib": "min", "cython": "min", "joblib": "min", + "narwhals": "min", "threadpoolctl": "min", "meson-python": "min", "pandas": "min", @@ -260,6 +262,7 @@ def remove_from(alist, to_remove): "pandas", "cython", "joblib", + "narwhals", "pillow", ], ) @@ -284,6 +287,7 @@ def remove_from(alist, to_remove): "numpy", "scipy", "joblib", + "narwhals", "threadpoolctl", "pytest", "pytest-run-parallel", @@ -428,6 +432,7 @@ def remove_from(alist, to_remove): "pip_dependencies": [ "cython", "joblib", + "narwhals", "threadpoolctl", "pytest", "pytest-xdist", @@ -447,6 +452,7 @@ def remove_from(alist, to_remove): "pip_dependencies": [ "cython", "joblib", + "narwhals", "threadpoolctl", "pytest", "pytest-xdist", @@ -455,6 +461,7 @@ def remove_from(alist, to_remove): ], "package_constraints": { "joblib": "min", + "narwhals": "min", "threadpoolctl": "min", "cython": "min", }, diff --git a/doc/conf.py b/doc/conf.py index 57764eaffd9e1..9b843cee9130d 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -574,6 +574,7 @@ def add_js_css_files(app, pagename, templatename, context, doctree): "python": ("https://docs.python.org/{.major}".format(sys.version_info), None), "numpy": ("https://numpy.org/doc/stable", None), "scipy": ("https://docs.scipy.org/doc/scipy/", None), + "narwhals": ("https://narwhals-dev.github.io/narwhals/", None), "matplotlib": ("https://matplotlib.org/", None), "pandas": ("https://pandas.pydata.org/pandas-docs/stable/", None), "joblib": ("https://joblib.readthedocs.io/en/latest/", None), diff --git a/doc/developers/development_setup.rst b/doc/developers/development_setup.rst index 6dd0901e12cfd..1f36a8795760c 100644 --- a/doc/developers/development_setup.rst +++ b/doc/developers/development_setup.rst @@ -128,7 +128,7 @@ the required packages. .. prompt:: conda create -n sklearn-dev -c conda-forge ^ - python numpy scipy cython meson-python ninja ^ + python numpy scipy narwhals cython meson-python ninja ^ pytest pytest-cov ruff==0.12.2 mypy numpydoc ^ joblib threadpoolctl pre-commit diff --git a/doc/developers/maintainer.rst.template b/doc/developers/maintainer.rst.template index 5a6e28d5b63fd..0c1c41424bb67 100644 --- a/doc/developers/maintainer.rst.template +++ b/doc/developers/maintainer.rst.template @@ -401,7 +401,7 @@ Guideline for bumping minimum versions of our dependencies release (`X.Y.0`) that has wheels for our minimum Python version. In practice this means that our minimum supported version is around 3 years old, maybe a bit less. -- **pure Python dependencies** (joblib, threadpoolctl): at the time of the +- **pure Python dependencies** (joblib, narwhals, threadpoolctl): at the time of the scikit-learn release our minimum supported version is the most recent minor release (`X.Y.0`) that is at least 2 years old. - we may decide to be less conservative than this guideline in some edge cases. diff --git a/doc/whats_new/upcoming_changes/custom-top-level/31127.enhancement.rst b/doc/whats_new/upcoming_changes/custom-top-level/31127.enhancement.rst new file mode 100644 index 0000000000000..d4f1f89a9522b --- /dev/null +++ b/doc/whats_new/upcoming_changes/custom-top-level/31127.enhancement.rst @@ -0,0 +1,9 @@ +- Scikit-learn accepted a new library dependency: + `narwhals <https://github.com/narwhals-dev/narwhals>`__. + This is a very lightweight dependency that simplifies the support of dataframe input + `X` and dataframe output as specified in the `set_output` API. Examples are pandas and + polars dataframes. Narwhals can also help to support more dataframe libraries. + Another reason for its adoption was that the dataframe interchange protocol + (`__dataframe__`) on which scikit-learn relied so far for non-pandas dataframes got + deprecated by polars and has run its course. + By :user:`Christian Lorentzen <lorentzenchr>`. diff --git a/maint_tools/bump-dependencies-versions.py b/maint_tools/bump-dependencies-versions.py index 1e732e83f6dba..8f1042ec6779b 100644 --- a/maint_tools/bump-dependencies-versions.py +++ b/maint_tools/bump-dependencies-versions.py @@ -158,6 +158,7 @@ def show_versions_update(scikit_learn_release_date="today"): pure_python_or_example_dependencies = [ "joblib", + "narwhals", "threadpoolctl", "scikit-image", "seaborn", diff --git a/pyproject.toml b/pyproject.toml index d09e030b58226..d775d55516115 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ dependencies = [ "numpy>=1.24.1", "scipy>=1.10.0", "joblib>=1.3.0", + "narwhals>=2.0.1", "threadpoolctl>=3.2.0", ] requires-python = ">=3.11" @@ -44,7 +45,7 @@ tracker = "https://github.com/scikit-learn/scikit-learn/issues" [project.optional-dependencies] build = ["numpy>=1.24.1", "scipy>=1.10.0", "cython>=3.1.2", "meson-python>=0.17.1"] -install = ["numpy>=1.24.1", "scipy>=1.10.0", "joblib>=1.3.0", "threadpoolctl>=3.2.0"] +install = ["numpy>=1.24.1", "scipy>=1.10.0", "joblib>=1.3.0", "narwhals>=2.0.1", "threadpoolctl>=3.2.0"] benchmark = ["matplotlib>=3.6.1", "pandas>=1.5.0", "memory_profiler>=0.57.0"] docs = [ "matplotlib>=3.6.1", @@ -85,7 +86,7 @@ tests = [ "mypy>=1.15", "pyamg>=5.0.0", "polars>=0.20.30", - "pyarrow>=12.0.0", + "pyarrow>=13.0.0", "numpydoc>=1.2.0", "pooch>=1.8.0", ] diff --git a/sklearn/_min_dependencies.py b/sklearn/_min_dependencies.py index e187bb604168f..08687d7d7a742 100644 --- a/sklearn/_min_dependencies.py +++ b/sklearn/_min_dependencies.py @@ -10,6 +10,7 @@ NUMPY_MIN_VERSION = "1.24.1" SCIPY_MIN_VERSION = "1.10.0" JOBLIB_MIN_VERSION = "1.3.0" +NARWHALS_MIN_VERSION = "2.0.1" THREADPOOLCTL_MIN_VERSION = "3.2.0" PYTEST_MIN_VERSION = "7.1.2" CYTHON_MIN_VERSION = "3.1.2" @@ -22,6 +23,7 @@ "numpy": (NUMPY_MIN_VERSION, "build, install"), "scipy": (SCIPY_MIN_VERSION, "build, install"), "joblib": (JOBLIB_MIN_VERSION, "install"), + "narwhals": (NARWHALS_MIN_VERSION, "install"), "threadpoolctl": (THREADPOOLCTL_MIN_VERSION, "install"), "cython": (CYTHON_MIN_VERSION, "build"), "meson-python": ("0.17.1", "build"), @@ -36,7 +38,7 @@ "mypy": ("1.15", "tests"), "pyamg": ("5.0.0", "tests"), "polars": ("0.20.30", "docs, tests"), - "pyarrow": ("12.0.0", "tests"), + "pyarrow": ("13.0.0", "tests"), "sphinx": ("7.3.7", "docs"), "sphinx-copybutton": ("0.5.2", "docs"), "sphinx-gallery": ("0.17.1", "docs"), diff --git a/sklearn/compose/_column_transformer.py b/sklearn/compose/_column_transformer.py index 60c0a7f211565..971d06895ff83 100644 --- a/sklearn/compose/_column_transformer.py +++ b/sklearn/compose/_column_transformer.py @@ -12,6 +12,7 @@ from itertools import chain from numbers import Integral, Real +import narwhals.stable.v2 as nw import numpy as np from scipy import sparse @@ -19,7 +20,7 @@ from sklearn.pipeline import _fit_transform_one, _name_estimators, _transform_one from sklearn.preprocessing import FunctionTransformer from sklearn.utils import Bunch -from sklearn.utils._dataframe import is_pandas_df, is_polars_df +from sklearn.utils._dataframe import is_pandas_df from sklearn.utils._indexing import ( _determine_key_type, _get_column_indices, @@ -747,9 +748,7 @@ def _validate_output(self, result): ] for Xs, name in zip(result, names): if not ( - getattr(Xs, "ndim", 0) == 2 - or hasattr(Xs, "__dataframe__") - or is_polars_df(Xs) + getattr(Xs, "ndim", 0) == 2 or nw.dependencies.is_into_dataframe(Xs) ): raise ValueError( f"The output of the '{name}' transformer should be 2D (numpy " @@ -1045,7 +1044,7 @@ def transform(self, X, **params): # were not present in fit time, and the order of the columns doesn't # matter. fit_dataframe_and_transform_dataframe = hasattr(self, "feature_names_in_") and ( - is_pandas_df(X) or is_polars_df(X) or hasattr(X, "__dataframe__") + nw.dependencies.is_into_dataframe(X) ) n_samples = _num_samples(X) @@ -1293,8 +1292,7 @@ def _check_X(X): """Use check_array only when necessary, e.g. on lists and other non-array-likes.""" if ( (hasattr(X, "__array__") and hasattr(X, "shape")) - or hasattr(X, "__dataframe__") - or is_polars_df(X) + or nw.dependencies.is_into_dataframe(X) or sparse.issparse(X) ): return X diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index 93f31ed5f963d..c9795628ad124 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -196,12 +196,9 @@ def test_column_transformer_tuple_transformers_parameter(): ) -@pytest.mark.parametrize("constructor_name", ["dataframe", "polars"]) +@pytest.mark.parametrize("constructor_name", ["pandas", "polars"]) def test_column_transformer_dataframe(constructor_name): - if constructor_name == "dataframe": - dataframe_lib = pytest.importorskip("pandas") - else: - dataframe_lib = pytest.importorskip(constructor_name) + df_lib = pytest.importorskip(constructor_name) X_array = np.array([[0, 1, 2], [2, 4, 6]]).T X_df = _convert_container( @@ -229,16 +226,15 @@ def test_column_transformer_dataframe(constructor_name): # boolean mask (np.array([True, False]), X_res_first), ([True, False], X_res_first), + # scalar + (0, X_res_first), + ("first", X_res_first), ] - if constructor_name == "dataframe": - # Scalars are only supported for pandas dataframes. + if constructor_name == "pandas": cases.extend( [ - # scalar - (0, X_res_first), - ("first", X_res_first), ( - dataframe_lib.Series([True, False], index=["first", "second"]), + df_lib.Series([True, False], index=["first", "second"]), X_res_first, ), ] @@ -315,38 +311,36 @@ def fit(self, X, y=None): def transform(self, X, y=None): assert isinstance(X, self.expected_type_transform) - if isinstance(X, dataframe_lib.Series): - X = X.to_frame() + if len(X.shape) < 2: + X = _convert_container(X, constructor_name) return X ct = ColumnTransformer( [ ( "trans", - TransAssert(expected_type_transform=dataframe_lib.DataFrame), + TransAssert(expected_type_transform=df_lib.DataFrame), ["first", "second"], ) ] ) ct.fit_transform(X_df) - if constructor_name == "dataframe": - # DataFrame protocol does not have 1d columns, so we only test on Pandas - # dataframes. - ct = ColumnTransformer( - [ - ( - "trans", - TransAssert(expected_type_transform=dataframe_lib.Series), - "first", - ) - ], - remainder="drop", - ) - ct.fit_transform(X_df) + ct = ColumnTransformer( + [ + ( + "trans", + TransAssert(expected_type_transform=df_lib.Series), + "first", + ) + ], + remainder="drop", + ) + ct.fit_transform(X_df) - # Only test on pandas because the dataframe protocol requires string column - # names + if constructor_name == "pandas": + # Only pandas (but not polars, nor pyarrow) allows for column names that are + # not strings. # integer column spec + integer column names -> still use positional X_df2 = X_df.copy() X_df2.columns = [1, 0] diff --git a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py index 9635162af773d..2018e0bc6853e 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py +++ b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py @@ -4,13 +4,13 @@ # SPDX-License-Identifier: BSD-3-Clause import itertools -import sys from abc import ABC, abstractmethod from contextlib import contextmanager, nullcontext, suppress from functools import partial from numbers import Integral, Real from time import time +import narwhals.stable.v2 as nw import numpy as np from sklearn._loss.loss import ( @@ -41,7 +41,6 @@ from sklearn.model_selection import train_test_split from sklearn.preprocessing import FunctionTransformer, LabelEncoder, OrdinalEncoder from sklearn.utils import check_random_state, compute_sample_weight, resample -from sklearn.utils._dataframe import is_pandas_df, is_polars_df from sklearn.utils._missing import is_scalar_nan from sklearn.utils._openmp_helpers import _openmp_effective_n_threads from sklearn.utils._param_validation import Interval, RealNotInt, StrOptions @@ -368,28 +367,12 @@ def _check_categorical_features(self, X): Indicates whether a feature is categorical. If no feature is categorical, this is None. """ - # Special code for pandas because of a bug in recent pandas, which is - # fixed in main and maybe included in 2.2.1, see - # https://github.com/pandas-dev/pandas/pull/57173. - # Also pandas versions < 1.5.1 do not support the dataframe interchange - if is_pandas_df(X): - X_is_dataframe = True - categorical_columns_mask = np.asarray(X.dtypes == "category") - elif is_polars_df(X): - # Special code for polars because polars 1.40 deprecates the __dataframe__ - # protocol. - X_is_dataframe = True - pl = sys.modules["polars"] - categorical_columns_mask = np.asarray( - [d in (pl.Categorical, pl.Enum) for d in X.dtypes] - ) - elif hasattr(X, "__dataframe__"): + if nw.dependencies.is_into_dataframe(X): + X = nw.from_native(X) + dtypes = X.schema.dtypes() X_is_dataframe = True categorical_columns_mask = np.asarray( - [ - c.dtype[0].name == "CATEGORICAL" - for c in X.__dataframe__().get_columns() - ] + [d in (nw.Categorical, nw.Enum) for d in dtypes] ) else: X_is_dataframe = False @@ -408,8 +391,7 @@ def _check_categorical_features(self, X): if no_categorical_dtype: return None - use_pandas_categorical = categorical_by_dtype and X_is_dataframe - if use_pandas_categorical: + if categorical_by_dtype and X_is_dataframe: categorical_features = categorical_columns_mask else: categorical_features = np.asarray(categorical_features) @@ -1579,11 +1561,10 @@ class HistGradientBoostingRegressor(RegressorMixin, BaseHistGradientBoosting): features. - str array-like: names of categorical features (assuming the training data has feature names). - - `"from_dtype"`: dataframe columns with dtype "category" are - considered to be categorical features. The input must be an object - exposing a ``__dataframe__`` method such as pandas or polars - DataFrames to use this feature. For polars dataframes, dtypes - pl.Categorical and pl.Enum are detected. + - `"from_dtype"`: dataframe columns with dtype "Categorical" and "Enum" are + considered to be categorical features. The input must be a dataframe that + is supported by narwhals (or supports it): :func:`narwhals.from_native` must + work. This is the case, for instance, for pandas and polars DataFrames. For each categorical feature, there must be at most `max_bins` unique categories. Negative values for categorical features encoded as numeric @@ -1973,11 +1954,10 @@ class HistGradientBoostingClassifier(ClassifierMixin, BaseHistGradientBoosting): features. - str array-like: names of categorical features (assuming the training data has feature names). - - `"from_dtype"`: dataframe columns with dtype "category" are - considered to be categorical features. The input must be an object - exposing a ``__dataframe__`` method such as pandas or polars - DataFrames to use this feature. For polars dataframes, dtypes - pl.Categorical and pl.Enum are detected. + - `"from_dtype"`: dataframe columns with dtype "Categorical" and "Enum" are + considered to be categorical features. The input must be a dataframe that + is supported by narwhals (or supports it): :func:`narwhals.from_native` must + work. This is the case, for instance, for pandas and polars DataFrames. For each categorical feature, there must be at most `max_bins` unique categories. Negative values for categorical features encoded as numeric diff --git a/sklearn/tests/test_base.py b/sklearn/tests/test_base.py index 392b7881b2bd7..bd151b40242ce 100644 --- a/sklearn/tests/test_base.py +++ b/sklearn/tests/test_base.py @@ -915,12 +915,12 @@ class Estimator(BaseEstimator, WithSlots): "constructor_name, minversion", [ ("dataframe", "1.5.0"), - ("pyarrow", "12.0.0"), + ("pyarrow", "13.0.0"), ("polars", "0.20.23"), ], ) -def test_dataframe_protocol(constructor_name, minversion): - """Uses the dataframe exchange protocol to get feature names.""" +def test_feature_names_in_on_dataframes(constructor_name, minversion): + """Test that feature_names_in_ is correctly set for dataframe X.""" data = [[1, 4, 2], [3, 3, 6]] columns = ["col_0", "col_1", "col_2"] df = _convert_container( diff --git a/sklearn/utils/_indexing.py b/sklearn/utils/_indexing.py index 05d5f4a0ff0d3..b912c5b45c99a 100644 --- a/sklearn/utils/_indexing.py +++ b/sklearn/utils/_indexing.py @@ -6,6 +6,7 @@ import warnings from itertools import compress, islice +import narwhals.stable.v2 as nw import numpy as np from scipy.sparse import issparse @@ -15,19 +16,13 @@ get_namespace_and_device, move_to, ) -from sklearn.utils._dataframe import ( - is_pandas_df, - is_polars_df, - is_polars_df_or_series, - is_pyarrow_data, -) +from sklearn.utils._dataframe import is_pyarrow_data from sklearn.utils._param_validation import Interval, validate_params from sklearn.utils.extmath import _approximate_mode -from sklearn.utils.fixes import PYARROW_VERSION_BELOW_17, SCIPY_VERSION_BELOW_1_12 +from sklearn.utils.fixes import SCIPY_VERSION_BELOW_1_12 from sklearn.utils.validation import ( _check_sample_weight, _is_arraylike_not_scalar, - _use_interchange_protocol, check_array, check_consistent_length, check_random_state, @@ -67,6 +62,37 @@ def _array_indexing(array, key, key_dtype, axis): return array[key, ...] if axis == 0 else array[:, key] +def _narwhals_indexing(X, key, key_dtype, axis): + """Index a narwhals dataframe or series.""" + X = nw.from_native(X, allow_series=True) + if not (isinstance(key, (list, slice)) or key is None): + # Note that at least tuples should be converted to either list or ndarray as + # tuples in __getitem__ are special: x[(1, 2)] is equal to x[1, 2]. + # Also, not all backends of narwhals support ndarray, but all support lists. + key = np.asarray(key).tolist() + + if axis == 1: + if key_dtype == "bool": + subset = X.select(col for (col, select) in zip(X.columns, key) if select) + return subset.to_native() + return X[:, key].to_native() + + # From here on axis == 0: + if key_dtype == "bool": + X_indexed = X.filter(key) + else: + X_indexed = X[key] + + if np.isscalar(key): + if len(X.shape) <= 1: + return X_indexed + # TODO: `X_indexed` is a DataFrame with a single row; we return a Series to be + # consistent with pandas. Narwhals would return a dataframe which is + # advantageous if the columns have different dtypes. + return np.array([col.item(0) for col in X_indexed.iter_columns()]) + return X_indexed.to_native() + + def _pandas_indexing(X, key, key_dtype, axis): """Index a pandas dataframe or a series.""" if _is_arraylike_not_scalar(key): @@ -94,94 +120,6 @@ def _list_indexing(X, key, key_dtype): return [X[idx] for idx in key] -def _polars_indexing(X, key, key_dtype, axis): - """Index a polars dataframe or series.""" - # Polars behavior is more consistent with lists - if isinstance(key, np.ndarray): - # Convert each element of the array to a Python scalar - key = key.tolist() - elif not (np.isscalar(key) or isinstance(key, slice)): - key = list(key) - - if axis == 1: - # Here we are certain to have a polars DataFrame; which can be indexed with - # integer and string scalar, and list of integer, string and boolean - return X[:, key] - - if key_dtype == "bool": - # Boolean mask can be indexed in the same way for Series and DataFrame (axis=0) - return X.filter(key) - - # Integer scalar and list of integer can be indexed in the same way for Series and - # DataFrame (axis=0) - X_indexed = X[key] - if np.isscalar(key) and len(X.shape) == 2: - # `X_indexed` is a DataFrame with a single row; we return a Series to be - # consistent with pandas - pl = sys.modules["polars"] - return pl.Series(X_indexed.row(0)) - return X_indexed - - -def _pyarrow_indexing(X, key, key_dtype, axis): - """Index a pyarrow data.""" - scalar_key = np.isscalar(key) - if isinstance(key, slice): - if isinstance(key.stop, str): - start = X.column_names.index(key.start) - stop = X.column_names.index(key.stop) + 1 - else: - start = 0 if not key.start else key.start - stop = key.stop - step = 1 if not key.step else key.step - key = list(range(start, stop, step)) - - if axis == 1: - # Here we are certain that X is a pyarrow Table or RecordBatch. - if key_dtype == "int" and not isinstance(key, list): - # pyarrow's X.select behavior is more consistent with integer lists. - key = np.asarray(key).tolist() - if key_dtype == "bool": - key = np.asarray(key).nonzero()[0].tolist() - - if scalar_key: - return X.column(key) - - return X.select(key) - - # axis == 0 from here on - if scalar_key: - if hasattr(X, "shape"): - # X is a Table or RecordBatch - key = [key] - else: - return X[key].as_py() - elif not isinstance(key, list): - key = np.asarray(key) - - if key_dtype == "bool": - # TODO(pyarrow): remove version checking and following if-branch when - # pyarrow==17.0.0 is the minimal version, see pyarrow issue - # https://github.com/apache/arrow/issues/42013 for more info - if PYARROW_VERSION_BELOW_17: - import pyarrow - - if not isinstance(key, pyarrow.BooleanArray): - key = pyarrow.array(key, type=pyarrow.bool_()) - - X_indexed = X.filter(key) - - else: - X_indexed = X.take(key) - - if scalar_key and len(getattr(X, "shape", [0])) == 2: - # X_indexed is a dataframe-like with a single row; we return a Series to be - # consistent with pandas - pa = sys.modules["pyarrow"] - return pa.array(X_indexed.to_pylist()[0].values()) - return X_indexed - - def _determine_key_type(key, accept_slice=True): """Determine the data type of key. @@ -345,7 +283,9 @@ def _safe_indexing(X, indices, *, axis=0): if ( axis == 1 and indices_dtype == "str" - and not (is_pandas_df(X) or is_polars_df(X) or _use_interchange_protocol(X)) + and not ( + nw.dependencies.is_into_dataframe(X) or nw.dependencies.is_into_series(X) + ) ): raise ValueError( "Specifying the columns using strings is only supported for dataframes." @@ -356,23 +296,20 @@ def _safe_indexing(X, indices, *, axis=0): # 1) Currently, it (probably) works for dataframes compliant to pandas' API. # 2) Updating would require updating some tests such as # test_train_test_split_mock_pandas. + # 3) Should also work with _narwhals_indexing, but + # test_safe_indexing_pandas_no_settingwithcopy_warning does not pass. return _pandas_indexing(X, indices, indices_dtype, axis=axis) - elif is_polars_df_or_series(X): - return _polars_indexing(X, indices, indices_dtype, axis=axis) + elif nw.dependencies.is_into_dataframe(X) or nw.dependencies.is_into_series(X): + return _narwhals_indexing(X, indices, indices_dtype, axis=axis) elif is_pyarrow_data(X): - return _pyarrow_indexing(X, indices, indices_dtype, axis=axis) - elif _use_interchange_protocol(X): # pragma: no cover - # Once the dataframe X is converted into its dataframe interchange protocol - # version by calling X.__dataframe__(), it becomes very hard to turn it back - # into its original type, e.g., a pyarrow.Table, see - # https://github.com/data-apis/dataframe-api/issues/85. - raise warnings.warn( - message="A data object with support for the dataframe interchange protocol" - "was passed, but scikit-learn does currently not know how to handle this " - "kind of data. Some array/list indexing will be tried.", - category=UserWarning, - ) - + # Narwhals Series are backed by ChunkedArray, not Array. + # To reuse `_narwhals_indexing`, we temporarily convert to `ChunkedArray`. + pa = sys.modules["pyarrow"] + X = pa.chunked_array(X) + ret = _narwhals_indexing(X, indices, indices_dtype, axis=axis) + if isinstance(ret, pa.ChunkedArray): + return ret.combine_chunks() + return ret if hasattr(X, "shape"): return _array_indexing(X, indices, indices_dtype, axis=axis) else: @@ -434,79 +371,31 @@ def _get_column_indices(X, key): :func:`_safe_indexing`. """ key_dtype = _determine_key_type(key) - if is_polars_df(X): + + if nw.dependencies.is_into_dataframe(X): + # Note: narwhals raises DuplicateError if column names are not unique. + df_nw = nw.from_native(X) + n_columns = df_nw.shape[1] + column_names = df_nw.columns + else: n_columns = X.shape[1] - column_names = X.columns - return _get_column_indices_interchange_and_polars( - n_columns, column_names, key, key_dtype - ) - elif _use_interchange_protocol(X): - X_interchange = X.__dataframe__() - n_columns = X_interchange.num_columns() - column_names = list(X_interchange.column_names()) - return _get_column_indices_interchange_and_polars( - n_columns, column_names, key, key_dtype - ) + column_names = None - n_columns = X.shape[1] if isinstance(key, (list, tuple)) and not key: # we get an empty list return [] elif key_dtype in ("bool", "int"): return _get_column_indices_for_bool_or_int(key, n_columns) else: - try: - all_columns = X.columns - except AttributeError: + if column_names is None: raise ValueError( "Specifying the columns using strings is only supported for dataframes." ) - if isinstance(key, str): - columns = [key] - elif isinstance(key, slice): - start, stop = key.start, key.stop - if start is not None: - start = all_columns.get_loc(start) - if stop is not None: - # pandas indexing with strings is endpoint included - stop = all_columns.get_loc(stop) + 1 - else: - stop = n_columns + 1 - return list(islice(range(n_columns), start, stop)) - else: - columns = list(key) - - try: - column_indices = [] - for col in columns: - col_idx = all_columns.get_loc(col) - if not isinstance(col_idx, numbers.Integral): - raise ValueError( - f"Selected columns, {columns}, are not unique in dataframe" - ) - column_indices.append(col_idx) - - except KeyError as e: - missing = {*columns} - {*all_columns} - raise ValueError( - f"Some column names are not columns of the dataframe: {missing}" - ) from e - - return column_indices - - -def _get_column_indices_interchange_and_polars(n_columns, column_names, key, key_dtype): - """Same as _get_column_indices but for X with __dataframe__ protocol or polars.""" - if isinstance(key, (list, tuple)) and not key: - # we get an empty list - return [] - elif key_dtype in ("bool", "int"): - return _get_column_indices_for_bool_or_int(key, n_columns) - else: if isinstance(key, slice): if key.step not in [1, None]: raise NotImplementedError("key.step must be 1 or None") + start, stop = key.start, key.stop if start is not None: start = column_names.index(start) @@ -516,16 +405,14 @@ def _get_column_indices_interchange_and_polars(n_columns, column_names, key, key else: stop = n_columns + 1 return list(islice(range(n_columns), start, stop)) - - selected_columns = [key] if np.isscalar(key) else key - - try: - return [column_names.index(col) for col in selected_columns] - except ValueError as e: - missing = {*selected_columns} - {*column_names} - raise ValueError( - f"Some column names are not columns of the dataframe: {missing}" - ) from e + else: + selected_columns = [key] if np.isscalar(key) else key + try: + return [column_names.index(col) for col in selected_columns] + except ValueError as e: + missing = {*selected_columns} - {*column_names} + msg = f"Some column names are not columns of the dataframe: {missing}" + raise ValueError(msg) from e @validate_params( diff --git a/sklearn/utils/fixes.py b/sklearn/utils/fixes.py index 4a14cf39f6ec4..5a57835eafc0d 100644 --- a/sklearn/utils/fixes.py +++ b/sklearn/utils/fixes.py @@ -393,18 +393,6 @@ def _get_additional_lbfgs_options_dict(key, value): return {} if sp_version >= parse_version("1.15") else {key: value} -# TODO(pyarrow): Remove when minimum pyarrow version is 17.0.0 -PYARROW_VERSION_BELOW_17 = False -try: - import pyarrow - - pyarrow_version = parse_version(pyarrow.__version__) - if pyarrow_version < parse_version("17.0.0"): - PYARROW_VERSION_BELOW_17 = True -except ModuleNotFoundError: # pragma: no cover - pass - - # TODO: Replace when Scipy 1.12 is the minimum supported version # fixes for transitioning scipy.sparse function names if not SCIPY_VERSION_BELOW_1_12: diff --git a/sklearn/utils/tests/test_indexing.py b/sklearn/utils/tests/test_indexing.py index 673a80deda90b..84b69b84c80eb 100644 --- a/sklearn/utils/tests/test_indexing.py +++ b/sklearn/utils/tests/test_indexing.py @@ -4,6 +4,7 @@ import numpy as np import pytest +from narwhals.exceptions import DuplicateError from scipy.stats import kstest import sklearn @@ -501,44 +502,47 @@ def test_get_column_indices_pandas_nonunique_columns_error(key): columns = ["col1", "col1", "col2", "col3", "col2"] X = pd.DataFrame(toy, columns=columns) - err_msg = "Selected columns, {}, are not unique in dataframe".format(key) - with pytest.raises(ValueError) as exc_info: + err_msg = "Expected unique column names, got.*" + with pytest.raises(DuplicateError, match=err_msg): _get_column_indices(X, key) - assert str(exc_info.value) == err_msg -@pytest.mark.parametrize("df_type", ["interchange", "polars"]) -def test_get_column_indices_interchange_and_polars(df_type): - """Check _get_column_indices for edge cases with the interchange and polars""" - if df_type == "polars": - pl = pytest.importorskip("polars") - df = pl.DataFrame([[1, 2, 3], [4, 5, 6]], schema=["a", "b", "c"]) - else: - # Pyarrow tables go down the interchange path. - pa = pytest.importorskip("pyarrow") - df = pa.table([[1, 4], [2, 5], [3, 6]], names=["a", "b", "c"]) +@pytest.mark.parametrize( + "constructor_name", ["array", "sparse", "pandas", "pyarrow", "polars"] +) +def test_get_column_indices_dataframes(constructor_name): + """Check _get_column_indices for edge cases with 2d input X.""" + df = _convert_container( + [[1, 2, 3], [4, 5, 6]], constructor_name, columns_name=["a", "b", "c"] + ) key_results = [ - (slice(1, None), [1, 2]), - (slice(None, 2), [0, 1]), - (slice(1, 2), [1]), - (["b", "c"], [1, 2]), - (slice("a", "b"), [0, 1]), - (slice("a", None), [0, 1, 2]), - (slice(None, "a"), [0]), - (["c", "a"], [2, 0]), - ([], []), + (slice(1, None), [1, 2], False), + (slice(None, 2), [0, 1], False), + (slice(1, 2), [1], False), + (["b", "c"], [1, 2], True), + (slice("a", "b"), [0, 1], True), + (slice("a", None), [0, 1, 2], True), + (slice(None, "a"), [0], True), + (["c", "a"], [2, 0], True), + ([], [], False), ] - for key, result in key_results: - assert _get_column_indices(df, key) == result - - msg = r"Some column names are not columns of the dataframe: \{'not_a_column'\}" - with pytest.raises(ValueError, match=msg): - _get_column_indices(df, ["not_a_column"]) - - msg = "key.step must be 1 or None" - with pytest.raises(NotImplementedError, match=msg): - _get_column_indices(df, slice("a", None, 2)) + msg = "Specifying the columns using strings is only supported for dataframes" + for key, result, use_names in key_results: + if constructor_name in ("array", "sparse") and use_names: + with pytest.raises(ValueError, match=msg): + _get_column_indices(df, key) + else: + assert _get_column_indices(df, key) == result + + if constructor_name not in ("array", "sparse"): + msg = r"Some column names are not columns of the dataframe: \{'not_a_column'\}" + with pytest.raises(ValueError, match=msg): + _get_column_indices(df, ["not_a_column"]) + + msg = "key.step must be 1 or None" + with pytest.raises(NotImplementedError, match=msg): + _get_column_indices(df, slice("a", None, 2)) def test_resample(): diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 90edc6deda155..ab87539ca9759 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -1366,7 +1366,9 @@ def test_check_X_y_informative_error(): check_X_y(X, y, estimator=RandomForestRegressor()) -def test_retrieve_samples_from_non_standard_shape(): +def test_num_samples_on_non_standard_shape(): + """Test _num_samples on different non standard input X.""" + class TestNonNumericShape: def __init__(self): self.shape = ("not numeric",) @@ -1385,6 +1387,37 @@ def __init__(self): with pytest.raises(TypeError, match="Expected sequence or array-like"): _num_samples(TestNoLenWeirdShape()) + class TestNoLenNoShapeButArrayProtocol: + def __init__(self, x): + self.x = x + + def __array__(self, dtype=None, copy=None): + return np.asarray(self.x, dtype=dtype) # copy needs numpy >= 2.0 + + X = TestNoLenNoShapeButArrayProtocol(np.arange(3)) + assert _num_samples(X) == 3 + X = TestNoLenNoShapeButArrayProtocol(np.arange(6).reshape(3, 2)) + assert _num_samples(X) == 3 + + +@pytest.mark.parametrize( + "constructor_name", ["list", "tuple", "array", "series", "polars_series"] +) +def test_num_samples_on_1d(constructor_name): + """Test _num_samples on different 1d input X.""" + X = _convert_container(list(range(3)), constructor_name) + assert _num_samples(X) == 3 + + +@pytest.mark.parametrize( + "constructor_name", + ["list", "tuple", "array", "sparse", "dataframe", "pandas", "pyarrow", "polars"], +) +def test_num_samples_on_dataframe_likes(constructor_name): + """Test _num_samples on different dataframe-like input X.""" + X = _convert_container([[1, 11], [2, 22], [3, 33]], constructor_name) + assert _num_samples(X) == 3 + @pytest.mark.parametrize("x", [2, 3, 2.5, 5]) def test_check_scalar_valid(x): @@ -2037,10 +2070,10 @@ def test_get_feature_names_pandas(): @pytest.mark.parametrize( "constructor_name, minversion", - [("pyarrow", "12.0.0"), ("dataframe", "1.5.0"), ("polars", "0.18.2")], + [("pyarrow", "13.0.0"), ("dataframe", "1.5.0"), ("polars", "0.18.2")], ) -def test_get_feature_names_dataframe_protocol(constructor_name, minversion): - """Uses the dataframe exchange protocol to get feature names.""" +def test_get_feature_names_4_dataframes(constructor_name, minversion): + """Test _get_features_names on dataframes.""" data = [[1, 4, 2], [3, 3, 6]] columns = ["col_0", "col_1", "col_2"] df = _convert_container( @@ -2254,23 +2287,6 @@ def test_check_array_multiple_extensions( assert_array_equal(X_regular_checked, X_extension_checked) -def test_num_samples_dataframe_protocol(): - """Use the DataFrame interchange protocol to get n_samples.""" - pa = pytest.importorskip("pyarrow") - - class MockDFInterchange: - """A dataframe class without .shape attr but with __dataframe__ protocol""" - - def __init__(self, *args, **kwargs): - self.df = pa.table(*args, **kwargs) - - def __dataframe__(self): - return self.df.__dataframe__() - - df = MockDFInterchange({"a": [1, 2, 3], "b": [4, 5, 6]}) - assert _num_samples(df) == 3 - - @pytest.mark.parametrize( "sparse_container", CSR_CONTAINERS + CSC_CONTAINERS + COO_CONTAINERS + DIA_CONTAINERS, diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index 25f08c993f376..e6b2c7585be09 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -12,6 +12,7 @@ from inspect import Parameter, isclass, signature import joblib +import narwhals.stable.v2 as nw import numpy as np import scipy.sparse as sp @@ -29,7 +30,7 @@ get_namespace_and_device, move_to, ) -from sklearn.utils._dataframe import is_pandas_df, is_pandas_df_or_series, is_polars_df +from sklearn.utils._dataframe import is_pandas_df_or_series from sklearn.utils._isfinite import FiniteStatus, cy_isfinite from sklearn.utils._tags import get_tags from sklearn.utils.fixes import ( @@ -305,19 +306,6 @@ def _is_arraylike_not_scalar(array): return _is_arraylike(array) and not np.isscalar(array) -def _use_interchange_protocol(X): - """Use interchange protocol for non-pandas/polars dataframes that follow the - protocol. - - Note: At this point we chose not to use the interchange API on pandas dataframe - to ensure strict behavioral backward compatibility with older versions of - scikit-learn. - We also exclude the interchange protocol for polars because it was deprecated - in polars 1.40. - """ - return hasattr(X, "__dataframe__") and not is_pandas_df(X) and not is_polars_df(X) - - def _num_features(X): """Return the number of features in an array-like X. @@ -389,8 +377,8 @@ def _num_samples(x): if isinstance(x.shape[0], numbers.Integral): return x.shape[0] - if _use_interchange_protocol(x): - return x.__dataframe__().num_rows() + if nw.dependencies.is_into_dataframe(x) or nw.dependencies.is_into_series(x): + return nw.from_native(x).shape[0] if not hasattr(x, "__len__") and not hasattr(x, "shape"): if hasattr(x, "__array__"): @@ -2346,42 +2334,30 @@ def _check_method_params(X, params, indices=None): def _get_feature_names(X): """Get feature names from X. - Support for other array containers should place its implementation here. + Support for other (2d) data containers should place its implementation here. Parameters ---------- X : {ndarray, dataframe} of shape (n_samples, n_features) Array container to extract feature names. - - pandas dataframe : The columns will be considered to be feature - names. If the dataframe contains non-string feature names, `None` is - returned. + - narwhals compliant dataframe : The columns will be considered to be feature + names. - All other array containers will return `None`. Returns ------- names: ndarray or None - Feature names of `X`. Unrecognized array containers will return `None`. + Feature names of `X`. Unrecognized data containers will return `None`. """ feature_names = None - # extract feature names for support array containers - if is_pandas_df(X) or is_polars_df(X): - # Make sure we can inspect columns names from pandas, even with - # versions too old to expose a working implementation of - # __dataframe__.column_names() and avoid introducing any - # additional copy. - # TODO: remove the pandas-specific branch (but keep polars) once the minimum - # supported version of pandas has a working implementation of - # __dataframe__.column_names() that is guaranteed to not introduce any - # additional copy of the data without having to impose allow_copy=False - # that could fail with other libraries. Note: in the longer term, we - # could decide to instead rely on the __dataframe_namespace__ API once - # adopted by our minimally supported pandas version. - feature_names = np.asarray(X.columns, dtype=object) - elif hasattr(X, "__dataframe__"): - df_protocol = X.__dataframe__() - feature_names = np.asarray(list(df_protocol.column_names()), dtype=object) + # Extract feature names for supported data containers. + if nw.dependencies.is_into_dataframe(X): + # Note: Narwhals API says that the .columns property ist a list of strings, but + # this does not hold. If pandas has integer column names, .columns returns a + # list of integers, see https://github.com/narwhals-dev/narwhals/issues/3571. + feature_names = np.asarray(nw.from_native(X).columns, dtype=object) if feature_names is None or len(feature_names) == 0: return From 7501a8659e5bcbb9ef84f2090a1130f8dd2accf9 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Fri, 8 May 2026 02:02:45 +0200 Subject: [PATCH 442/462] MNT cleanup Cython imports in tree module (#33947) --- sklearn/tree/_criterion.pyx | 2 +- sklearn/tree/_partitioner.pxd | 2 +- sklearn/tree/_partitioner.pyx | 9 +++------ sklearn/tree/_splitter.pyx | 5 +---- sklearn/tree/_tree.pxd | 7 ++++--- sklearn/tree/_tree.pyx | 3 +-- sklearn/tree/_utils.pxd | 2 +- 7 files changed, 12 insertions(+), 18 deletions(-) diff --git a/sklearn/tree/_criterion.pyx b/sklearn/tree/_criterion.pyx index b04766ee266ef..8c0da50ad3260 100644 --- a/sklearn/tree/_criterion.pyx +++ b/sklearn/tree/_criterion.pyx @@ -1,9 +1,9 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause +from libc.math cimport INFINITY from libc.string cimport memcpy from libc.string cimport memset -from libc.math cimport INFINITY import numpy as np cimport numpy as cnp diff --git a/sklearn/tree/_partitioner.pxd b/sklearn/tree/_partitioner.pxd index 8dca0f78823e2..75f4e683d99dc 100644 --- a/sklearn/tree/_partitioner.pxd +++ b/sklearn/tree/_partitioner.pxd @@ -6,7 +6,7 @@ from cython cimport floating from sklearn.utils._typedefs cimport ( - float32_t, float64_t, int8_t, int32_t, intp_t, uint8_t, uint32_t + float32_t, float64_t, int32_t, intp_t, uint8_t ) from sklearn.tree._splitter cimport SplitRecord diff --git a/sklearn/tree/_partitioner.pyx b/sklearn/tree/_partitioner.pyx index a6b1c318f8476..00719348696c7 100644 --- a/sklearn/tree/_partitioner.pyx +++ b/sklearn/tree/_partitioner.pyx @@ -11,7 +11,7 @@ and sparse data stored in a Compressed Sparse Column (CSC) format. # SPDX-License-Identifier: BSD-3-Clause from cython cimport final -from libc.math cimport isnan, log2 +from libc.math cimport INFINITY, isnan, log2 from libc.stdlib cimport qsort from libc.string cimport memcpy, memmove @@ -26,9 +26,6 @@ from sklearn.tree._splitter cimport SplitRecord # in SparsePartitioner cdef float32_t EXTRACT_NNZ_SWITCH = 0.1 -# Allow for 32 bit float comparisons -cdef float32_t INFINITY_32t = np.inf - @final cdef class DensePartitioner: @@ -138,8 +135,8 @@ cdef class DensePartitioner: intp_t p float32_t current_feature_value intp_t[::1] samples = self.samples - float32_t min_feature_value = INFINITY_32t - float32_t max_feature_value = -INFINITY_32t + float32_t min_feature_value = INFINITY + float32_t max_feature_value = -INFINITY float32_t[::1] feature_values = self.feature_values intp_t n_missing = 0 bint seen_non_missing = False diff --git a/sklearn/tree/_splitter.pyx b/sklearn/tree/_splitter.pyx index cc48cf5019139..bf4de11b2517a 100644 --- a/sklearn/tree/_splitter.pyx +++ b/sklearn/tree/_splitter.pyx @@ -20,9 +20,9 @@ of splitting strategies: # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause +from libc.math cimport INFINITY from libc.string cimport memcpy -from sklearn.utils._typedefs cimport int8_t from sklearn.tree._criterion cimport Criterion from sklearn.tree._partitioner cimport ( FEATURE_THRESHOLD, DensePartitioner, SparsePartitioner, @@ -41,9 +41,6 @@ ctypedef fused Partitioner: SparsePartitioner -cdef float64_t INFINITY = np.inf - - cdef inline void _init_split(SplitRecord* self, intp_t start_pos) noexcept nogil: self.impurity_left = INFINITY self.impurity_right = INFINITY diff --git a/sklearn/tree/_tree.pxd b/sklearn/tree/_tree.pxd index 593f8d0c5f542..df56e53bcca86 100644 --- a/sklearn/tree/_tree.pxd +++ b/sklearn/tree/_tree.pxd @@ -6,10 +6,11 @@ import numpy as np cimport numpy as cnp -from sklearn.utils._typedefs cimport float32_t, float64_t, intp_t, int32_t, uint8_t, uint32_t +from sklearn.utils._typedefs cimport ( + float32_t, float64_t, intp_t, int32_t, uint8_t, uint32_t +) +from sklearn.tree._splitter cimport Splitter, SplitRecord -from sklearn.tree._splitter cimport Splitter -from sklearn.tree._splitter cimport SplitRecord cdef struct Node: # Base storage structure for the nodes in a Tree object diff --git a/sklearn/tree/_tree.pyx b/sklearn/tree/_tree.pyx index 31985fdeca56d..764c0f3ba25fe 100644 --- a/sklearn/tree/_tree.pyx +++ b/sklearn/tree/_tree.pyx @@ -3,11 +3,11 @@ from cpython cimport Py_INCREF, PyObject, PyTypeObject +from libc.math cimport INFINITY, isnan from libc.stdlib cimport free from libc.string cimport memcpy from libc.string cimport memset from libc.stdint cimport INTPTR_MAX -from libc.math cimport isnan from libcpp.vector cimport vector from libcpp.algorithm cimport pop_heap from libcpp.algorithm cimport push_heap @@ -42,7 +42,6 @@ cdef extern from "numpy/arrayobject.h": from numpy import float32 as DTYPE from numpy import float64 as DOUBLE -cdef float64_t INFINITY = np.inf cdef float64_t EPSILON = np.finfo('double').eps # Some handy constants (BestFirstTreeBuilder) diff --git a/sklearn/tree/_utils.pxd b/sklearn/tree/_utils.pxd index 97f8d60645b04..5aba8f532203d 100644 --- a/sklearn/tree/_utils.pxd +++ b/sklearn/tree/_utils.pxd @@ -6,7 +6,7 @@ cimport numpy as cnp from sklearn.tree._tree cimport Node from sklearn.neighbors._quad_tree cimport Cell -from sklearn.utils._typedefs cimport float32_t, float64_t, intp_t, uint8_t, int32_t, uint32_t +from sklearn.utils._typedefs cimport float32_t, float64_t, intp_t, uint8_t, uint32_t cdef enum: From ad19a8454e0b80eef0efb1e3c7caae063a380bb2 Mon Sep 17 00:00:00 2001 From: david-cortes-intel <david.cortes@intel.com> Date: Fri, 8 May 2026 03:16:59 +0200 Subject: [PATCH 443/462] DOC Clarify that prediction data with array API must be on same device (#33848) --- doc/modules/array_api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/modules/array_api.rst b/doc/modules/array_api.rst index 41ebdc50259e5..eb29e0c3fd457 100644 --- a/doc/modules/array_api.rst +++ b/doc/modules/array_api.rst @@ -92,8 +92,8 @@ The example code snippet below demonstrates how to use `CuPy After the model is trained, fitted attributes that are arrays will also be from the same Array API namespace as the training data. For example, if CuPy's Array API namespace was used for training, then fitted attributes will be on the GPU. -Passing data in a different namespace to ``transform`` or ``predict`` is an -error:: +Passing data in a different namespace or in a different device within the same +namespace to ``transform`` or ``predict`` is an error:: >>> with config_context(array_api_dispatch=True): ... lda.transform(X_np) From a481e870f00c6c874931f95f091cafa9201f1bf3 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Fri, 8 May 2026 12:55:28 +0200 Subject: [PATCH 444/462] MNT move _check_categorical_features to utils.validation (#33946) --- .../gradient_boosting.py | 114 +--------------- sklearn/utils/tests/test_validation.py | 74 +++++++++++ sklearn/utils/validation.py | 123 ++++++++++++++++++ 3 files changed, 199 insertions(+), 112 deletions(-) diff --git a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py index 2018e0bc6853e..fed9a945f4f7f 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py +++ b/sklearn/ensemble/_hist_gradient_boosting/gradient_boosting.py @@ -10,7 +10,6 @@ from numbers import Integral, Real from time import time -import narwhals.stable.v2 as nw import numpy as np from sklearn._loss.loss import ( @@ -46,6 +45,7 @@ from sklearn.utils._param_validation import Interval, RealNotInt, StrOptions from sklearn.utils.multiclass import check_classification_targets from sklearn.utils.validation import ( + _check_categorical_features, _check_monotonic_cst, _check_sample_weight, _check_y, @@ -267,7 +267,7 @@ def _preprocess_X(self, X, *, reset): return self._preprocessor.transform(X) # At this point, reset is False, which runs during `fit`. - self.is_categorical_ = self._check_categorical_features(X) + self.is_categorical_ = _check_categorical_features(X, self.categorical_features) if self.is_categorical_ is None: self._preprocessor = None @@ -353,116 +353,6 @@ def _check_categories(self): known_categories[feature_idx] = np.arange(len(categories), dtype=X_DTYPE) return known_categories - def _check_categorical_features(self, X): - """Check and validate categorical features in X - - Parameters - ---------- - X : {array-like, pandas DataFrame} of shape (n_samples, n_features) - Input data. - - Return - ------ - is_categorical : ndarray of shape (n_features,) or None, dtype=bool - Indicates whether a feature is categorical. If no feature is - categorical, this is None. - """ - if nw.dependencies.is_into_dataframe(X): - X = nw.from_native(X) - dtypes = X.schema.dtypes() - X_is_dataframe = True - categorical_columns_mask = np.asarray( - [d in (nw.Categorical, nw.Enum) for d in dtypes] - ) - else: - X_is_dataframe = False - categorical_columns_mask = None - - categorical_features = self.categorical_features - - categorical_by_dtype = ( - isinstance(categorical_features, str) - and categorical_features == "from_dtype" - ) - no_categorical_dtype = categorical_features is None or ( - categorical_by_dtype and not X_is_dataframe - ) - - if no_categorical_dtype: - return None - - if categorical_by_dtype and X_is_dataframe: - categorical_features = categorical_columns_mask - else: - categorical_features = np.asarray(categorical_features) - - if categorical_features.size == 0: - return None - - if categorical_features.dtype.kind not in ("i", "b", "U", "O"): - raise ValueError( - "categorical_features must be an array-like of bool, int or " - f"str, got: {categorical_features.dtype.name}." - ) - - if categorical_features.dtype.kind == "O": - types = set(type(f) for f in categorical_features) - if types != {str}: - raise ValueError( - "categorical_features must be an array-like of bool, int or " - f"str, got: {', '.join(sorted(t.__name__ for t in types))}." - ) - - n_features = X.shape[1] - # At this point `validate_data` was not called yet because we use the original - # dtypes to discover the categorical features. Thus `feature_names_in_` - # is not defined yet. - feature_names_in_ = getattr(X, "columns", None) - - if categorical_features.dtype.kind in ("U", "O"): - # check for feature names - if feature_names_in_ is None: - raise ValueError( - "categorical_features should be passed as an array of " - "integers or as a boolean mask when the model is fitted " - "on data without feature names." - ) - is_categorical = np.zeros(n_features, dtype=bool) - feature_names = list(feature_names_in_) - for feature_name in categorical_features: - try: - is_categorical[feature_names.index(feature_name)] = True - except ValueError as e: - raise ValueError( - f"categorical_features has an item value '{feature_name}' " - "which is not a valid feature name of the training " - f"data. Observed feature names: {feature_names}" - ) from e - elif categorical_features.dtype.kind == "i": - # check for categorical features as indices - if ( - np.max(categorical_features) >= n_features - or np.min(categorical_features) < 0 - ): - raise ValueError( - "categorical_features set as integer " - "indices must be in [0, n_features - 1]" - ) - is_categorical = np.zeros(n_features, dtype=bool) - is_categorical[categorical_features] = True - else: - if categorical_features.shape[0] != n_features: - raise ValueError( - "categorical_features set as a boolean mask " - "must have shape (n_features,), got: " - f"{categorical_features.shape}" - ) - is_categorical = categorical_features - - if not np.any(is_categorical): - return None - return is_categorical - def _check_interaction_cst(self, n_features): """Check and validation for interaction constraints.""" if self.interaction_cst is None: diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index ab87539ca9759..2cb449d72ceb8 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -65,6 +65,7 @@ from sklearn.utils.validation import ( FLOAT_DTYPES, _allclose_dense_sparse, + _check_categorical_features, _check_feature_names_in, _check_method_params, _check_pos_label_consistency, @@ -2439,3 +2440,76 @@ def test_check_array_on_sparse_inputs_with_array_api_enabled(): def test_check_array_allow_nd_errors(X, estimator, expected_error_message): with pytest.raises(ValueError, match=expected_error_message): check_array(X, estimator=estimator) + + +@pytest.mark.parametrize( + ["categorical_features", "expected_msg"], + [ + ( + [b"hello", b"world"], + re.escape( + "categorical_features must be an array-like of bool, int or str, " + "got: bytes40." + ), + ), + ( + np.array([b"hello", 1.3], dtype=object), + re.escape( + "categorical_features must be an array-like of bool, int or str, " + "got: bytes, float." + ), + ), + ( + [0, -1], + re.escape( + "categorical_features set as integer indices must be in " + "[0, n_features - 1]" + ), + ), + ( + [True, True, False, False, True], + re.escape( + "categorical_features set as a boolean mask must have shape " + "(n_features,)" + ), + ), + ], +) +def test_check_categorical_features_raises(categorical_features, expected_msg): + """Test that check_categorical_features raises expected errors.""" + rng = np.random.RandomState(0) + n_samples, n_features = 10, 10 + X = rng.randint(0, 3, size=(n_samples, n_features)) + + with pytest.raises(ValueError, match=expected_msg): + _check_categorical_features(X, categorical_features) + + +@pytest.mark.parametrize( + ["categorical_features", "on_array"], + [ + ([False, True, True, False], True), + ([1, 2], True), + (["b", "c"], False), + ("from_dtype", False), + ], +) +@pytest.mark.parametrize("constructor_name", ["array", "pandas", "polars"]) +def test_check_categorical_features(categorical_features, on_array, constructor_name): + """Test that check_categorical_features returns as expected on simple data.""" + rng = np.random.RandomState(0) + n_samples, n_features = 30, 4 + X = rng.randint(0, 3, size=(n_samples, n_features)) + if constructor_name == "array" and not on_array: + return + elif constructor_name == "polars": + X = X.astype(str) + X = _convert_container( + X, + constructor_name, + columns_name=["a", "b", "c", "d"], + categorical_feature_names=["b", "c"], + ) + + result = _check_categorical_features(X, categorical_features) + assert_allclose(result, [False, True, True, False]) diff --git a/sklearn/utils/validation.py b/sklearn/utils/validation.py index e6b2c7585be09..c1812bd3c8d5b 100644 --- a/sklearn/utils/validation.py +++ b/sklearn/utils/validation.py @@ -2468,6 +2468,129 @@ def _generate_get_feature_names_out(estimator, n_features_out, input_features=No ) +def _check_categorical_features(X, categorical_features): + """Check and validate categorical features in X + + Parameters + ---------- + X : {array-like, pandas DataFrame} of shape (n_samples, n_features) + Input data. + + categorical_features : array-like of {bool, int, str} of shape (n_features) \ + or shape (n_categorical_features,), default='from_dtype' + Indicates the categorical features in `X`. + + - None : no feature will be considered categorical. + - boolean array-like : boolean mask indicating categorical features. + - integer array-like : integer indices indicating categorical + features. + - str array-like: names of categorical features (assuming the training + data has feature names). + - `"from_dtype"`: dataframe columns with dtype "Categorical" and "Enum" are + considered to be categorical features. The input must be a dataframe that + is supported by narwhals (or supports it): :func:`narwhals.from_native` must + work. This is the case, for instance, for pandas and polars DataFrames. + + Return + ------ + is_categorical : ndarray of shape (n_features,) or None, dtype=bool + Indicates whether a feature is categorical. If no feature is + categorical, this is None. + """ + if nw.dependencies.is_into_dataframe(X): + X = nw.from_native(X) + dtypes = X.schema.dtypes() + X_is_dataframe = True + categorical_columns_mask = np.asarray( + [d in (nw.Categorical, nw.Enum) for d in dtypes] + ) + else: + X_is_dataframe = False + categorical_columns_mask = None + + categorical_by_dtype = ( + isinstance(categorical_features, str) and categorical_features == "from_dtype" + ) + no_categorical_dtype = categorical_features is None or ( + categorical_by_dtype and not X_is_dataframe + ) + + if no_categorical_dtype: + return None + + if categorical_by_dtype and X_is_dataframe: + categorical_features = categorical_columns_mask + else: + categorical_features = np.asarray(categorical_features) + + if categorical_features.size == 0: + return None + + if categorical_features.dtype.kind not in ("i", "b", "U", "O"): + raise ValueError( + "categorical_features must be an array-like of bool, int or " + f"str, got: {categorical_features.dtype.name}." + ) + + if categorical_features.dtype.kind == "O": + types = set(type(f) for f in categorical_features) + if types != {str}: + raise ValueError( + "categorical_features must be an array-like of bool, int or " + f"str, got: {', '.join(sorted(t.__name__ for t in types))}." + ) + + n_features = X.shape[1] + # At this point `validate_data` was not called yet because we use the original + # dtypes to discover the categorical features. Thus `feature_names_in_` + # is not defined yet. + feature_names_in_ = getattr(X, "columns", None) + + if categorical_features.dtype.kind in ("U", "O"): + # check for feature names + if feature_names_in_ is None: + raise ValueError( + "categorical_features should be passed as an array of " + "integers or as a boolean mask when the model is fitted " + "on data without feature names." + ) + is_categorical = np.zeros(n_features, dtype=bool) + feature_names = list(feature_names_in_) + for feature_name in categorical_features: + try: + is_categorical[feature_names.index(feature_name)] = True + except ValueError as e: + raise ValueError( + f"categorical_features has an item value '{feature_name}' " + "which is not a valid feature name of the training " + f"data. Observed feature names: {feature_names}" + ) from e + elif categorical_features.dtype.kind == "i": + # check for categorical features as indices + if ( + np.max(categorical_features) >= n_features + or np.min(categorical_features) < 0 + ): + raise ValueError( + "categorical_features set as integer " + "indices must be in [0, n_features - 1]" + ) + is_categorical = np.zeros(n_features, dtype=bool) + is_categorical[categorical_features] = True + else: + if categorical_features.shape[0] != n_features: + raise ValueError( + "categorical_features set as a boolean mask " + "must have shape (n_features,), got: " + f"{categorical_features.shape}" + ) + is_categorical = categorical_features + + if not np.any(is_categorical): + return None + return is_categorical + + def _check_monotonic_cst(estimator, monotonic_cst=None): """Check the monotonic constraints and return the corresponding array. From 900adff57900af5350fc545c4d39aceff5361a31 Mon Sep 17 00:00:00 2001 From: Virgil Chan <virchan.math@gmail.com> Date: Fri, 8 May 2026 07:21:03 -0700 Subject: [PATCH 445/462] CI adapt tolerance for `test_enet_ridge_consistency` (#33949) --- sklearn/linear_model/tests/test_coordinate_descent.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sklearn/linear_model/tests/test_coordinate_descent.py b/sklearn/linear_model/tests/test_coordinate_descent.py index e1e5292f48ef9..13e94e23ceb92 100644 --- a/sklearn/linear_model/tests/test_coordinate_descent.py +++ b/sklearn/linear_model/tests/test_coordinate_descent.py @@ -1624,11 +1624,11 @@ def test_enet_sample_weight_does_not_overwrite_sample_weight(check_input): @pytest.mark.parametrize( ["precompute", "n_targets"], [(False, 1), (True, 1), (False, 3)] ) -def test_enet_ridge_consistency(ridge_alpha, precompute, n_targets): +def test_enet_ridge_consistency(ridge_alpha, precompute, n_targets, global_random_seed): # Check that ElasticNet(l1_ratio=0) converges to the same solution as Ridge # provided that the value of alpha is adapted. - rng = np.random.RandomState(42) + rng = np.random.RandomState(global_random_seed) n_samples = 300 X, y = make_regression( n_samples=n_samples, @@ -1660,9 +1660,10 @@ def test_enet_ridge_consistency(ridge_alpha, precompute, n_targets): # The CD solver using the gram matrix (precompute = True) loses numerical precision # by working with the squares of matrices like Q=X'X (=gram) and # R^2 = y^2 + wQw - 2yQw (=square of residuals). - rtol = 1e-5 if precompute else 1e-7 - assert_allclose(enet.coef_, ridge.coef_, rtol=rtol) - assert_allclose(enet.intercept_, ridge.intercept_) + rtol = 1e-5 if precompute else 5e-7 + atol = 3e-11 + assert_allclose(enet.coef_, ridge.coef_, rtol=rtol, atol=atol) + assert_allclose(enet.intercept_, ridge.intercept_, atol=atol) @pytest.mark.filterwarnings("ignore:With alpha=0, this algorithm:UserWarning") From 113ee7473f8344cee938384f0ef1a85c59b0654e Mon Sep 17 00:00:00 2001 From: Kiyarash Fazeli <caci96@gmail.com> Date: Sat, 9 May 2026 17:24:40 +0330 Subject: [PATCH 446/462] Fix TypeError in LogisticRegressionCV with refit, use_legacy_attribute False (#33902) --- .../sklearn.linear_model/33902.fix.rst | 5 +++++ sklearn/linear_model/_logistic.py | 2 +- sklearn/linear_model/tests/test_logistic.py | 21 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.linear_model/33902.fix.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.linear_model/33902.fix.rst b/doc/whats_new/upcoming_changes/sklearn.linear_model/33902.fix.rst new file mode 100644 index 0000000000000..991afe2bb4c9e --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.linear_model/33902.fix.rst @@ -0,0 +1,5 @@ +- :class:`linear_model.LogisticRegressionCV` no longer raises a ``TypeError`` + when `refit=False` and `use_legacy_attributes=False` are set together with a + non-elasticnet penalty like `l1_ratios=[0.0]`. Previously, `None` was stored in `l1_ratio_` instead + of `0.0`, which caused `float()` to fail during post-processing. + By :user:`Mohamad Fazeli <Fazel94>`. diff --git a/sklearn/linear_model/_logistic.py b/sklearn/linear_model/_logistic.py index 779a76265eac5..62b5d0885a6b9 100644 --- a/sklearn/linear_model/_logistic.py +++ b/sklearn/linear_model/_logistic.py @@ -2195,7 +2195,7 @@ def fit(self, X, y, sample_weight=None, **params): best_indices_l1 = best_indices[:, 1] self.l1_ratio_.append(np.mean(l1_ratios_[best_indices_l1])) else: - self.l1_ratio_.append(None) + self.l1_ratio_.append(0.0) if is_binary: self.coef_ = w[:, :n_features] if w.ndim == 2 else w[:n_features][None, :] diff --git a/sklearn/linear_model/tests/test_logistic.py b/sklearn/linear_model/tests/test_logistic.py index a1bd4e2c10314..99be5686c0d69 100644 --- a/sklearn/linear_model/tests/test_logistic.py +++ b/sklearn/linear_model/tests/test_logistic.py @@ -473,6 +473,27 @@ def test_logistic_cv(global_random_seed, use_legacy_attributes): assert lr_cv.scores_.shape == (n_cv, n_l1_ratios, n_Cs) +# TODO(1.11): remove filterwarnings with change of default scoring +@pytest.mark.filterwarnings("ignore:The default value.*scoring.*:FutureWarning") +def test_logistic_cv_refit_false_non_elasticnet(global_random_seed): + """Test that non-elasticnet penalty with refit=False and + use_legacy_attributes=False works without error. + + For non-elasticnet penalties, l1_ratio=0.0 (equivalent to pure L2). + Previously, None was stored, which caused float() to raise a + TypeError when use_legacy_attributes=False converted the value to a scalar. + """ + X, y = make_classification(random_state=global_random_seed) + lr_cv = LogisticRegressionCV( + l1_ratios=[0.0], + refit=False, + use_legacy_attributes=False, + random_state=global_random_seed, + ) + lr_cv.fit(X, y) + assert lr_cv.l1_ratio_ == 0.0 + + def test_logistic_cv_mock_scorer(): """Test that LogisticRegressionCV calls the scorer.""" From e02dfc40d6323447640e1a2bc21dbc648ddcbe30 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Sat, 9 May 2026 16:05:18 +0200 Subject: [PATCH 447/462] MNT move bitset from HGBT to utils (#33957) Co-authored-by: Adam Li <adam2392@gmail.com> --- .../_hist_gradient_boosting/_bitset.pxd | 20 ------ .../_hist_gradient_boosting/_bitset.pyx | 65 ------------------- .../_hist_gradient_boosting/_predictor.pyx | 3 +- .../_hist_gradient_boosting/binning.py | 2 +- .../_hist_gradient_boosting/common.pxd | 8 ++- .../_hist_gradient_boosting/common.pyx | 3 + .../_hist_gradient_boosting/grower.py | 4 +- .../_hist_gradient_boosting/meson.build | 1 - .../_hist_gradient_boosting/splitting.pyx | 7 +- .../tests/test_predictor.py | 8 +-- sklearn/utils/_bitset.pxd | 21 ++++++ sklearn/utils/_bitset.pyx | 63 ++++++++++++++++++ sklearn/utils/meson.build | 2 + .../tests/test_bitset.py | 5 +- 14 files changed, 105 insertions(+), 107 deletions(-) delete mode 100644 sklearn/ensemble/_hist_gradient_boosting/_bitset.pxd delete mode 100644 sklearn/ensemble/_hist_gradient_boosting/_bitset.pyx create mode 100644 sklearn/utils/_bitset.pxd create mode 100644 sklearn/utils/_bitset.pyx rename sklearn/{ensemble/_hist_gradient_boosting => utils}/tests/test_bitset.py (90%) diff --git a/sklearn/ensemble/_hist_gradient_boosting/_bitset.pxd b/sklearn/ensemble/_hist_gradient_boosting/_bitset.pxd deleted file mode 100644 index 83dda474bab7f..0000000000000 --- a/sklearn/ensemble/_hist_gradient_boosting/_bitset.pxd +++ /dev/null @@ -1,20 +0,0 @@ -from sklearn.ensemble._hist_gradient_boosting.common cimport X_BINNED_DTYPE_C -from sklearn.ensemble._hist_gradient_boosting.common cimport BITSET_DTYPE_C -from sklearn.ensemble._hist_gradient_boosting.common cimport BITSET_INNER_DTYPE_C -from sklearn.ensemble._hist_gradient_boosting.common cimport X_DTYPE_C -from sklearn.utils._typedefs cimport uint8_t - - -cdef void init_bitset(BITSET_DTYPE_C bitset) noexcept nogil - -cdef void set_bitset(BITSET_DTYPE_C bitset, X_BINNED_DTYPE_C val) noexcept nogil - -cdef uint8_t in_bitset(BITSET_DTYPE_C bitset, X_BINNED_DTYPE_C val) noexcept nogil - -cpdef uint8_t in_bitset_memoryview(const BITSET_INNER_DTYPE_C[:] bitset, - X_BINNED_DTYPE_C val) noexcept nogil - -cdef uint8_t in_bitset_2d_memoryview( - const BITSET_INNER_DTYPE_C[:, :] bitset, - X_BINNED_DTYPE_C val, - unsigned int row) noexcept nogil diff --git a/sklearn/ensemble/_hist_gradient_boosting/_bitset.pyx b/sklearn/ensemble/_hist_gradient_boosting/_bitset.pyx deleted file mode 100644 index e80ce0e16985d..0000000000000 --- a/sklearn/ensemble/_hist_gradient_boosting/_bitset.pyx +++ /dev/null @@ -1,65 +0,0 @@ -from sklearn.ensemble._hist_gradient_boosting.common cimport BITSET_INNER_DTYPE_C -from sklearn.ensemble._hist_gradient_boosting.common cimport BITSET_DTYPE_C -from sklearn.ensemble._hist_gradient_boosting.common cimport X_DTYPE_C -from sklearn.ensemble._hist_gradient_boosting.common cimport X_BINNED_DTYPE_C -from sklearn.utils._typedefs cimport uint8_t - - -# A bitset is a data structure used to represent sets of integers in [0, n]. We -# use them to represent sets of features indices (e.g. features that go to the -# left child, or features that are categorical). For familiarity with bitsets -# and bitwise operations: -# https://en.wikipedia.org/wiki/Bit_array -# https://en.wikipedia.org/wiki/Bitwise_operation - - -cdef inline void init_bitset(BITSET_DTYPE_C bitset) noexcept nogil: # OUT - cdef: - unsigned int i - - for i in range(8): - bitset[i] = 0 - - -cdef inline void set_bitset(BITSET_DTYPE_C bitset, # OUT - X_BINNED_DTYPE_C val) noexcept nogil: - bitset[val // 32] |= (1 << (val % 32)) - - -cdef inline uint8_t in_bitset(BITSET_DTYPE_C bitset, - X_BINNED_DTYPE_C val) noexcept nogil: - return (bitset[val // 32] >> (val % 32)) & 1 - - -cpdef inline uint8_t in_bitset_memoryview(const BITSET_INNER_DTYPE_C[:] bitset, - X_BINNED_DTYPE_C val) noexcept nogil: - return (bitset[val // 32] >> (val % 32)) & 1 - - -cdef inline uint8_t in_bitset_2d_memoryview(const BITSET_INNER_DTYPE_C[:, :] bitset, - X_BINNED_DTYPE_C val, - unsigned int row) noexcept nogil: - # Same as above but works on 2d memory views to avoid the creation of 1d - # memory views. See https://github.com/scikit-learn/scikit-learn/issues/17299 - return (bitset[row, val // 32] >> (val % 32)) & 1 - - -cpdef inline void set_bitset_memoryview(BITSET_INNER_DTYPE_C[:] bitset, # OUT - X_BINNED_DTYPE_C val): - bitset[val // 32] |= (1 << (val % 32)) - - -def set_raw_bitset_from_binned_bitset(BITSET_INNER_DTYPE_C[:] raw_bitset, # OUT - BITSET_INNER_DTYPE_C[:] binned_bitset, - X_DTYPE_C[:] categories): - """Set the raw_bitset from the values of the binned bitset - - categories is a mapping from binned category value to raw category value. - """ - cdef: - int binned_cat_value - X_DTYPE_C raw_cat_value - - for binned_cat_value, raw_cat_value in enumerate(categories): - if in_bitset_memoryview(binned_bitset, binned_cat_value): - set_bitset_memoryview(raw_bitset, <X_BINNED_DTYPE_C>raw_cat_value) diff --git a/sklearn/ensemble/_hist_gradient_boosting/_predictor.pyx b/sklearn/ensemble/_hist_gradient_boosting/_predictor.pyx index 37f8055fcdf8c..e8dde001ec98e 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/_predictor.pyx +++ b/sklearn/ensemble/_hist_gradient_boosting/_predictor.pyx @@ -5,14 +5,13 @@ from cython.parallel import prange from libc.math cimport isnan import numpy as np +from sklearn.utils._bitset cimport BITSET_INNER_DTYPE_C, in_bitset_2d_memoryview from sklearn.utils._typedefs cimport intp_t, uint8_t from sklearn.ensemble._hist_gradient_boosting.common cimport X_DTYPE_C from sklearn.ensemble._hist_gradient_boosting.common cimport Y_DTYPE_C from sklearn.ensemble._hist_gradient_boosting.common import Y_DTYPE from sklearn.ensemble._hist_gradient_boosting.common cimport X_BINNED_DTYPE_C -from sklearn.ensemble._hist_gradient_boosting.common cimport BITSET_INNER_DTYPE_C from sklearn.ensemble._hist_gradient_boosting.common cimport node_struct -from sklearn.ensemble._hist_gradient_boosting._bitset cimport in_bitset_2d_memoryview def _predict_from_raw_data( # raw data = non-binned data diff --git a/sklearn/ensemble/_hist_gradient_boosting/binning.py b/sklearn/ensemble/_hist_gradient_boosting/binning.py index 3b3a4108359ee..444249eda041c 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/binning.py +++ b/sklearn/ensemble/_hist_gradient_boosting/binning.py @@ -14,7 +14,6 @@ from sklearn.base import BaseEstimator, TransformerMixin from sklearn.ensemble._hist_gradient_boosting._binning import _map_to_bins -from sklearn.ensemble._hist_gradient_boosting._bitset import set_bitset_memoryview from sklearn.ensemble._hist_gradient_boosting.common import ( ALMOST_INF, X_BINNED_DTYPE, @@ -22,6 +21,7 @@ X_DTYPE, ) from sklearn.utils import check_array, check_random_state +from sklearn.utils._bitset import set_bitset_memoryview from sklearn.utils._openmp_helpers import _openmp_effective_n_threads from sklearn.utils.parallel import Parallel, delayed from sklearn.utils.stats import _weighted_percentile diff --git a/sklearn/ensemble/_hist_gradient_boosting/common.pxd b/sklearn/ensemble/_hist_gradient_boosting/common.pxd index 63ae2a3da2d3d..ec98206a685cc 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/common.pxd +++ b/sklearn/ensemble/_hist_gradient_boosting/common.pxd @@ -1,12 +1,14 @@ -from sklearn.utils._typedefs cimport float32_t, float64_t, intp_t, uint8_t, uint32_t +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +from sklearn.utils._bitset cimport BITSET_INNER_DTYPE_C, BITSET_INNER_DTYPE_C +from sklearn.utils._typedefs cimport float32_t, float64_t, intp_t, uint8_t ctypedef float64_t X_DTYPE_C ctypedef uint8_t X_BINNED_DTYPE_C ctypedef float64_t Y_DTYPE_C ctypedef float32_t G_H_DTYPE_C -ctypedef uint32_t BITSET_INNER_DTYPE_C -ctypedef BITSET_INNER_DTYPE_C[8] BITSET_DTYPE_C cdef packed struct hist_struct: diff --git a/sklearn/ensemble/_hist_gradient_boosting/common.pyx b/sklearn/ensemble/_hist_gradient_boosting/common.pyx index 6b20e32813d5b..184c80c72f088 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/common.pyx +++ b/sklearn/ensemble/_hist_gradient_boosting/common.pyx @@ -1,3 +1,6 @@ +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + import numpy as np # Y_DYTPE is the dtype to which the targets y are converted to. This is also diff --git a/sklearn/ensemble/_hist_gradient_boosting/grower.py b/sklearn/ensemble/_hist_gradient_boosting/grower.py index d734c390ad824..55bcb35d4df64 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/grower.py +++ b/sklearn/ensemble/_hist_gradient_boosting/grower.py @@ -14,9 +14,6 @@ import numpy as np -from sklearn.ensemble._hist_gradient_boosting._bitset import ( - set_raw_bitset_from_binned_bitset, -) from sklearn.ensemble._hist_gradient_boosting.common import ( PREDICTOR_RECORD_DTYPE, X_BITSET_INNER_DTYPE, @@ -25,6 +22,7 @@ from sklearn.ensemble._hist_gradient_boosting.histogram import HistogramBuilder from sklearn.ensemble._hist_gradient_boosting.predictor import TreePredictor from sklearn.ensemble._hist_gradient_boosting.splitting import Splitter +from sklearn.utils._bitset import set_raw_bitset_from_binned_bitset from sklearn.utils._openmp_helpers import _openmp_effective_n_threads diff --git a/sklearn/ensemble/_hist_gradient_boosting/meson.build b/sklearn/ensemble/_hist_gradient_boosting/meson.build index 1114b7719a2f4..7b5f1c6b5963e 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/meson.build +++ b/sklearn/ensemble/_hist_gradient_boosting/meson.build @@ -12,7 +12,6 @@ hist_gradient_boosting_extension_metadata = { 'splitting': {'sources': [cython_gen.process('splitting.pyx')], 'dependencies': [openmp_dep]}, '_binning': {'sources': [cython_gen.process('_binning.pyx')], 'dependencies': [openmp_dep]}, '_predictor': {'sources': [cython_gen.process('_predictor.pyx')], 'dependencies': [openmp_dep]}, - '_bitset': {'sources': [cython_gen.process('_bitset.pyx')]}, 'common': {'sources': [cython_gen.process('common.pyx')]}, } diff --git a/sklearn/ensemble/_hist_gradient_boosting/splitting.pyx b/sklearn/ensemble/_hist_gradient_boosting/splitting.pyx index 8b8b976415d81..6fae29e26ee4b 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/splitting.pyx +++ b/sklearn/ensemble/_hist_gradient_boosting/splitting.pyx @@ -16,16 +16,13 @@ from libc.math cimport INFINITY, ceil from libc.stdlib cimport malloc, free, qsort from libc.string cimport memcpy +from sklearn.utils._bitset cimport BITSET_DTYPE_C, BITSET_INNER_DTYPE_C +from sklearn.utils._bitset cimport in_bitset, init_bitset, set_bitset from sklearn.utils._typedefs cimport uint8_t from sklearn.ensemble._hist_gradient_boosting.common cimport X_BINNED_DTYPE_C from sklearn.ensemble._hist_gradient_boosting.common cimport Y_DTYPE_C from sklearn.ensemble._hist_gradient_boosting.common cimport hist_struct -from sklearn.ensemble._hist_gradient_boosting.common cimport BITSET_INNER_DTYPE_C -from sklearn.ensemble._hist_gradient_boosting.common cimport BITSET_DTYPE_C from sklearn.ensemble._hist_gradient_boosting.common cimport MonotonicConstraint -from sklearn.ensemble._hist_gradient_boosting._bitset cimport init_bitset -from sklearn.ensemble._hist_gradient_boosting._bitset cimport set_bitset -from sklearn.ensemble._hist_gradient_boosting._bitset cimport in_bitset cdef struct split_info_struct: diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_predictor.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_predictor.py index ae9770ca14a83..0612e038aa0a8 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_predictor.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_predictor.py @@ -3,10 +3,6 @@ from numpy.testing import assert_allclose from sklearn.datasets import make_regression -from sklearn.ensemble._hist_gradient_boosting._bitset import ( - set_bitset_memoryview, - set_raw_bitset_from_binned_bitset, -) from sklearn.ensemble._hist_gradient_boosting.binning import _BinMapper from sklearn.ensemble._hist_gradient_boosting.common import ( ALMOST_INF, @@ -20,6 +16,10 @@ from sklearn.ensemble._hist_gradient_boosting.predictor import TreePredictor from sklearn.metrics import r2_score from sklearn.model_selection import train_test_split +from sklearn.utils._bitset import ( + set_bitset_memoryview, + set_raw_bitset_from_binned_bitset, +) from sklearn.utils._openmp_helpers import _openmp_effective_n_threads n_threads = _openmp_effective_n_threads() diff --git a/sklearn/utils/_bitset.pxd b/sklearn/utils/_bitset.pxd new file mode 100644 index 0000000000000..5b8b145c08d80 --- /dev/null +++ b/sklearn/utils/_bitset.pxd @@ -0,0 +1,21 @@ +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + +from sklearn.utils._typedefs cimport float64_t, uint8_t, uint32_t + +ctypedef uint32_t BITSET_INNER_DTYPE_C +ctypedef BITSET_INNER_DTYPE_C[8] BITSET_DTYPE_C + +cdef void init_bitset(BITSET_DTYPE_C bitset) noexcept nogil + +cdef void set_bitset(BITSET_DTYPE_C bitset, uint8_t val) noexcept nogil + +cdef uint8_t in_bitset(BITSET_DTYPE_C bitset, uint8_t val) noexcept nogil + +cpdef uint8_t in_bitset_memoryview( + const BITSET_INNER_DTYPE_C[:] bitset, uint8_t val +) noexcept nogil + +cdef uint8_t in_bitset_2d_memoryview( + const BITSET_INNER_DTYPE_C[:, :] bitset, uint8_t val, unsigned int row +) noexcept nogil diff --git a/sklearn/utils/_bitset.pyx b/sklearn/utils/_bitset.pyx new file mode 100644 index 0000000000000..4b275eba03e69 --- /dev/null +++ b/sklearn/utils/_bitset.pyx @@ -0,0 +1,63 @@ +""" +A bitset is a data structure used to represent sets of integers in [0, n]. For decision +trees, we use them to represent sets of features indices (e.g. features that go to the +left child, or features that are categorical). For familiarity with bitsets and bitwise +operations see: +https://en.wikipedia.org/wiki/Bit_array +https://en.wikipedia.org/wiki/Bitwise_operation +""" + +# Authors: The scikit-learn developers +# SPDX-License-Identifier: BSD-3-Clause + + +cdef inline void init_bitset(BITSET_DTYPE_C bitset) noexcept nogil: + cdef: + unsigned int i + + for i in range(8): + bitset[i] = 0 + + +cdef inline void set_bitset(BITSET_DTYPE_C bitset, uint8_t val) noexcept nogil: + bitset[val // 32] |= (1 << (val % 32)) + + +cdef inline uint8_t in_bitset(BITSET_DTYPE_C bitset, uint8_t val) noexcept nogil: + return (bitset[val // 32] >> (val % 32)) & 1 + + +cpdef inline uint8_t in_bitset_memoryview( + const BITSET_INNER_DTYPE_C[:] bitset, uint8_t val +) noexcept nogil: + return (bitset[val // 32] >> (val % 32)) & 1 + + +cdef inline uint8_t in_bitset_2d_memoryview( + const BITSET_INNER_DTYPE_C[:, :] bitset, uint8_t val, unsigned int row +) noexcept nogil: + # Same as above but works on 2d memory views to avoid the creation of 1d + # memory views. See https://github.com/scikit-learn/scikit-learn/issues/17299 + return (bitset[row, val // 32] >> (val % 32)) & 1 + + +cpdef inline void set_bitset_memoryview(BITSET_INNER_DTYPE_C[:] bitset, uint8_t val): + bitset[val // 32] |= (1 << (val % 32)) + + +def set_raw_bitset_from_binned_bitset( + BITSET_INNER_DTYPE_C[:] raw_bitset, + BITSET_INNER_DTYPE_C[:] binned_bitset, + float64_t[:] categories, +): + """Set the raw_bitset from the values of the binned bitset + + categories is a mapping from binned category value to raw category value. + """ + cdef: + int binned_cat_value + float64_t raw_cat_value + + for binned_cat_value, raw_cat_value in enumerate(categories): + if in_bitset_memoryview(binned_bitset, binned_cat_value): + set_bitset_memoryview(raw_bitset, <uint8_t>raw_cat_value) diff --git a/sklearn/utils/meson.build b/sklearn/utils/meson.build index c3402df91363c..71b98c088d4c1 100644 --- a/sklearn/utils/meson.build +++ b/sklearn/utils/meson.build @@ -24,6 +24,7 @@ utils_cython_tree = [ # early in the build sklearn_root_cython_tree, fs.copyfile('__init__.py'), + fs.copyfile('_bitset.pxd'), fs.copyfile('_cython_blas.pxd'), fs.copyfile('_heap.pxd'), fs.copyfile('_openmp_helpers.pxd'), @@ -38,6 +39,7 @@ utils_extension_metadata = { {'sources': [cython_gen.process('sparsefuncs_fast.pyx')]}, '_cython_blas': {'sources': [cython_gen.process('_cython_blas.pyx'), _blas_int_pxi]}, 'arrayfuncs': {'sources': [cython_gen.process('arrayfuncs.pyx')]}, + '_bitset': {'sources': [cython_gen.process('_bitset.pyx')]}, 'murmurhash': { 'sources': [cython_gen.process('murmurhash.pyx'), 'src' / 'MurmurHash3.cpp'], }, diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_bitset.py b/sklearn/utils/tests/test_bitset.py similarity index 90% rename from sklearn/ensemble/_hist_gradient_boosting/tests/test_bitset.py rename to sklearn/utils/tests/test_bitset.py index c02d66b666f80..8a8277ba56dfb 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_bitset.py +++ b/sklearn/utils/tests/test_bitset.py @@ -2,12 +2,11 @@ import pytest from numpy.testing import assert_allclose -from sklearn.ensemble._hist_gradient_boosting._bitset import ( +from sklearn.utils._bitset import ( in_bitset_memoryview, set_bitset_memoryview, set_raw_bitset_from_binned_bitset, ) -from sklearn.ensemble._hist_gradient_boosting.common import X_DTYPE @pytest.mark.parametrize( @@ -49,7 +48,7 @@ def test_raw_bitset_from_binned_bitset( ): binned_bitset = np.zeros(2, dtype=np.uint32) raw_bitset = np.zeros(2, dtype=np.uint32) - raw_categories = np.asarray(raw_categories, dtype=X_DTYPE) + raw_categories = np.asarray(raw_categories, dtype=np.float64) for val in binned_cat_to_insert: set_bitset_memoryview(binned_bitset, val) From a421648c9d5b68b2e3a1f710ebd75220ccd47ba3 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Sat, 9 May 2026 17:18:14 +0200 Subject: [PATCH 448/462] MNT _convert_container "dataframe" -> "pandas" (#33956) --- sklearn/datasets/tests/test_openml.py | 4 +- .../tests/test_monotonic_constraints.py | 2 +- sklearn/impute/tests/test_base.py | 4 +- sklearn/impute/tests/test_impute.py | 10 ++-- .../tests/test_plot_partial_dependence.py | 24 ++++---- sklearn/inspection/tests/test_pd_utils.py | 2 +- .../tests/test_permutation_importance.py | 2 +- sklearn/linear_model/tests/test_bayes.py | 2 +- sklearn/preprocessing/tests/test_encoders.py | 2 +- sklearn/tests/test_base.py | 2 +- sklearn/utils/_testing.py | 4 +- sklearn/utils/tests/test_array_api.py | 4 +- sklearn/utils/tests/test_dataframe.py | 8 +-- sklearn/utils/tests/test_indexing.py | 14 ++--- sklearn/utils/tests/test_mocking.py | 2 +- sklearn/utils/tests/test_testing.py | 8 +-- sklearn/utils/tests/test_validation.py | 58 +++++++------------ 17 files changed, 64 insertions(+), 88 deletions(-) diff --git a/sklearn/datasets/tests/test_openml.py b/sklearn/datasets/tests/test_openml.py index 7639558652137..916c42d7cab7e 100644 --- a/sklearn/datasets/tests/test_openml.py +++ b/sklearn/datasets/tests/test_openml.py @@ -1042,7 +1042,7 @@ def test_fetch_openml_sparse_arff_error(monkeypatch, params, err_msg): @pytest.mark.parametrize( "data_id, data_type", [ - (61, "dataframe"), # iris dataset version 1 + (61, "pandas"), # iris dataset version 1 (292, "sparse"), # Australian dataset version 1 ], ) @@ -1052,7 +1052,7 @@ def test_fetch_openml_auto_mode(monkeypatch, data_id, data_type): _monkey_patch_webbased_functions(monkeypatch, data_id, True) data = fetch_openml(data_id=data_id, as_frame="auto", cache=False) - klass = pd.DataFrame if data_type == "dataframe" else scipy.sparse.csr_matrix + klass = pd.DataFrame if data_type == "pandas" else scipy.sparse.csr_matrix assert isinstance(data.data, klass) diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_monotonic_constraints.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_monotonic_constraints.py index 56b6068d794e8..d9adbc2b71ac5 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_monotonic_constraints.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_monotonic_constraints.py @@ -226,7 +226,7 @@ def test_predictions(global_random_seed, use_feature_names): X = np.c_[f_a, f_0, f_b, f_1, f_c] columns_name = ["f_a", "f_0", "f_b", "f_1", "f_c"] - constructor_name = "dataframe" if use_feature_names else "array" + constructor_name = "pandas" if use_feature_names else "array" X = _convert_container(X, constructor_name, columns_name=columns_name) noise = rng.normal(loc=0.0, scale=0.01, size=n_samples) diff --git a/sklearn/impute/tests/test_base.py b/sklearn/impute/tests/test_base.py index 0c1bd83f7ca9e..35ed59db89028 100644 --- a/sklearn/impute/tests/test_base.py +++ b/sklearn/impute/tests/test_base.py @@ -90,7 +90,7 @@ def test_base_no_precomputed_mask_transform(data): imputer.fit_transform(data) -@pytest.mark.parametrize("X1_type", ["array", "dataframe"]) +@pytest.mark.parametrize("X1_type", ["array", "pandas"]) def test_assign_where(X1_type): """Check the behaviour of the private helpers `_assign_where`.""" rng = np.random.RandomState(0) @@ -102,6 +102,6 @@ def test_assign_where(X1_type): _assign_where(X1, X2, mask) - if X1_type == "dataframe": + if X1_type == "pandas": X1 = X1.to_numpy() assert_allclose(X1[mask], X2[mask]) diff --git a/sklearn/impute/tests/test_impute.py b/sklearn/impute/tests/test_impute.py index 6605b1cd76cef..09a07e1a3c832 100644 --- a/sklearn/impute/tests/test_impute.py +++ b/sklearn/impute/tests/test_impute.py @@ -286,12 +286,12 @@ def test_imputation_mean_median_error_invalid_type(strategy, dtype): @pytest.mark.parametrize("strategy", ["mean", "median"]) -@pytest.mark.parametrize("type", ["list", "dataframe"]) -def test_imputation_mean_median_error_invalid_type_list_pandas(strategy, type): +@pytest.mark.parametrize("constructor_name", ["list", "pandas"]) +def test_imputation_mean_median_error_invalid_type_list_pandas( + strategy, constructor_name +): X = [["a", "b", 3], [4, "e", 6], ["g", "h", 9]] - if type == "dataframe": - pd = pytest.importorskip("pandas") - X = pd.DataFrame(X) + X = _convert_container(X, constructor_name) msg = "non-numeric data:\ncould not convert string to float:" with pytest.raises(ValueError, match=msg): imputer = SimpleImputer(strategy=strategy) diff --git a/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py b/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py index 855c88e17fe15..021362b6b983a 100644 --- a/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py +++ b/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py @@ -178,17 +178,17 @@ def test_plot_partial_dependence_kind( @pytest.mark.parametrize( "input_type, feature_names_type", [ - ("dataframe", None), - ("dataframe", "list"), + ("pandas", None), + ("pandas", "list"), ("list", "list"), ("array", "list"), - ("dataframe", "array"), + ("pandas", "array"), ("list", "array"), ("array", "array"), - ("dataframe", "series"), + ("pandas", "series"), ("list", "series"), ("array", "series"), - ("dataframe", "index"), + ("pandas", "index"), ("list", "index"), ("array", "index"), ], @@ -205,13 +205,9 @@ def test_plot_partial_dependence_str_features( age = diabetes.data[:, diabetes.feature_names.index("age")] bmi = diabetes.data[:, diabetes.feature_names.index("bmi")] - if input_type == "dataframe": - pd = pytest.importorskip("pandas") - X = pd.DataFrame(diabetes.data, columns=diabetes.feature_names) - elif input_type == "list": - X = diabetes.data.tolist() - else: - X = diabetes.data + X = _convert_container( + diabetes.data, input_type, columns_name=diabetes.feature_names + ) if feature_names_type is None: feature_names = None @@ -803,7 +799,7 @@ def test_plot_partial_dependence_does_not_override_ylabel( @pytest.mark.parametrize( "categorical_features, array_type", [ - (["col_A", "col_C"], "dataframe"), + (["col_A", "col_C"], "pandas"), ([0, 2], "array"), ([True, False, True], "array"), ], @@ -985,7 +981,7 @@ def test_partial_dependence_overwrite_labels( @pytest.mark.parametrize( "categorical_features, array_type", [ - (["col_A", "col_C"], "dataframe"), + (["col_A", "col_C"], "pandas"), ([0, 2], "array"), ([True, False, True], "array"), ], diff --git a/sklearn/inspection/tests/test_pd_utils.py b/sklearn/inspection/tests/test_pd_utils.py index 5dea3834a77a7..d3d4a70a8ee8f 100644 --- a/sklearn/inspection/tests/test_pd_utils.py +++ b/sklearn/inspection/tests/test_pd_utils.py @@ -9,7 +9,7 @@ "feature_names, array_type, expected_feature_names", [ (None, "array", ["x0", "x1", "x2"]), - (None, "dataframe", ["a", "b", "c"]), + (None, "pandas", ["a", "b", "c"]), (np.array(["a", "b", "c"]), "array", ["a", "b", "c"]), ], ) diff --git a/sklearn/inspection/tests/test_permutation_importance.py b/sklearn/inspection/tests/test_permutation_importance.py index c09daee20dbd9..d105d0943be02 100644 --- a/sklearn/inspection/tests/test_permutation_importance.py +++ b/sklearn/inspection/tests/test_permutation_importance.py @@ -369,7 +369,7 @@ def test_permutation_importance_equivalence_array_dataframe(n_jobs, max_samples) ) -@pytest.mark.parametrize("input_type", ["array", "dataframe"]) +@pytest.mark.parametrize("input_type", ["array", "pandas"]) def test_permutation_importance_large_memmaped_data(input_type): # Smoke, non-regression test for: # https://github.com/scikit-learn/scikit-learn/issues/15810 diff --git a/sklearn/linear_model/tests/test_bayes.py b/sklearn/linear_model/tests/test_bayes.py index abb21decb9484..af730a57a8364 100644 --- a/sklearn/linear_model/tests/test_bayes.py +++ b/sklearn/linear_model/tests/test_bayes.py @@ -240,7 +240,7 @@ def test_ard_accuracy_on_easy_problem(global_random_seed, n_samples, n_features) assert abs_coef_error < 1e-10 -@pytest.mark.parametrize("constructor_name", ["array", "dataframe"]) +@pytest.mark.parametrize("constructor_name", ["array", "pandas"]) def test_return_std(constructor_name, global_random_seed): # Test return_std option for both Bayesian regressors rng = np.random.RandomState(global_random_seed) diff --git a/sklearn/preprocessing/tests/test_encoders.py b/sklearn/preprocessing/tests/test_encoders.py index e7baa4b0bd0d8..e172dcafa07b0 100644 --- a/sklearn/preprocessing/tests/test_encoders.py +++ b/sklearn/preprocessing/tests/test_encoders.py @@ -1394,7 +1394,7 @@ def test_ohe_infrequent_user_cats_unknown_training_errors(kwargs): @pytest.mark.parametrize( "input_dtype, category_dtype", ["OO", "OU", "UO", "UU", "SO", "SU", "SS"] ) -@pytest.mark.parametrize("array_type", ["list", "array", "dataframe"]) +@pytest.mark.parametrize("array_type", ["list", "array", "pandas"]) def test_encoders_string_categories(input_dtype, category_dtype, array_type): """Check that encoding work with object, unicode, and byte string dtypes. Non-regression test for: diff --git a/sklearn/tests/test_base.py b/sklearn/tests/test_base.py index bd151b40242ce..b7e308c4f648d 100644 --- a/sklearn/tests/test_base.py +++ b/sklearn/tests/test_base.py @@ -914,7 +914,7 @@ class Estimator(BaseEstimator, WithSlots): @pytest.mark.parametrize( "constructor_name, minversion", [ - ("dataframe", "1.5.0"), + ("pandas", "1.5.0"), ("pyarrow", "13.0.0"), ("polars", "0.20.23"), ], diff --git a/sklearn/utils/_testing.py b/sklearn/utils/_testing.py index 792259482ae79..dd9ff797566ba 100644 --- a/sklearn/utils/_testing.py +++ b/sklearn/utils/_testing.py @@ -978,7 +978,7 @@ def _convert_container( ---------- container : array-like The container to convert. - constructor_name : {"list", "tuple", "array", "sparse", "dataframe", \ + constructor_name : {"list", "tuple", "array", "sparse", \ "pandas", "series", "index", "slice", "sparse_csr", "sparse_csc", \ "sparse_csr_array", "sparse_csc_array", "pyarrow", "polars", \ "polars_series"} @@ -1010,7 +1010,7 @@ def _convert_container( return tuple(np.asarray(container, dtype=dtype).tolist()) elif constructor_name == "array": return np.asarray(container, dtype=dtype) - elif constructor_name in ("pandas", "dataframe"): + elif constructor_name == "pandas": pd = pytest.importorskip("pandas", minversion=minversion) result = pd.DataFrame(container, columns=columns_name, dtype=dtype, copy=False) if categorical_feature_names is not None: diff --git a/sklearn/utils/tests/test_array_api.py b/sklearn/utils/tests/test_array_api.py index 480b35896a3ef..a2060468f78f6 100644 --- a/sklearn/utils/tests/test_array_api.py +++ b/sklearn/utils/tests/test_array_api.py @@ -93,9 +93,7 @@ def test_get_namespace_ndarray_or_similar_default_with_dispatch(X): @skip_if_array_api_compat_not_configured -@pytest.mark.parametrize( - "constructor_name", ["pyarrow", "dataframe", "polars", "series"] -) +@pytest.mark.parametrize("constructor_name", ["pyarrow", "pandas", "polars", "series"]) def test_get_namespace_df_with_dispatch(constructor_name): """Test get_namespace on dataframes and series.""" diff --git a/sklearn/utils/tests/test_dataframe.py b/sklearn/utils/tests/test_dataframe.py index 49e5296590c34..fc626db52a96c 100644 --- a/sklearn/utils/tests/test_dataframe.py +++ b/sklearn/utils/tests/test_dataframe.py @@ -8,7 +8,7 @@ from sklearn.utils._testing import _convert_container -@pytest.mark.parametrize("constructor_name", ["pyarrow", "dataframe", "polars"]) +@pytest.mark.parametrize("constructor_name", ["pyarrow", "pandas", "polars"]) def test_is_df_or_series(constructor_name): df = _convert_container([[1, 4, 2], [3, 3, 6]], constructor_name) @@ -16,7 +16,7 @@ def test_is_df_or_series(constructor_name): assert not is_df_or_series(np.asarray([1, 2, 3])) -@pytest.mark.parametrize("constructor_name", ["pyarrow", "dataframe", "polars"]) +@pytest.mark.parametrize("constructor_name", ["pyarrow", "pandas", "polars"]) def test_is_pandas_df_other_libraries(constructor_name): df = _convert_container([[1, 4, 2], [3, 3, 6]], constructor_name) if constructor_name in ("pyarrow", "polars"): @@ -45,7 +45,7 @@ def test_is_pandas_df_pandas_not_installed(hide_available_pandas): "constructor_name, minversion", [ ("pyarrow", dependent_packages["pyarrow"][0]), - ("dataframe", dependent_packages["pandas"][0]), + ("pandas", dependent_packages["pandas"][0]), ("polars", dependent_packages["polars"][0]), ], ) @@ -55,7 +55,7 @@ def test_is_polars_df_other_libraries(constructor_name, minversion): constructor_name, minversion=minversion, ) - if constructor_name in ("pyarrow", "dataframe"): + if constructor_name in ("pyarrow", "pandas"): assert not is_polars_df(df) else: assert is_polars_df(df) diff --git a/sklearn/utils/tests/test_indexing.py b/sklearn/utils/tests/test_indexing.py index 84b69b84c80eb..d462e773df497 100644 --- a/sklearn/utils/tests/test_indexing.py +++ b/sklearn/utils/tests/test_indexing.py @@ -173,7 +173,7 @@ def test_safe_indexing_array_api_support( @pytest.mark.parametrize( - "array_type", ["list", "array", "sparse", "dataframe", "polars", "pyarrow"] + "array_type", ["list", "array", "sparse", "pandas", "polars", "pyarrow"] ) @pytest.mark.parametrize("indices_type", ["list", "tuple", "array", "series", "slice"]) def test_safe_indexing_2d_container_axis_0(array_type, indices_type): @@ -203,7 +203,7 @@ def test_safe_indexing_1d_container(array_type, indices_type): @pytest.mark.parametrize( - "array_type", ["array", "sparse", "dataframe", "polars", "pyarrow"] + "array_type", ["array", "sparse", "pandas", "polars", "pyarrow"] ) @pytest.mark.parametrize("indices_type", ["list", "tuple", "array", "series", "slice"]) @pytest.mark.parametrize("indices", [[1, 2], ["col_1", "col_2"]]) @@ -236,7 +236,7 @@ def test_safe_indexing_2d_container_axis_1(array_type, indices_type, indices): @pytest.mark.parametrize("array_read_only", [True, False]) @pytest.mark.parametrize("indices_read_only", [True, False]) @pytest.mark.parametrize( - "array_type", ["array", "sparse", "dataframe", "polars", "pyarrow"] + "array_type", ["array", "sparse", "pandas", "polars", "pyarrow"] ) @pytest.mark.parametrize("indices_type", ["array", "series"]) @pytest.mark.parametrize( @@ -270,7 +270,7 @@ def test_safe_indexing_1d_container_mask(array_type, indices_type): @pytest.mark.parametrize( - "array_type", ["array", "sparse", "dataframe", "polars", "pyarrow"] + "array_type", ["array", "sparse", "pandas", "polars", "pyarrow"] ) @pytest.mark.parametrize("indices_type", ["list", "tuple", "array", "series"]) @pytest.mark.parametrize( @@ -297,7 +297,7 @@ def test_safe_indexing_2d_mask(array_type, indices_type, axis, expected_subset): ("list", "list"), ("array", "array"), ("sparse", "sparse"), - ("dataframe", "series"), + ("pandas", "series"), ("polars", "polars_series"), ("pyarrow", "pyarrow_array"), ], @@ -325,7 +325,7 @@ def test_safe_indexing_1d_scalar(array_type): [ ("array", "array"), ("sparse", "sparse"), - ("dataframe", "series"), + ("pandas", "series"), ("polars", "polars_series"), ("pyarrow", "pyarrow_array"), ], @@ -440,7 +440,7 @@ def test_safe_indexing_list_axis_1_unsupported(indices): _safe_indexing(X, indices, axis=1) -@pytest.mark.parametrize("array_type", ["array", "sparse", "dataframe"]) +@pytest.mark.parametrize("array_type", ["array", "sparse", "pandas"]) def test_safe_assign(array_type): """Check that `_safe_assign` works as expected.""" rng = np.random.RandomState(0) diff --git a/sklearn/utils/tests/test_mocking.py b/sklearn/utils/tests/test_mocking.py index bd143855e6dcd..f464688af0921 100644 --- a/sklearn/utils/tests/test_mocking.py +++ b/sklearn/utils/tests/test_mocking.py @@ -77,7 +77,7 @@ def test_check_X_on_predict_fail(iris, pred_func): getattr(clf, pred_func)(X) -@pytest.mark.parametrize("input_type", ["list", "array", "sparse", "dataframe"]) +@pytest.mark.parametrize("input_type", ["list", "array", "sparse", "pandas"]) def test_checking_classifier(iris, input_type): # Check that the CheckingClassifier outputs what we expect X, y = iris diff --git a/sklearn/utils/tests/test_testing.py b/sklearn/utils/tests/test_testing.py index 7e5349869d401..29bef9465051c 100644 --- a/sklearn/utils/tests/test_testing.py +++ b/sklearn/utils/tests/test_testing.py @@ -895,7 +895,7 @@ def test_create_memmap_backed_data(monkeypatch): # depending of the installed SciPy version *zip(["sparse_csr", "sparse_csr_array"], CSR_CONTAINERS), *zip(["sparse_csc", "sparse_csc_array"], CSC_CONTAINERS), - ("dataframe", lambda: pytest.importorskip("pandas").DataFrame), + ("pandas", lambda: pytest.importorskip("pandas").DataFrame), ("series", lambda: pytest.importorskip("pandas").Series), ("index", lambda: pytest.importorskip("pandas").Index), ("pyarrow", lambda: pytest.importorskip("pyarrow").Table), @@ -923,7 +923,7 @@ def test_convert_container( """Check that we convert the container to the right type of array with the right data type.""" if constructor_name in ( - "dataframe", + "pandas", "index", "polars", "polars_series", @@ -957,9 +957,7 @@ def test_convert_container( def test_convert_container_categories_pandas(): pytest.importorskip("pandas") - df = _convert_container( - [["x"]], "dataframe", ["A"], categorical_feature_names=["A"] - ) + df = _convert_container([["x"]], "pandas", ["A"], categorical_feature_names=["A"]) assert df.dtypes.iloc[0] == "category" diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 2cb449d72ceb8..8e5a6da66b91a 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -10,7 +10,6 @@ import numpy as np import pytest import scipy.sparse as sp -from pytest import importorskip import sklearn from sklearn._config import config_context @@ -43,7 +42,6 @@ _MockEstimatorOnOffPrediction, ) from sklearn.utils._testing import ( - SkipTest, TempMemmap, _array_api_for_tests, _convert_container, @@ -1096,16 +1094,13 @@ def test_check_consistent_length_array_api(array_namespace, device_name, dtype_n def test_check_dataframe_fit_attribute(): - # check pandas dataframe with 'fit' column does not raise error + # check pandas.DataFrame with 'fit' column does not raise error # https://github.com/scikit-learn/scikit-learn/issues/8415 - try: - import pandas as pd - - X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) - X_df = pd.DataFrame(X, columns=["a", "b", "fit"]) - check_consistent_length(X_df) - except ImportError: - raise SkipTest("Pandas not found") + # This essentially tests _num_samples. + pd = pytest.importorskip("pandas") + X = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + X_df = pd.DataFrame(X, columns=["a", "b", "fit"]) + check_consistent_length(X_df) def test_suppress_validation(): @@ -1121,7 +1116,7 @@ def test_suppress_validation(): def test_check_array_series(): # regression test that check_array works on pandas Series - pd = importorskip("pandas") + pd = pytest.importorskip("pandas") res = check_array(pd.Series([1, 2, 3]), ensure_2d=False) assert_array_equal(res, np.array([1, 2, 3])) @@ -1136,13 +1131,13 @@ def test_check_array_series(): ) @pytest.mark.parametrize("bool_dtype", ("bool", "boolean")) def test_check_dataframe_mixed_float_dtypes(dtype, bool_dtype): - # pandas dataframe will coerce a boolean into a object, this is a mismatch + # pandas.DataFrame will coerce a boolean into a object, this is a mismatch # with np.result_type which will return a float # check_array needs to explicitly check for bool dtype in a dataframe for # this situation # https://github.com/scikit-learn/scikit-learn/issues/15787 - pd = importorskip("pandas") + pd = pytest.importorskip("pandas") df = pd.DataFrame( { @@ -1162,8 +1157,8 @@ def test_check_dataframe_mixed_float_dtypes(dtype, bool_dtype): def test_check_dataframe_with_only_bool(): - """Check that dataframe with bool return a boolean arrays.""" - pd = importorskip("pandas") + """Check that pandas.DataFrame with bool return a boolean arrays.""" + pd = pytest.importorskip("pandas") df = pd.DataFrame({"bool": [True, False, True]}) array = check_array(df, dtype=None) @@ -1181,8 +1176,8 @@ def test_check_dataframe_with_only_bool(): def test_check_dataframe_with_only_boolean(): - """Check that dataframe with boolean return a float array with dtype=None""" - pd = importorskip("pandas") + """Check that pandas.DataFrame with boolean return a float array with dtype=None""" + pd = pytest.importorskip("pandas") df = pd.DataFrame({"bool": pd.Series([True, False, True], dtype="boolean")}) array = check_array(df, dtype=None) @@ -1412,7 +1407,7 @@ def test_num_samples_on_1d(constructor_name): @pytest.mark.parametrize( "constructor_name", - ["list", "tuple", "array", "sparse", "dataframe", "pandas", "pyarrow", "polars"], + ["list", "tuple", "array", "sparse", "pandas", "pyarrow", "polars"], ) def test_num_samples_on_dataframe_likes(constructor_name): """Test _num_samples on different dataframe-like input X.""" @@ -1911,8 +1906,7 @@ def test_check_method_params(indices): @pytest.mark.parametrize("sp_format", [True, "csr", "csc", "coo", "bsr"]) def test_check_sparse_pandas_sp_format(sp_format): - # check_array converts pandas dataframe with only sparse arrays into - # sparse matrix + # check_array converts pandas.DataFrame with only sparse arrays into sparse matrix pd = pytest.importorskip("pandas") sp_mat = _sparse_random_matrix(10, 3) @@ -1943,7 +1937,7 @@ def test_check_sparse_pandas_sp_format(sp_format): ], ) def test_check_pandas_sparse_mixed_dtypes(ntype1, ntype2): - """Check that pandas dataframes having sparse extension arrays with mixed dtypes + """Check that pandas.DataFrame having sparse extension arrays with mixed dtypes works.""" pd = pytest.importorskip("pandas") df = pd.DataFrame( @@ -1991,7 +1985,7 @@ def test_check_pandas_sparse_valid(ntype1, ntype2, expected_subtype): @pytest.mark.parametrize( "constructor_name", - ["list", "tuple", "array", "dataframe", "sparse_csr", "sparse_csc"], + ["list", "tuple", "array", "pandas", "sparse_csr", "sparse_csc"], ) def test_num_features(constructor_name): """Check _num_features for array-likes.""" @@ -2046,7 +2040,7 @@ def test_num_features_errors_scalars(X): ids=["list-int", "range", "default", "MultiIndex"], ) def test_get_feature_names_pandas_with_ints_no_warning(names): - """Get feature names with pandas dataframes without warning. + """Get feature names with pandas.DataFrames without warning. Column names with consistent dtypes will not warn, such as int or MultiIndex. """ @@ -2059,19 +2053,9 @@ def test_get_feature_names_pandas_with_ints_no_warning(names): assert names is None -def test_get_feature_names_pandas(): - """Get feature names with pandas dataframes.""" - pd = pytest.importorskip("pandas") - columns = [f"col_{i}" for i in range(3)] - X = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=columns) - feature_names = _get_feature_names(X) - - assert_array_equal(feature_names, columns) - - @pytest.mark.parametrize( "constructor_name, minversion", - [("pyarrow", "13.0.0"), ("dataframe", "1.5.0"), ("polars", "0.18.2")], + [("pyarrow", "13.0.0"), ("pandas", "1.5.0"), ("polars", "0.18.2")], ) def test_get_feature_names_4_dataframes(constructor_name, minversion): """Test _get_features_names on dataframes.""" @@ -2214,7 +2198,7 @@ def test_check_response_method_list_str(): def test_boolean_series_remains_boolean(): """Regression test for gh-25145""" - pd = importorskip("pandas") + pd = pytest.importorskip("pandas") res = check_array(pd.Series([True, False]), ensure_2d=False) expected = np.array([True, False]) @@ -2228,7 +2212,7 @@ def test_pandas_array_returns_ndarray(input_values): Non-regression test for gh-25637. """ - pd = importorskip("pandas") + pd = pytest.importorskip("pandas") input_series = pd.array(input_values, dtype="Int32") result = check_array( input_series, From 090dc149b4298b08ff0c3e95c6144dbdfa9cc7b2 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Sat, 9 May 2026 19:32:05 +0200 Subject: [PATCH 449/462] MNT _convert_container columns_name -> column_names (#33955) --- sklearn/compose/tests/test_column_transformer.py | 4 ++-- sklearn/datasets/_arff_parser.py | 8 ++++---- .../tests/test_monotonic_constraints.py | 12 ++++++------ .../tests/test_boundary_decision_display.py | 2 +- .../_plot/tests/test_plot_partial_dependence.py | 16 ++++++++-------- sklearn/inspection/tests/test_pd_utils.py | 2 +- .../tests/test_function_transformer.py | 4 ++-- sklearn/tests/test_base.py | 4 ++-- sklearn/utils/_testing.py | 16 ++++++++-------- sklearn/utils/tests/test_indexing.py | 14 +++++++------- sklearn/utils/tests/test_validation.py | 4 ++-- 11 files changed, 43 insertions(+), 43 deletions(-) diff --git a/sklearn/compose/tests/test_column_transformer.py b/sklearn/compose/tests/test_column_transformer.py index c9795628ad124..95bcb452a0964 100644 --- a/sklearn/compose/tests/test_column_transformer.py +++ b/sklearn/compose/tests/test_column_transformer.py @@ -202,7 +202,7 @@ def test_column_transformer_dataframe(constructor_name): X_array = np.array([[0, 1, 2], [2, 4, 6]]).T X_df = _convert_container( - X_array, constructor_name, columns_name=["first", "second"] + X_array, constructor_name, column_names=["first", "second"] ) X_res_first = np.array([0, 1, 2]).reshape(-1, 1) @@ -530,7 +530,7 @@ def test_column_transformer_list(): @pytest.mark.parametrize("constructor_name", ["array", "pandas", "polars"]) def test_column_transformer_sparse_stacking(csr_container, constructor_name): X = np.array([[0, 1, 2], [2, 4, 6]]).T - X = _convert_container(X, constructor_name, columns_name=["first", "second"]) + X = _convert_container(X, constructor_name, column_names=["first", "second"]) col_trans = ColumnTransformer( [("trans1", Trans(), [0]), ("trans2", SparseMatrixTrans(csr_container), 1)], diff --git a/sklearn/datasets/_arff_parser.py b/sklearn/datasets/_arff_parser.py index 2df375e410c8b..d884d68f1f26d 100644 --- a/sklearn/datasets/_arff_parser.py +++ b/sklearn/datasets/_arff_parser.py @@ -185,21 +185,21 @@ def _io_to_generator(gzip_file): pd = check_pandas_support("fetch_openml with as_frame=True") columns_info = OrderedDict(arff_container["attributes"]) - columns_names = list(columns_info.keys()) + column_names = list(columns_info.keys()) # calculate chunksize first_row = next(arff_container["data"]) - first_df = pd.DataFrame([first_row], columns=columns_names, copy=False) + first_df = pd.DataFrame([first_row], columns=column_names, copy=False) row_bytes = first_df.memory_usage(deep=True).sum() chunksize = get_chunk_n_rows(row_bytes) # read arff data with chunks - columns_to_keep = [col for col in columns_names if col in columns_to_select] + columns_to_keep = [col for col in column_names if col in columns_to_select] dfs = [first_df[columns_to_keep]] for data in chunk_generator(arff_container["data"], chunksize): dfs.append( - pd.DataFrame(data, columns=columns_names, copy=False)[columns_to_keep] + pd.DataFrame(data, columns=column_names, copy=False)[columns_to_keep] ) # dfs[0] contains only one row, which may not have enough data to infer to # column's dtype. Here we use `dfs[1]` to configure the dtype in dfs[0] diff --git a/sklearn/ensemble/_hist_gradient_boosting/tests/test_monotonic_constraints.py b/sklearn/ensemble/_hist_gradient_boosting/tests/test_monotonic_constraints.py index d9adbc2b71ac5..3b0be9ef8fa0e 100644 --- a/sklearn/ensemble/_hist_gradient_boosting/tests/test_monotonic_constraints.py +++ b/sklearn/ensemble/_hist_gradient_boosting/tests/test_monotonic_constraints.py @@ -225,9 +225,9 @@ def test_predictions(global_random_seed, use_feature_names): f_c = rng.randint(low=0, high=9, size=n_samples) X = np.c_[f_a, f_0, f_b, f_1, f_c] - columns_name = ["f_a", "f_0", "f_b", "f_1", "f_c"] + column_names = ["f_a", "f_0", "f_b", "f_1", "f_c"] constructor_name = "pandas" if use_feature_names else "array" - X = _convert_container(X, constructor_name, columns_name=columns_name) + X = _convert_container(X, constructor_name, column_names=column_names) noise = rng.normal(loc=0.0, scale=0.01, size=n_samples) y = 5 * f_0 + np.sin(10 * np.pi * f_0) - 5 * f_1 - np.cos(10 * np.pi * f_1) + noise @@ -261,24 +261,24 @@ def test_predictions(global_random_seed, use_feature_names): # First non-categorical feature (POS) # assert pred is all increasing when f_0 is all increasing X = np.c_[constant, linspace, constant, constant, constant] - X = _convert_container(X, constructor_name, columns_name=columns_name) + X = _convert_container(X, constructor_name, column_names=column_names) pred = gbdt.predict(X) assert is_increasing(pred) # assert pred actually follows the variations of f_0 X = np.c_[constant, sin, constant, constant, constant] - X = _convert_container(X, constructor_name, columns_name=columns_name) + X = _convert_container(X, constructor_name, column_names=column_names) pred = gbdt.predict(X) assert np.all((np.diff(pred) >= 0) == (np.diff(sin) >= 0)) # Second non-categorical feature (NEG) # assert pred is all decreasing when f_1 is all increasing X = np.c_[constant, constant, constant, linspace, constant] - X = _convert_container(X, constructor_name, columns_name=columns_name) + X = _convert_container(X, constructor_name, column_names=column_names) pred = gbdt.predict(X) assert is_decreasing(pred) # assert pred actually follows the inverse variations of f_1 X = np.c_[constant, constant, constant, sin, constant] - X = _convert_container(X, constructor_name, columns_name=columns_name) + X = _convert_container(X, constructor_name, column_names=column_names) pred = gbdt.predict(X) assert ((np.diff(pred) <= 0) == (np.diff(sin) >= 0)).all() diff --git a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py index 309cc7f41e1ac..84b373dc969de 100644 --- a/sklearn/inspection/_plot/tests/test_boundary_decision_display.py +++ b/sklearn/inspection/_plot/tests/test_boundary_decision_display.py @@ -485,7 +485,7 @@ def test_dataframe_support(pyplot, constructor_name): * https://github.com/scikit-learn/scikit-learn/issues/28717 """ df = _convert_container( - X, constructor_name=constructor_name, columns_name=["col_x", "col_y"] + X, constructor_name=constructor_name, column_names=["col_x", "col_y"] ) estimator = LogisticRegression().fit(df, y) diff --git a/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py b/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py index 021362b6b983a..afdd042c79bde 100644 --- a/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py +++ b/sklearn/inspection/_plot/tests/test_plot_partial_dependence.py @@ -206,7 +206,7 @@ def test_plot_partial_dependence_str_features( bmi = diabetes.data[:, diabetes.feature_names.index("bmi")] X = _convert_container( - diabetes.data, input_type, columns_name=diabetes.feature_names + diabetes.data, input_type, column_names=diabetes.feature_names ) if feature_names_type is None: @@ -808,8 +808,8 @@ def test_plot_partial_dependence_with_categorical( pyplot, categorical_features, array_type ): X = [[1, 1, "A"], [2, 0, "C"], [3, 2, "B"]] - column_name = ["col_A", "col_B", "col_C"] - X = _convert_container(X, array_type, columns_name=column_name) + column_names = ["col_A", "col_B", "col_C"] + X = _convert_container(X, array_type, column_names=column_names) y = np.array([1.2, 0.5, 0.45]).T preprocessor = make_column_transformer((OneHotEncoder(), categorical_features)) @@ -821,7 +821,7 @@ def test_plot_partial_dependence_with_categorical( model, X, features=["col_C"], - feature_names=column_name, + feature_names=column_names, categorical_features=categorical_features, ) @@ -843,7 +843,7 @@ def test_plot_partial_dependence_with_categorical( model, X, features=[("col_A", "col_C")], - feature_names=column_name, + feature_names=column_names, categorical_features=categorical_features, ) @@ -991,8 +991,8 @@ def test_grid_resolution_with_categorical(pyplot, categorical_features, array_ty respect to the number of categories in the categorical features targeted. """ X = [["A", 1, "A"], ["B", 0, "C"], ["C", 2, "B"]] - column_name = ["col_A", "col_B", "col_C"] - X = _convert_container(X, array_type, columns_name=column_name) + column_names = ["col_A", "col_B", "col_C"] + X = _convert_container(X, array_type, column_names=column_names) y = np.array([1.2, 0.5, 0.45]).T preprocessor = make_column_transformer((OneHotEncoder(), categorical_features)) @@ -1007,7 +1007,7 @@ def test_grid_resolution_with_categorical(pyplot, categorical_features, array_ty model, X, features=["col_C"], - feature_names=column_name, + feature_names=column_names, categorical_features=categorical_features, grid_resolution=2, ) diff --git a/sklearn/inspection/tests/test_pd_utils.py b/sklearn/inspection/tests/test_pd_utils.py index d3d4a70a8ee8f..f113933a7e000 100644 --- a/sklearn/inspection/tests/test_pd_utils.py +++ b/sklearn/inspection/tests/test_pd_utils.py @@ -16,7 +16,7 @@ def test_check_feature_names(feature_names, array_type, expected_feature_names): X = np.random.randn(10, 3) column_names = ["a", "b", "c"] - X = _convert_container(X, constructor_name=array_type, columns_name=column_names) + X = _convert_container(X, constructor_name=array_type, column_names=column_names) feature_names_validated = _check_feature_names(X, feature_names) assert feature_names_validated == expected_feature_names diff --git a/sklearn/preprocessing/tests/test_function_transformer.py b/sklearn/preprocessing/tests/test_function_transformer.py index 8364b12eed6ef..d6b42fd9dd6f9 100644 --- a/sklearn/preprocessing/tests/test_function_transformer.py +++ b/sklearn/preprocessing/tests/test_function_transformer.py @@ -192,7 +192,7 @@ def test_function_transformer_raise_error_with_mixed_dtype(X_type): dtype = "object" data = ["one", "two", "three", "one", "one", 5, 6] - data = _convert_container(data, X_type, columns_name=["value"], dtype=dtype) + data = _convert_container(data, X_type, column_names=["value"], dtype=dtype) def func(X): return np.array([mapping[X[i]] for i in range(X.size)], dtype=object) @@ -201,7 +201,7 @@ def inverse_func(X): return _convert_container( [inverse_mapping[x] for x in X], X_type, - columns_name=["value"], + column_names=["value"], dtype=dtype, ) diff --git a/sklearn/tests/test_base.py b/sklearn/tests/test_base.py index b7e308c4f648d..2418270513d0f 100644 --- a/sklearn/tests/test_base.py +++ b/sklearn/tests/test_base.py @@ -924,7 +924,7 @@ def test_feature_names_in_on_dataframes(constructor_name, minversion): data = [[1, 4, 2], [3, 3, 6]] columns = ["col_0", "col_1", "col_2"] df = _convert_container( - data, constructor_name, columns_name=columns, minversion=minversion + data, constructor_name, column_names=columns, minversion=minversion ) class NoOpTransformer(TransformerMixin, BaseEstimator): @@ -946,7 +946,7 @@ def transform(self, X): assert_allclose(df, X_out) bad_names = ["a", "b", "c"] - df_bad = _convert_container(data, constructor_name, columns_name=bad_names) + df_bad = _convert_container(data, constructor_name, column_names=bad_names) with pytest.raises(ValueError, match="The feature names should match"): no_op.transform(df_bad) diff --git a/sklearn/utils/_testing.py b/sklearn/utils/_testing.py index dd9ff797566ba..f0b9a4b7f9acb 100644 --- a/sklearn/utils/_testing.py +++ b/sklearn/utils/_testing.py @@ -967,7 +967,7 @@ def assert_run_python_script_without_output(source_code, pattern=".+", timeout=6 def _convert_container( container, constructor_name, - columns_name=None, + column_names=None, dtype=None, minversion=None, categorical_feature_names=None, @@ -983,8 +983,8 @@ def _convert_container( "sparse_csr_array", "sparse_csc_array", "pyarrow", "polars", \ "polars_series"} The type of the returned container. - columns_name : index or array-like, default=None - For pandas/polars container supporting `columns_names`, it will affect + column_names : index or array-like, default=None + For pandas/polars container supporting `column_names`, it will affect specific names. dtype : dtype, default=None Force the dtype of the container. Does not apply to `"slice"` @@ -1012,7 +1012,7 @@ def _convert_container( return np.asarray(container, dtype=dtype) elif constructor_name == "pandas": pd = pytest.importorskip("pandas", minversion=minversion) - result = pd.DataFrame(container, columns=columns_name, dtype=dtype, copy=False) + result = pd.DataFrame(container, columns=column_names, dtype=dtype, copy=False) if categorical_feature_names is not None: for col_name in categorical_feature_names: result[col_name] = result[col_name].astype("category") @@ -1021,9 +1021,9 @@ def _convert_container( pa = pytest.importorskip("pyarrow", minversion=minversion) array = np.asarray(container) array = array[:, None] if array.ndim == 1 else array - if columns_name is None: - columns_name = [f"col{i}" for i in range(array.shape[1])] - data = {name: array[:, i] for i, name in enumerate(columns_name)} + if column_names is None: + column_names = [f"col{i}" for i in range(array.shape[1])] + data = {name: array[:, i] for i, name in enumerate(column_names)} result = pa.Table.from_pydict(data) if categorical_feature_names is not None: for col_idx, col_name in enumerate(result.column_names): @@ -1034,7 +1034,7 @@ def _convert_container( return result elif constructor_name == "polars": pl = pytest.importorskip("polars", minversion=minversion) - result = pl.DataFrame(container, schema=columns_name, orient="row") + result = pl.DataFrame(container, schema=column_names, orient="row") if categorical_feature_names is not None: for col_name in categorical_feature_names: result = result.with_columns(pl.col(col_name).cast(pl.Categorical)) diff --git a/sklearn/utils/tests/test_indexing.py b/sklearn/utils/tests/test_indexing.py index d462e773df497..7426994d78f58 100644 --- a/sklearn/utils/tests/test_indexing.py +++ b/sklearn/utils/tests/test_indexing.py @@ -214,9 +214,9 @@ def test_safe_indexing_2d_container_axis_1(array_type, indices_type, indices): if indices_type == "slice" and isinstance(indices[1], int): indices_converted[1] += 1 - columns_name = ["col_0", "col_1", "col_2"] + column_names = ["col_0", "col_1", "col_2"] array = _convert_container( - [[1, 2, 3], [4, 5, 6], [7, 8, 9]], array_type, columns_name + [[1, 2, 3], [4, 5, 6], [7, 8, 9]], array_type, column_names ) indices_converted = _convert_container(indices_converted, indices_type) @@ -278,9 +278,9 @@ def test_safe_indexing_1d_container_mask(array_type, indices_type): [(0, [[4, 5, 6], [7, 8, 9]]), (1, [[2, 3], [5, 6], [8, 9]])], ) def test_safe_indexing_2d_mask(array_type, indices_type, axis, expected_subset): - columns_name = ["col_0", "col_1", "col_2"] + column_names = ["col_0", "col_1", "col_2"] array = _convert_container( - [[1, 2, 3], [4, 5, 6], [7, 8, 9]], array_type, columns_name + [[1, 2, 3], [4, 5, 6], [7, 8, 9]], array_type, column_names ) indices = [False, True, True] indices = _convert_container(indices, indices_type) @@ -332,9 +332,9 @@ def test_safe_indexing_1d_scalar(array_type): ) @pytest.mark.parametrize("indices", [2, "col_2"]) def test_safe_indexing_2d_scalar_axis_1(array_type, expected_output_type, indices): - columns_name = ["col_0", "col_1", "col_2"] + column_names = ["col_0", "col_1", "col_2"] array = _convert_container( - [[1, 2, 3], [4, 5, 6], [7, 8, 9]], array_type, columns_name + [[1, 2, 3], [4, 5, 6], [7, 8, 9]], array_type, column_names ) if isinstance(indices, str) and array_type in ("array", "sparse"): @@ -513,7 +513,7 @@ def test_get_column_indices_pandas_nonunique_columns_error(key): def test_get_column_indices_dataframes(constructor_name): """Check _get_column_indices for edge cases with 2d input X.""" df = _convert_container( - [[1, 2, 3], [4, 5, 6]], constructor_name, columns_name=["a", "b", "c"] + [[1, 2, 3], [4, 5, 6]], constructor_name, column_names=["a", "b", "c"] ) key_results = [ diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 8e5a6da66b91a..9c3d8341659f2 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -2062,7 +2062,7 @@ def test_get_feature_names_4_dataframes(constructor_name, minversion): data = [[1, 4, 2], [3, 3, 6]] columns = ["col_0", "col_1", "col_2"] df = _convert_container( - data, constructor_name, columns_name=columns, minversion=minversion + data, constructor_name, column_names=columns, minversion=minversion ) feature_names = _get_feature_names(df) @@ -2491,7 +2491,7 @@ def test_check_categorical_features(categorical_features, on_array, constructor_ X = _convert_container( X, constructor_name, - columns_name=["a", "b", "c", "d"], + column_names=["a", "b", "c", "d"], categorical_feature_names=["b", "c"], ) From 5a73062f9a79256edd1563b9bef9c932d0284d60 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Sun, 10 May 2026 03:16:51 +0200 Subject: [PATCH 450/462] TST remove test_check_feature_names_in_pandas (#33954) --- sklearn/utils/tests/test_validation.py | 38 ++++++++++++-------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 9c3d8341659f2..9553c94f80912 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -2113,36 +2113,34 @@ def get_feature_names_out(self, input_features=None): return _check_feature_names_in(self, input_features) -def test_check_feature_names_in(): +@pytest.mark.parametrize( + ["constructor_name", "feature_names", "msg"], + [ + ("array", ["x0", "x1", "x2"], "input_features should have length equal to"), + ("pandas", ["a", "b", "c"], "input_features is not equal to"), + ("polars", ["a", "b", "c"], "input_features is not equal to"), + ], +) +def test_check_feature_names_in(constructor_name, feature_names, msg): """Check behavior of check_feature_names_in for arrays.""" X = np.array([[0.0, 1.0, 2.0]]) + X = _convert_container(X, constructor_name, column_names=["a", "b", "c"]) est = PassthroughTransformer().fit(X) names = est.get_feature_names_out() - assert_array_equal(names, ["x0", "x1", "x2"]) + assert_array_equal(names, feature_names) - incorrect_len_names = ["x10", "x1"] - with pytest.raises(ValueError, match="input_features should have length equal to"): + incorrect_len_names = feature_names[:2] + with pytest.raises(ValueError, match=msg): est.get_feature_names_out(incorrect_len_names) # remove n_feature_in_ del est.n_features_in_ - with pytest.raises(ValueError, match="Unable to generate feature names"): - est.get_feature_names_out() - - -def test_check_feature_names_in_pandas(): - """Check behavior of check_feature_names_in for pandas dataframes.""" - pd = pytest.importorskip("pandas") - names = ["a", "b", "c"] - df = pd.DataFrame([[0.0, 1.0, 2.0]], columns=names) - est = PassthroughTransformer().fit(df) - - names = est.get_feature_names_out() - assert_array_equal(names, ["a", "b", "c"]) - - with pytest.raises(ValueError, match="input_features is not equal to"): - est.get_feature_names_out(["x1", "x2", "x3"]) + if constructor_name == "array": + with pytest.raises(ValueError, match="Unable to generate feature names"): + est.get_feature_names_out() + else: + assert_array_equal(est.get_feature_names_out(), feature_names) def test_check_response_method_unknown_method(): From 6e9ef2b29549f85a2c2198f56bfde4a08e085dab Mon Sep 17 00:00:00 2001 From: "Samuel O. Ronsin" <samuel.ronsin@dataiku.com> Date: Sun, 10 May 2026 13:40:59 +0200 Subject: [PATCH 451/462] ENH Support for monotonic trees with missing values (#27630) Co-authored-by: Guillaume Lemaitre <g.lemaitre58@gmail.com> --- .../sklearn.tree/27630.enhancement.rst | 9 ++ sklearn/ensemble/_forest.py | 12 +-- sklearn/tree/_classes.py | 18 +--- sklearn/tree/tests/test_monotonic_tree.py | 92 ++++++++++++------- 4 files changed, 76 insertions(+), 55 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.tree/27630.enhancement.rst diff --git a/doc/whats_new/upcoming_changes/sklearn.tree/27630.enhancement.rst b/doc/whats_new/upcoming_changes/sklearn.tree/27630.enhancement.rst new file mode 100644 index 0000000000000..56f5904b8e87c --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.tree/27630.enhancement.rst @@ -0,0 +1,9 @@ +- :class:`tree.DecisionTreeClassifier`, :class:`tree.DecisionTreeRegressor`, + :class:`tree.ExtraTreeClassifier`, :class:`tree.ExtraTreeRegressor`, + :class:`ensemble.RandomForestClassifier`, + :class:`ensemble.RandomForestRegressor`, :class:`ensemble.ExtraTreesClassifier`, + and :class:`ensemble.ExtraTreesRegressor` now support combining + `monotonic_cst` with missing values in dense training data. This builds on + the improvements to missing-value support for dense training data in + :pr:`32119`. + By :user:`Samuel O. Ronsin <samronsin>`. diff --git a/sklearn/ensemble/_forest.py b/sklearn/ensemble/_forest.py index 6df5152e04273..1be148428e0f0 100644 --- a/sklearn/ensemble/_forest.py +++ b/sklearn/ensemble/_forest.py @@ -1387,8 +1387,7 @@ class RandomForestClassifier(ForestClassifier): Monotonicity constraints are not supported for: - multiclass classifications (i.e. when `n_classes > 2`), - - multioutput classifications (i.e. when `n_outputs_ > 1`), - - classifications trained on data with missing values. + - multioutput classifications (i.e. when `n_outputs_ > 1`). The constraints hold over the probability of the positive class. @@ -1779,8 +1778,7 @@ class RandomForestRegressor(ForestRegressor): If monotonic_cst is None, no constraints are applied. Monotonicity constraints are not supported for: - - multioutput regressions (i.e. when `n_outputs_ > 1`), - - regressions trained on data with missing values. + - multioutput regressions (i.e. when `n_outputs_ > 1`). Read more in the :ref:`User Guide <monotonic_cst_gbdt>`. @@ -2174,8 +2172,7 @@ class ExtraTreesClassifier(ForestClassifier): Monotonicity constraints are not supported for: - multiclass classifications (i.e. when `n_classes > 2`), - - multioutput classifications (i.e. when `n_outputs_ > 1`), - - classifications trained on data with missing values. + - multioutput classifications (i.e. when `n_outputs_ > 1`). The constraints hold over the probability of the positive class. @@ -2549,8 +2546,7 @@ class ExtraTreesRegressor(ForestRegressor): If monotonic_cst is None, no constraints are applied. Monotonicity constraints are not supported for: - - multioutput regressions (i.e. when `n_outputs_ > 1`), - - regressions trained on data with missing values. + - multioutput regressions (i.e. when `n_outputs_ > 1`). Read more in the :ref:`User Guide <monotonic_cst_gbdt>`. diff --git a/sklearn/tree/_classes.py b/sklearn/tree/_classes.py index 5b3781f1e856d..588ee45c7b048 100644 --- a/sklearn/tree/_classes.py +++ b/sklearn/tree/_classes.py @@ -184,11 +184,7 @@ def get_n_leaves(self): return self.tree_.n_leaves def _support_missing_values(self, X): - return ( - not issparse(X) - and self.__sklearn_tags__().input_tags.allow_nan - and self.monotonic_cst is None - ) + return not issparse(X) and self.__sklearn_tags__().input_tags.allow_nan def _compute_missing_values_in_feature_mask(self, X, estimator_name=None): """Return boolean mask denoting if there are missing values for each feature. @@ -849,8 +845,7 @@ class DecisionTreeClassifier(ClassifierMixin, BaseDecisionTree): Monotonicity constraints are not supported for: - multiclass classifications (i.e. when `n_classes > 2`), - - multioutput classifications (i.e. when `n_outputs_ > 1`), - - classifications trained on data with missing values. + - multioutput classifications (i.e. when `n_outputs_ > 1`). The constraints hold over the probability of the positive class. @@ -1243,8 +1238,7 @@ class DecisionTreeRegressor(RegressorMixin, BaseDecisionTree): If monotonic_cst is None, no constraints are applied. Monotonicity constraints are not supported for: - - multioutput regressions (i.e. when `n_outputs_ > 1`), - - regressions trained on data with missing values. + - multioutput regressions (i.e. when `n_outputs_ > 1`). Read more in the :ref:`User Guide <monotonic_cst_gbdt>`. @@ -1601,8 +1595,7 @@ class ExtraTreeClassifier(DecisionTreeClassifier): Monotonicity constraints are not supported for: - multiclass classifications (i.e. when `n_classes > 2`), - - multioutput classifications (i.e. when `n_outputs_ > 1`), - - classifications trained on data with missing values. + - multioutput classifications (i.e. when `n_outputs_ > 1`). The constraints hold over the probability of the positive class. @@ -1877,8 +1870,7 @@ class ExtraTreeRegressor(DecisionTreeRegressor): If monotonic_cst is None, no constraints are applied. Monotonicity constraints are not supported for: - - multioutput regressions (i.e. when `n_outputs_ > 1`), - - regressions trained on data with missing values. + - multioutput regressions (i.e. when `n_outputs_ > 1`). Read more in the :ref:`User Guide <monotonic_cst_gbdt>`. diff --git a/sklearn/tree/tests/test_monotonic_tree.py b/sklearn/tree/tests/test_monotonic_tree.py index dfe39720df224..cce5e86d0c8c7 100644 --- a/sklearn/tree/tests/test_monotonic_tree.py +++ b/sklearn/tree/tests/test_monotonic_tree.py @@ -30,13 +30,22 @@ @pytest.mark.parametrize("TreeClassifier", TREE_BASED_CLASSIFIER_CLASSES) +@pytest.mark.parametrize( + "sparse_splitter, with_missing", + [ + (False, False), + (True, False), + (False, True), + ], + ids=["dense-without-missing", "sparse-without-missing", "dense-with-missing"], +) @pytest.mark.parametrize("depth_first_builder", (True, False)) -@pytest.mark.parametrize("sparse_splitter", (True, False)) @pytest.mark.parametrize("csc_container", CSC_CONTAINERS) def test_monotonic_constraints_classifications( TreeClassifier, - depth_first_builder, sparse_splitter, + depth_first_builder, + with_missing, global_random_seed, csc_container, ): @@ -72,9 +81,13 @@ def test_monotonic_constraints_classifications( max_leaf_nodes=n_samples_train, ) if hasattr(est, "random_state"): - est.set_params(**{"random_state": global_random_seed}) + est.set_params(random_state=global_random_seed) if hasattr(est, "n_estimators"): - est.set_params(**{"n_estimators": 5}) + est.set_params(n_estimators=5) + if with_missing: + generator = np.random.default_rng(seed=global_random_seed) + mask = generator.choice(2, size=X_train.shape).astype(bool) + X_train[mask] = np.nan if sparse_splitter: X_train = csc_container(X_train) est.fit(X_train, y_train) @@ -95,14 +108,23 @@ def test_monotonic_constraints_classifications( @pytest.mark.parametrize("TreeRegressor", TREE_BASED_REGRESSOR_CLASSES) +@pytest.mark.parametrize( + "sparse_splitter, with_missing", + [ + (False, False), + (True, False), + (False, True), + ], + ids=["dense-without-missing", "sparse-without-missing", "dense-with-missing"], +) @pytest.mark.parametrize("depth_first_builder", (True, False)) -@pytest.mark.parametrize("sparse_splitter", (True, False)) @pytest.mark.parametrize("criterion", ("absolute_error", "squared_error")) @pytest.mark.parametrize("csc_container", CSC_CONTAINERS) def test_monotonic_constraints_regressions( TreeRegressor, - depth_first_builder, sparse_splitter, + depth_first_builder, + with_missing, criterion, global_random_seed, csc_container, @@ -145,7 +167,11 @@ def test_monotonic_constraints_regressions( if hasattr(est, "random_state"): est.set_params(random_state=global_random_seed) if hasattr(est, "n_estimators"): - est.set_params(**{"n_estimators": 5}) + est.set_params(n_estimators=5) + if with_missing: + generator = np.random.default_rng(seed=global_random_seed) + mask = generator.choice(2, size=X_train.shape).astype(bool) + X_train[mask] = np.nan if sparse_splitter: X_train = csc_container(X_train) est.fit(X_train, y_train) @@ -190,29 +216,6 @@ def test_multiple_output_raises(TreeClassifier): est.fit(X, y) -@pytest.mark.parametrize( - "Tree", - [ - DecisionTreeClassifier, - DecisionTreeRegressor, - ExtraTreeClassifier, - ExtraTreeRegressor, - ], -) -def test_missing_values_raises(Tree): - X, y = make_classification( - n_samples=100, n_features=5, n_classes=2, n_informative=3, random_state=0 - ) - X[0, 0] = np.nan - monotonic_cst = np.zeros(X.shape[1]) - monotonic_cst[0] = 1 - est = Tree(max_depth=None, monotonic_cst=monotonic_cst, random_state=0) - - msg = "Input X contains NaN" - with pytest.raises(ValueError, match=msg): - est.fit(X, y) - - @pytest.mark.parametrize("TreeClassifier", TREE_BASED_CLASSIFIER_CLASSES) def test_bad_monotonic_cst_raises(TreeClassifier): X = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]] @@ -307,11 +310,17 @@ def test_1d_opposite_monotonicity_cst_data(TreeRegressor): @pytest.mark.parametrize("TreeRegressor", TREE_REGRESSOR_CLASSES) +@pytest.mark.parametrize("with_missing", (True, False)) @pytest.mark.parametrize("monotonic_sign", (-1, 1)) @pytest.mark.parametrize("depth_first_builder", (True, False)) @pytest.mark.parametrize("criterion", ("absolute_error", "squared_error")) def test_1d_tree_nodes_values( - TreeRegressor, monotonic_sign, depth_first_builder, criterion, global_random_seed + TreeRegressor, + with_missing, + monotonic_sign, + depth_first_builder, + criterion, + global_random_seed, ): # Adaptation from test_nodes_values in test_monotonic_constraints.py # in sklearn.ensemble._hist_gradient_boosting @@ -351,10 +360,15 @@ def test_1d_tree_nodes_values( criterion=criterion, random_state=global_random_seed, ) + if with_missing: + generator = np.random.default_rng(seed=global_random_seed) + mask = generator.choice(2, size=X.shape, p=[0.8, 0.2]).astype(bool) + X[mask] = np.nan clf.fit(X, y) assert_1d_reg_tree_children_monotonic_bounded(clf.tree_, monotonic_sign) - assert_1d_reg_monotonic(clf, monotonic_sign, np.min(X), np.max(X), 100) + min_x, max_x = np.nanmin(X), np.nanmax(X) + assert_1d_reg_monotonic(clf, monotonic_sign, min_x, max_x, 100) def assert_nd_reg_tree_children_monotonic_bounded(tree_, monotonic_cst): @@ -379,7 +393,7 @@ def assert_nd_reg_tree_children_monotonic_bounded(tree_, monotonic_cst): # Split node: check and update bounds for the children. i_left = tree_.children_left[i] i_right = tree_.children_right[i] - # unpack value from nx1x1 array + # unpack value from nx1x1 array (middle_value after clipping) middle_value = (tree_.value[i_left][0][0] + tree_.value[i_right][0][0]) / 2 if monotonic_cst[feature] == 0: @@ -460,11 +474,17 @@ def test_assert_nd_reg_tree_children_monotonic_bounded(): @pytest.mark.parametrize("TreeRegressor", TREE_REGRESSOR_CLASSES) +@pytest.mark.parametrize("with_missing", (True, False)) @pytest.mark.parametrize("monotonic_sign", (-1, 1)) @pytest.mark.parametrize("depth_first_builder", (True, False)) @pytest.mark.parametrize("criterion", ("absolute_error", "squared_error")) def test_nd_tree_nodes_values( - TreeRegressor, monotonic_sign, depth_first_builder, criterion, global_random_seed + TreeRegressor, + with_missing, + monotonic_sign, + depth_first_builder, + criterion, + global_random_seed, ): # Build tree with several features, and make sure the nodes # values respect the monotonicity constraints. @@ -508,5 +528,9 @@ def test_nd_tree_nodes_values( criterion=criterion, random_state=global_random_seed, ) + if with_missing: + generator = np.random.default_rng(seed=global_random_seed) + mask = generator.choice(2, size=X.shape, p=[0.8, 0.2]).astype(bool) + X[mask] = np.nan clf.fit(X, y) assert_nd_reg_tree_children_monotonic_bounded(clf.tree_, monotonic_cst) From d79611d87fb42316b1e6e9731f2c7c6972ef2163 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 11 May 2026 04:11:29 -0400 Subject: [PATCH 452/462] :lock: :robot: CI Update lock files for array-api CI build(s) :lock: :robot: (#33977) Co-authored-by: Lock file bot <noreply@github.com> --- ...a_forge_cuda_array-api_linux-64_conda.lock | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock index 2ee3c9a59fbeb..807a24ee28798 100644 --- a/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_cuda_array-api_linux-64_conda.lock @@ -9,7 +9,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77 https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.26.0-ha770c72_0.conda#cb93c6e226a7bed5557601846555153d https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 -https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_11.conda#4a1793b78e4309bbdb99bd033226f0d2 +https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_12.conda#95321ce2d03500a23a6e80034cbd4804 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 @@ -24,8 +24,8 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/noarch/libnvptxcompiler-dev_linux-64-12.9.86-ha770c72_2.conda#a66a909acf08924aced622903832a937 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.4-h4922eb0_0.conda#fa2c5c7f8d5319ab9c9fcbbd04022abf -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_11.conda#c0004c583be9ac82ad2115bc08f3d77d +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.5-h4922eb0_1.conda#f66101d2eb5de2924c10a63bbfa2926e +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_12.conda#c6e7262ad8afd5fe1d64554cfa456060 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/cuda-cudart-dev_linux-64-12.9.79-h3f2d84a_0.conda#86e40eb67d83f1a58bdafdd44e5a77c6 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -35,7 +35,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.2-h25fd6f3_2.conda#c2a01a08fc991620a74b32420e97868a https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda#57736f29cc2b0ec0b6c2952d3f101b6a https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 @@ -49,8 +49,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda#331ee9b72b9dff570d56b1302c5ab37d +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda#85072b0ad177c966294f129b7c04a2d5 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb @@ -60,7 +60,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda#5794b3bdc38177caf969dabd3af08549 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 @@ -101,11 +101,11 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda#42bf7eca1a951735fa06c0e3c0d5c8e6 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libnvjitlink-12.9.86-hecca717_2.conda#3461b0f2d5cbb7973d361f9e85241d98 https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_19.conda#e5ce228e579726c07255dbf90dc62101 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-260.1-h6569c3e_0.conda#5020e400d8f01d9e6a39d559e65060f1 https://conda.anaconda.org/conda-forge/linux-64/libudev1-260.1-h6569c3e_0.conda#0bcc534980c246af677ed6f118d8c2ef https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -146,14 +146,14 @@ https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda#c https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.conda#e79d2c2f24b027aa8d5ab1b1ba3061e7 https://conda.anaconda.org/conda-forge/linux-64/python-3.14.4-habeac84_100_cp314.conda#a443f87920815d41bfe611296e507995 https://conda.anaconda.org/conda-forge/linux-64/qhull-2020.2-h434a139_5.conda#353823361b1d27eb3960efb076dfcaf6 -https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 +https://conda.anaconda.org/conda-forge/linux-64/rdma-core-62.0-h192683f_0.conda#46a9d3342a5945cf6067f9277989900c https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.6.0-h9b893ba_1.conda#cd4946050ecfcb3c6fd09106ae6a261e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.12-h4bacb7b_1.conda#7bc920933e5fb225aba86a788164a8f1 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.7.0-h9b893ba_0.conda#60076118b1579967748f0c9a2912de7c +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.13-h4bacb7b_0.conda#77f70a9ab785a146dbf66fba00131403 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 @@ -171,7 +171,7 @@ https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.4.0-pyhd8ed1ab_0.conda#2c11aa96ea85ced419de710c1c3a78ff https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19.1-h0c24ade_0.conda#f92f984b558e6e6204014b16d212b271 https://conda.anaconda.org/conda-forge/linux-64/libcublas-dev-12.9.1.4-h676940d_1.conda#f90f4ff087ac29005c6989ea0fb2735a https://conda.anaconda.org/conda-forge/linux-64/libcudnn-9.10.2.21-hf7e9902_0.conda#a178a1f3642521f104ecceeefa138d01 https://conda.anaconda.org/conda-forge/linux-64/libcudss-0.7.1.4-h58dd1b1_1.conda#c5b8ea827c65e5811d61aa49cd0bae9a @@ -188,7 +188,7 @@ https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ce https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.0-pyhcf101f3_0.conda#d2ec42db1d2fcd69003c8b069fb4301c https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/noarch/nvidia-ml-py-13.595.45-pyhd8ed1ab_1.conda#dc8587ae654e96031728802016e8258c https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -214,11 +214,11 @@ https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h2d2dd48_2.conda#675ea6d90900350b1dcfa8231a5ea2dd -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-he9ea9c5_1.conda#8e77514673f5773b40ff8953583938b6 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-ha62d5e7_3.conda#55eaf7066da1299d217ab32baedc7fa8 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-hc1936db_2.conda#9120bc47b6f837f3cea90928c3e9a8fa https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.14.0-py314h67df5f8_0.conda#7f8715a1928f6f126323320a4c5ada3a https://conda.anaconda.org/conda-forge/linux-64/cuda-bindings-12.9.6-py314h7ea930b_0.conda#a8841fd311da95db72916f58eff3f5a6 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 @@ -229,7 +229,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928 https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.5-hf7376ad_1.conda#6adc0202fa7fcf0a5fce8c31ef2ed866 https://conda.anaconda.org/rapidsai/linux-64/libucxx-0.49.00-cuda12_260408_8d47a9ff.conda#b8ddfc6e13aa7b755392fe8cb6f9250a https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 @@ -251,67 +251,67 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.cond https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h6d69fc9_5.conda#4c5c16bf1133dcfe100f33dd4470998e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.12.2-he6ee468_1.conda#50ae8372984b8b98e056ac8f6b70ab29 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 https://conda.anaconda.org/conda-forge/noarch/cuda-python-12.9.6-pyh698daf1_0.conda#8d3dbe5292af711edd6df92c68e55a89 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.5-default_h746c552_0.conda#c3df118cdc65584a78028bf225111b1b https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d +https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.1-py314h9891dd4_0.conda#44ffc8b345a7844a847d4fdf469d64ea https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/tbb-2023.0.0-h51de99f_1.conda#6383c1684badc0d94408b12850cf07f1 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h4c8aef7_3.conda#798a499cf76e530a992365d557ba5827 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.38.3-h745e52d_1.conda#6a65b3595a8933808c03ff065dfb7702 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_12.conda#1a4a54fad5e36b8282ec6208dcb9bfb7 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-h41c0014_4.conda#169a79ea1127077d8dc36dc963ff55ac https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_12.conda#db484eb7d5c23ca2a3129ddf5943de76 https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-24.0.0-ha7f89c6_0_cpu.conda#8aeb79715524b48267068fb0fd185956 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-24.0.0-h72d56d0_1_cuda.conda#55ecfbd2e0853dd720e13ca68bda5617 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-24.0.0-h53684a4_0_cpu.conda#73e0aeaa603ff40128e75435a3c5ac77 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-24.0.0-h53684a4_1_cuda.conda#1f3d6ccda609a3065054a983b09725af https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 https://conda.anaconda.org/conda-forge/linux-64/libmagma-2.9.0-ha7672b3_6.conda#7c6ca8cec0c6a213db89a1d80f53d197 -https://conda.anaconda.org/conda-forge/linux-64/libparquet-24.0.0-h7376487_0_cpu.conda#c828cca50cd3a7c53d12ce8f0872c6ec +https://conda.anaconda.org/conda-forge/linux-64/libparquet-24.0.0-h7376487_1_cuda.conda#5351c337776036ecb8e4bea758399bed https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 https://conda.anaconda.org/conda-forge/linux-64/cuda-core-0.7.0-cuda12_py314h6985919_0.conda#ec0ac10cf8ea10e2ca9437a1feebbfc6 https://conda.anaconda.org/conda-forge/linux-64/cupy-core-14.0.1-py314hf9e62a7_0.conda#4fe7bd0212d2f7788765875755f67684 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-24.0.0-h635bf11_0_cpu.conda#178d7e3f5c392e606ccd0aaff4331019 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-24.0.0-h635bf11_1_cuda.conda#42c3d4b56b5dd405f6389c7bc8200a9c https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cuda129_mkl_hd6d2a1f_303.conda#5b8a8672aca66f3871aab4d0d1a8f796 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py314hb4ffadd_0.conda#41ee6fe2a848876bc9f524c5a500b85b -https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-24.0.0-py314h969be7f_0_cpu.conda#b066370d80ec7fca3c1d4028dc09164f +https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-24.0.0-py314h57703d4_0_cuda.conda#66a1f66c0554402ab43f6ab69617d70b https://conda.anaconda.org/rapidsai/linux-64/rmm-26.04.00-cuda12_cp311_abi3_260408_48b36cc6.conda#347f02e4a94831af80076fd6157776ac https://conda.anaconda.org/conda-forge/linux-64/scipy-1.16.3-py314hf07bd8e_2.conda#ee95e8bb52e35c3267a53d3ee1347cc4 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 https://conda.anaconda.org/conda-forge/linux-64/cupy-14.0.1-py314h3d8d815_0.conda#5045e5051a4d781d41d63e4acc264944 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-24.0.0-h635bf11_0_cpu.conda#dc226b80ae51753ce2bd8193dcc42a88 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-24.0.0-h635bf11_1_cuda.conda#64b5b9d375485dc9b13f7506ead51ed3 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.9-py314h1194b4b_0.conda#11a821746ad11e642fcc615c3d66aa44 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cuda129_mkl_py314_h624cae8_303.conda#fa04d9a4d7fd7a9bd49deabc4b1a8b4f https://conda.anaconda.org/rapidsai/linux-64/ucxx-0.49.00-cuda12_cp311_abi3_260408_8d47a9ff.conda#4e44176d2cfc7f9941dc3089df22c9dc -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-24.0.0-hb4dd7c2_0_cpu.conda#cb5a9557a2ffa1b18b4e05621354c6bd +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-24.0.0-hb4dd7c2_1_cuda.conda#f36b071f6793519c17f07a3764e18ce9 https://conda.anaconda.org/rapidsai/linux-64/libraft-headers-26.04.00-cuda12_260408_b01e3028.conda#413e57142e096269834e8a95b4905d09 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.9-py314hdafbbf9_0.conda#2046de06d7f4149a29c5d0e2cc26d6dd https://conda.anaconda.org/conda-forge/linux-64/pytorch-gpu-2.10.0-cuda129_mkl_h0d04637_303.conda#1050dc8cf80cd0a9e63f361c12ee0e82 From 083d69f95040310533ebd739f1bdc1200aad3bc1 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 11 May 2026 04:11:52 -0400 Subject: [PATCH 453/462] :lock: :robot: CI Update lock files for free-threaded CI build(s) :lock: :robot: (#33976) Co-authored-by: Lock file bot <noreply@github.com> --- .../pylatest_free_threaded_linux-64_conda.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock index 2138f1e889158..95bc2fb843154 100644 --- a/build_tools/github/pylatest_free_threaded_linux-64_conda.lock +++ b/build_tools/github/pylatest_free_threaded_linux-64_conda.lock @@ -5,26 +5,26 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314t.conda#3251796e09870c978e0f69fa05e38fb6 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda#faac990cb7aedc7f3a2224f2c9b0c26c https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda#57736f29cc2b0ec0b6c2952d3f101b6a https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda#85072b0ad177c966294f129b7c04a2d5 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda#5794b3bdc38177caf969dabd3af08549 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda#cffd3bdd58090148f4cfcd831f4b26ab https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda#42bf7eca1a951735fa06c0e3c0d5c8e6 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda#b518e9e92493721281a60fa975bddc65 https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda#d7d95fc8287ea7bf33e0e7116d2b95ec @@ -37,7 +37,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cython-3.2.4-py314h3f98dc2_0.con https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.0-pyhcf101f3_0.conda#d2ec42db1d2fcd69003c8b069fb4301c https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e From 3d30456cebcb9ec5b43da12c70fd2be21d693efc Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 11 May 2026 04:12:22 -0400 Subject: [PATCH 454/462] :lock: :robot: CI Update lock files for scipy-dev CI build(s) :lock: :robot: (#33975) Co-authored-by: Lock file bot <noreply@github.com> --- .../pylatest_pip_scipy_dev_linux-64_conda.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock index de383cf2da563..04a0723668f53 100644 --- a/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_scipy_dev_linux-64_conda.lock @@ -5,19 +5,19 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda#faac990cb7aedc7f3a2224f2c9b0c26c https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda#57736f29cc2b0ec0b6c2952d3f101b6a https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda#5794b3bdc38177caf969dabd3af08549 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 @@ -32,10 +32,10 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl#sha256=3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a # pip charset-normalizer @ https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e -# pip coverage @ https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510 +# pip coverage @ https://files.pythonhosted.org/packages/d7/51/ec641c26e6dca1b25a7d2035ba6ecb7c884ef1a100a9e42fbe4ce4405139/coverage-7.14.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=5ebb8f4614a3787d567e610bbfdf96a4798dd69a1afb1bd8ad228d4111fe6ff3 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec -# pip idna @ https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl#sha256=892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 +# pip idna @ https://files.pythonhosted.org/packages/6c/3c/3f62dee257eb3d6b2c1ef2a09d36d9793c7111156a73b5654d2c2305e5ce/idna-3.14-py3-none-any.whl#sha256=e677eaf072e290f7b725f9acf0b3a2bd55f9fd6f7c70abe5f0e34823d0accf69 # pip imagesize @ https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl#sha256=5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip markupsafe @ https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 @@ -55,7 +55,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e # pip sphinxcontrib-qthelp @ https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl#sha256=b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb # pip sphinxcontrib-serializinghtml @ https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl#sha256=6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb -# pip urllib3 @ https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl#sha256=bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +# pip urllib3 @ https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl#sha256=9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 # pip pyproject-metadata @ https://files.pythonhosted.org/packages/1d/0b/da4851b1e2d9c40c9bd74c0abd94510a7d797da9ccde0a90e8953751ed4a/pyproject_metadata-0.11.0-py3-none-any.whl#sha256=85bbecca8694e2c00f63b492c96921d6c228454057c88e7c352b2077fcaa4096 # pip pytest @ https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl#sha256=2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9 From f6cb214601f456665493120b10f6740a72b69e05 Mon Sep 17 00:00:00 2001 From: scikit-learn-bot <tjpfdev@gmail.com> Date: Mon, 11 May 2026 04:51:13 -0400 Subject: [PATCH 455/462] :lock: :robot: CI Update lock files for main CI build(s) :lock: :robot: (#33978) Co-authored-by: Lock file bot <noreply@github.com> --- build_tools/circle/doc_linux-64_conda.lock | 68 +++++++++---------- .../doc_min_dependencies_linux-64_conda.lock | 60 ++++++++-------- build_tools/github/debian_32bit_lock.txt | 4 +- ...latest_conda_forge_mkl_linux-64_conda.lock | 62 ++++++++--------- ...onda_forge_mkl_no_openmp_osx-64_conda.lock | 16 ++--- .../pylatest_conda_forge_osx-arm64_conda.lock | 18 ++--- ...st_pip_openblas_pandas_linux-64_conda.lock | 14 ++-- ...n_conda_forge_arm_linux-aarch64_conda.lock | 24 +++---- ...nblas_min_dependencies_linux-64_conda.lock | 28 ++++---- ...e_openblas_ubuntu_2204_linux-64_conda.lock | 18 ++--- ...min_conda_forge_openblas_win-64_conda.lock | 12 ++-- 11 files changed, 162 insertions(+), 162 deletions(-) diff --git a/build_tools/circle/doc_linux-64_conda.lock b/build_tools/circle/doc_linux-64_conda.lock index cd2a8e36e4f1b..54940e3c25ddb 100644 --- a/build_tools/circle/doc_linux-64_conda.lock +++ b/build_tools/circle/doc_linux-64_conda.lock @@ -7,18 +7,18 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 -https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_11.conda#4a1793b78e4309bbdb99bd033226f0d2 +https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_12.conda#95321ce2d03500a23a6e80034cbd4804 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda#06901733131833f5edd68cf3d9679798 +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_119.conda#7d517e32d656a8880d98c0e4fc8ddc2c https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda#faac990cb7aedc7f3a2224f2c9b0c26c +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_119.conda#d1a866495b9654ccfef5392b8541dc58 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.4-h4922eb0_0.conda#fa2c5c7f8d5319ab9c9fcbbd04022abf -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_11.conda#c0004c583be9ac82ad2115bc08f3d77d +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.5-h4922eb0_1.conda#f66101d2eb5de2924c10a63bbfa2926e +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_12.conda#c6e7262ad8afd5fe1d64554cfa456060 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -26,7 +26,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c1 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda#57736f29cc2b0ec0b6c2952d3f101b6a https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_102.conda#8165352fdce2d2025bf884dc0ee85700 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 @@ -35,8 +35,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda#331ee9b72b9dff570d56b1302c5ab37d +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda#85072b0ad177c966294f129b7c04a2d5 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb @@ -46,7 +46,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.con https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.21-h280c20c_3.conda#7af961ef4aa2c1136e11dd43ded245ab https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda#5794b3bdc38177caf969dabd3af08549 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 @@ -75,10 +75,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.2.0-hb03c661_1.co https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda#9314bc5a1fe7d1044dc9dfd3ef400535 https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda#c277e0a4d549b03ac1e9d6cbbe3d017b https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda#42bf7eca1a951735fa06c0e3c0d5c8e6 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.4.0-h10be129_0.conda#3a9428b74c403c71048104d38437b48c -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_19.conda#007796e5a595bbc7df4a5e1580d72e1a +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_19.conda#e5ce228e579726c07255dbf90dc62101 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -97,7 +97,7 @@ https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-3.0.2-hc31b594_0.conda#53b70d577abebd6fbfe21849e27c309b -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h235f0fe_19.conda#99936dc616b7ce97b0468759b8a7c64e https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h0d30a3d_1.conda#6016ea5ee9e986bc683879408cc87529 @@ -123,7 +123,7 @@ https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.con https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/click-8.3.3-pyhc90fa1f_0.conda#2266262ce8a425ecb6523d765f79b303 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_19.conda#fd57230e9a97b97bf20dd63aeae6fe61 https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.4-py314hd8ed1ab_100.conda#f111d4cfaf1fe9496f386bc98ae94452 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c @@ -136,8 +136,8 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h50e9bb6_24.conda#91b0f19212d79a1a4dca034aac729e4f -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_19.conda#d5f5c8cc2a64220838a096041b7a7fb4 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_19.conda#8b867d053ed89743eeac52c3a50f112d https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac @@ -147,7 +147,7 @@ https://conda.anaconda.org/conda-forge/noarch/json5-0.14.0-pyhd8ed1ab_0.conda#12 https://conda.anaconda.org/conda-forge/noarch/jsonpointer-3.1.1-pyhcf101f3_0.conda#89bf346df77603055d3c8fe5811691e6 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 https://conda.anaconda.org/conda-forge/noarch/lark-1.3.1-pyhd8ed1ab_0.conda#9b965c999135d43a3d0f7bd7d024e26a -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19.1-h0c24ade_0.conda#f92f984b558e6e6204014b16d212b271 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c @@ -156,10 +156,10 @@ https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py314h67df5f8_1 https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_1.conda#592132998493b3ff25fd7479396e8351 https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.0-pyhcf101f3_0.conda#d2ec42db1d2fcd69003c8b069fb4301c https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/openjph-0.27.0-h8d634f6_0.conda#8397bb8cf4b370f5df7d7ee3d80ea977 +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.27.2-h8d634f6_0.conda#ac7564cac998d4df2f030de2e532291d https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2#457c2c8c08e54905d6954e79cb5b5db9 https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f @@ -188,7 +188,7 @@ https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.6.0-pyhecae5ae_0.conda#9d64911b31d57ca443e9f1e36b04385f https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b5325cf06a000c5b14970462ff5e4d58 https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.5-py314h5bd0f2a_0.conda#dc1ff1e915ab35a06b6fa61efae73ab5 -https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_1.conda#019a7385be9af33791c989871317e1ed +https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.0-pyhcf101f3_0.conda#4bada6a6d908a27262af8ebddf4f7492 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_1.conda#f6d7aa696c67756a650e91e15e88223c https://conda.anaconda.org/conda-forge/linux-64/unicodedata2-17.0.1-py314h5bd0f2a_0.conda#494fdf358c152f9fdd0673c128c2f3dd @@ -210,7 +210,7 @@ https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py314h4a8dc5f_1.conda#cf45f4278afd6f4e6d03eda0f435d527 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_19.conda#2dd149aa693db92758af3e685ef30439 https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h6b77fdb_24.conda#491f76c26b2d032b21ba0b79cc324c4f https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h8a413ad_24.conda#ea3921760f33250a1c12926fce1660eb https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 @@ -224,10 +224,10 @@ https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.5-hf7376ad_1.conda#6adc0202fa7fcf0a5fce8c31ef2ed866 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 -https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.0.0-pyhd8ed1ab_0.conda#5b5203189eb668f042ac2b0826244964 +https://conda.anaconda.org/conda-forge/noarch/markdown-it-py-4.2.0-pyhd8ed1ab_0.conda#6d03368f2b2b0a5fb6839df53b2eb5e0 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/noarch/mistune-3.2.1-pyhcf101f3_0.conda#b97e84d1553b4a1c765b87fff83453ad https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 @@ -259,22 +259,22 @@ https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0 https://conda.anaconda.org/conda-forge/noarch/bleach-with-css-6.3.0-hbca2aae_1.conda#f11a319b9700b203aa14c295858782b6 https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_1.conda#d3549fd50d450b6d9e7dddff25dd2110 -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-he448592_7.conda#94394acdc56dcb4d55dddf0393134966 +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-he448592_7.conda#91dc0abe7274ac5019deaa6100643265 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.1.0-pyhd8ed1ab_0.conda#e3bffa82b874f8b9a2631bddb3869529 https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2025.9.1-pyhcf101f3_0.conda#439cd0f567d697b20a8f45cb70a1005a https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.4-pyhcf101f3_0.conda#7b8bace4943e0dc345fc45938826f2b8 -https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.5-pyhcf101f3_0.conda#7b2c96c18996e40ff846045e89b7d01e -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 +https://conda.anaconda.org/conda-forge/noarch/jupyterlite-core-0.7.6-pyhcf101f3_0.conda#9885a00885bacfbf539e079a8aef0148 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.5-default_h746c552_0.conda#c3df118cdc65584a78028bf225111b1b https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 -https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.5.0-pyhd8ed1ab_0.conda#1997a083ef0b4c9331f9191564be275e +https://conda.anaconda.org/conda-forge/noarch/mdit-py-plugins-0.6.0-pyhd8ed1ab_0.conda#9a704e945e87078f464726c69071677a https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/tbb-2023.0.0-h51de99f_1.conda#6383c1684badc0d94408b12850cf07f1 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda#cbb88288f74dbe6ada1c6c7d0a97223e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-25.1.0-pyhd8ed1ab_0.conda#8ac12aff0860280ee0cff7fa2cf63f3b https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 @@ -283,7 +283,7 @@ https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_1.c https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.26.0-pyhcf101f3_0.conda#ada41c863af263cc4c5fcbaff7c3e4dc https://conda.anaconda.org/conda-forge/noarch/jupyterlite-pyodide-kernel-0.7.2-pyhcf101f3_0.conda#ffe2104d16bc6896d9a09c3c95f2b9b6 https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_12.conda#1a4a54fad5e36b8282ec6208dcb9bfb7 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_2.conda#082985717303dab433c976986c674b35 @@ -293,13 +293,13 @@ https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.cond https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.26.0-hcf101f3_0.conda#8368d58342d0825f0843dc6acdd0c483 https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.8.0-pyhcf101f3_0.conda#8a3d6d0523f66cf004e563a50d9392b3 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_12.conda#db484eb7d5c23ca2a3129ddf5943de76 https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_1.conda#bbe1963f1e47f594070ffe87cdf612ea https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/noarch/pooch-1.9.0-pyhd8ed1ab_0.conda#dd4b6337bf8886855db6905b336db3c8 https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.12.1-pyhcf101f3_0.conda#bf42ee94c750c0b2e7e998b79ac299ea -https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.1-pyhbbac1ac_0.conda#d8f030e3730713c93a358fdb46f08281 +https://conda.anaconda.org/conda-forge/noarch/jupytext-1.19.2-pyh0398c0e_0.conda#866d6b93cd3efa827ac3223c2c3cccbc https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.4-pyhd8ed1ab_0.conda#00f5b8dafa842e0c27c1cd7296aa4875 @@ -311,7 +311,7 @@ https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 https://conda.anaconda.org/conda-forge/linux-64/imagecodecs-2026.3.6-py314h2730e07_3.conda#8664abf57c0ab721522b72879a101d6c https://conda.anaconda.org/conda-forge/noarch/imageio-2.37.0-pyhfb79c49_0.conda#b5577bc2212219566578fd5af9993af6 -https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.1-pyhcf101f3_0.conda#0bfbcb99dbf7d3b833cbca0ea5273fc2 +https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.18.2-pyhcf101f3_0.conda#5ee7945accf0f215ddd6055d25d7cd83 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py314hb4ffadd_0.conda#41ee6fe2a848876bc9f524c5a500b85b https://conda.anaconda.org/conda-forge/noarch/patsy-1.0.2-pyhcf101f3_0.conda#8678577a52161cc4e1c93fcc18e8a646 https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 diff --git a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock index e861b15c62c8c..44b2f4756d5fe 100644 --- a/build_tools/circle/doc_min_dependencies_linux-64_conda.lock +++ b/build_tools/circle/doc_min_dependencies_linux-64_conda.lock @@ -7,18 +7,18 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda#86d9cba083cd041bfbf242a01a7a1999 -https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_11.conda#4a1793b78e4309bbdb99bd033226f0d2 +https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_12.conda#95321ce2d03500a23a6e80034cbd4804 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 -https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda#06901733131833f5edd68cf3d9679798 +https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_119.conda#7d517e32d656a8880d98c0e4fc8ddc2c https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 -https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda#865a399bce236119301ebd1532fced8d +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda#faac990cb7aedc7f3a2224f2c9b0c26c +https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_119.conda#d1a866495b9654ccfef5392b8541dc58 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.4-h4922eb0_0.conda#fa2c5c7f8d5319ab9c9fcbbd04022abf -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_11.conda#c0004c583be9ac82ad2115bc08f3d77d +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.5-h4922eb0_1.conda#f66101d2eb5de2924c10a63bbfa2926e +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_12.conda#c6e7262ad8afd5fe1d64554cfa456060 https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda#13dc3adbc692664cd3beabd216434749 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab @@ -26,7 +26,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c1 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda#57736f29cc2b0ec0b6c2952d3f101b6a https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_102.conda#8165352fdce2d2025bf884dc0ee85700 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 @@ -37,8 +37,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda#331ee9b72b9dff570d56b1302c5ab37d +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda#85072b0ad177c966294f129b7c04a2d5 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb @@ -49,7 +49,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda#5794b3bdc38177caf969dabd3af08549 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 @@ -79,10 +79,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda#42bf7eca1a951735fa06c0e3c0d5c8e6 https://conda.anaconda.org/conda-forge/linux-64/libhwy-1.4.0-h10be129_0.conda#3a9428b74c403c71048104d38437b48c -https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda#ad3a0e2dc4cce549b2860e2ef0e6d75b -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de +https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_19.conda#007796e5a595bbc7df4a5e1580d72e1a +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_19.conda#e5ce228e579726c07255dbf90dc62101 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda#8ee3cb7f64be0e8c4787f3a4dbe024e6 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 @@ -104,10 +104,10 @@ https://conda.anaconda.org/conda-forge/linux-64/blosc-1.21.6-he440d0b_1.conda#2c https://conda.anaconda.org/conda-forge/linux-64/brotli-bin-1.2.0-hb03c661_1.conda#af39b9a8711d4a8d437b52c1d78eb6a1 https://conda.anaconda.org/conda-forge/linux-64/brunsli-0.1-hd1e3526_2.conda#5948f4fead433c6e5c46444dbfb01162 https://conda.anaconda.org/conda-forge/linux-64/c-blosc2-3.0.2-hc31b594_0.conda#53b70d577abebd6fbfe21849e27c309b -https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda#30bb690150536f622873758b0e8d6712 +https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-h235f0fe_19.conda#99936dc616b7ce97b0468759b8a7c64e https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb53fb07ce46a575c5d004bbc96032c2 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_19.conda#35d07243abf828674d273aecd1dd537e https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h0d30a3d_1.conda#6016ea5ee9e986bc683879408cc87529 https://conda.anaconda.org/conda-forge/linux-64/libjxl-0.11.2-h174a0a3_1.conda#850f48943d6b4589800a303f0de6a816 https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 @@ -130,7 +130,7 @@ https://conda.anaconda.org/conda-forge/noarch/certifi-2026.4.22-pyhd8ed1ab_0.con https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.4.7-pyhd8ed1ab_0.conda#a9167b9571f3baa9d448faa2139d1089 https://conda.anaconda.org/conda-forge/noarch/click-8.3.3-pyhc90fa1f_0.conda#2266262ce8a425ecb6523d765f79b303 https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_1.conda#962b9857ee8e7018c22f2776ffa0b2d7 -https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda#0e3e144115c43c9150d18fa20db5f31c +https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_19.conda#fd57230e9a97b97bf20dd63aeae6fe61 https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhcf101f3_2.conda#4c2a8fef270f6c69591889b93f9f55c1 https://conda.anaconda.org/conda-forge/linux-64/cyrus-sasl-2.1.28-hac629b4_1.conda#af491aae930edc096b58466c51c4126c https://conda.anaconda.org/conda-forge/linux-64/cython-3.1.2-py311ha3e34f5_2.conda#f56da6e1e1f310f27cca558e58882f40 @@ -140,16 +140,16 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda#867127763fbe935bab59815b6e0b7b5c https://conda.anaconda.org/conda-forge/linux-64/freetype-2.14.3-ha770c72_0.conda#8462b5322567212beeb025f3519fb3e2 https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h50e9bb6_24.conda#91b0f19212d79a1a4dca034aac729e4f -https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_18.conda#91531d5176126c652e8b8dfcfa263dcd +https://conda.anaconda.org/conda-forge/linux-64/gfortran_impl_linux-64-14.3.0-h1a219da_19.conda#d5f5c8cc2a64220838a096041b7a7fb4 https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.88.1-hcfc306f_1.conda#ff216b19c24f3a46e9d17ebcf2f96390 -https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda#6514b3a10e84b6a849e1b15d3753eb22 +https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_19.conda#8b867d053ed89743eeac52c3a50f112d https://conda.anaconda.org/conda-forge/noarch/hpack-4.1.0-pyhd8ed1ab_0.conda#0a802cb9888dd14eeefc611f05c40b6e https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.conda#8e6923fc12f1fe8f8c4e5c9f343256ac https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19.1-h0c24ade_0.conda#f92f984b558e6e6204014b16d212b271 https://conda.anaconda.org/conda-forge/linux-64/libavif16-1.4.1-hcfa2d63_0.conda#f79415aee8862b3af85ea55dea37e46b https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c @@ -157,10 +157,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.3-h49c6c72_0.conda# https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.0-pyhcf101f3_0.conda#d2ec42db1d2fcd69003c8b069fb4301c https://conda.anaconda.org/conda-forge/noarch/networkx-3.4-pyhd8ed1ab_0.conda#17878dfc0a15a6e9d2aaef351a4210dc https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd -https://conda.anaconda.org/conda-forge/linux-64/openjph-0.27.0-h8d634f6_0.conda#8397bb8cf4b370f5df7d7ee3d80ea977 +https://conda.anaconda.org/conda-forge/linux-64/openjph-0.27.2-h8d634f6_0.conda#ac7564cac998d4df2f030de2e532291d https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.9.6-pyhcf101f3_0.conda#89c0b6d1793601a2a3a3f7d2d3d8b937 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e @@ -193,7 +193,7 @@ https://conda.anaconda.org/conda-forge/noarch/accessible-pygments-0.0.5-pyhd8ed1 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.1-py311h3778330_0.conda#dd214022a8f01bc2ebed383dfdc8deea -https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda#52d6457abc42e320787ada5f9033fa99 +https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_19.conda#2dd149aa693db92758af3e685ef30439 https://conda.anaconda.org/conda-forge/linux-64/gfortran_linux-64-14.3.0-h6b77fdb_24.conda#491f76c26b2d032b21ba0b79cc324c4f https://conda.anaconda.org/conda-forge/linux-64/glib-2.88.1-h435ced3_1.conda#7d844a122c6cf1d8d2fb024f85757225 https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h8a413ad_24.conda#ea3921760f33250a1c12926fce1660eb @@ -205,7 +205,7 @@ https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#61 https://conda.anaconda.org/conda-forge/noarch/lazy-loader-0.5-pyhd8ed1ab_0.conda#75932da6f03a6bef32b70a51e991f6eb https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.5-hf7376ad_1.conda#6adc0202fa7fcf0a5fce8c31ef2ed866 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/noarch/memory_profiler-0.61.0-pyhcf101f3_1.conda#e1bccffd88819e75729412799824e270 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 @@ -222,24 +222,24 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/noarch/beautifulsoup4-4.14.3-pyha770c72_0.conda#5267bef8efea4127aacd1f4e1f149b6e https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda#abd85120de1187b0d1ec305c2173c71b -https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-h76987e4_18.conda#958a6ecb4188cce9edbd9bbd2831a61d +https://conda.anaconda.org/conda-forge/linux-64/gfortran-14.3.0-he448592_7.conda#94394acdc56dcb4d55dddf0393134966 https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.11-h29cf534_0.conda#1e0e854b77451ac918b4a68f28932b1d -https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda#19189121d644d4ef75fed05383bc75f5 +https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-he448592_7.conda#91dc0abe7274ac5019deaa6100643265 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/noarch/importlib-resources-7.1.0-pyhd8ed1ab_0.conda#e3bffa82b874f8b9a2631bddb3869529 https://conda.anaconda.org/conda-forge/noarch/lazy_loader-0.5-pyhd8ed1ab_0.conda#4c8327180586e7b1cd8b6815fc8827f1 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.4-default_h99862b1_0.conda#fe7972688e6e3dd9b97d1fcce2d88235 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.5-default_h99862b1_0.conda#eb9e3f61562dcf3a5d313e45cf7b0dd6 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.5-default_h746c552_0.conda#c3df118cdc65584a78028bf225111b1b https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh8b19718_0.conda#35870d32aed92041d31cbb15e822dca3 https://conda.anaconda.org/conda-forge/linux-64/pyqt5-sip-12.17.0-py311h1ddb823_2.conda#4f296d802e51e7a6889955c7f1bd10be https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/tbb-2023.0.0-h51de99f_1.conda#6383c1684badc0d94408b12850cf07f1 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda#cbb88288f74dbe6ada1c6c7d0a97223e https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda#5da8c935dca9186673987f79cef0b2a5 https://conda.anaconda.org/conda-forge/linux-64/fortran-compiler-1.11.0-h9bea470_0.conda#d5596f445a1273ddc5ea68864c01b69f -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_12.conda#1a4a54fad5e36b8282ec6208dcb9bfb7 https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda#d53ffc0edc8eabf4253508008493c5bc https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 @@ -247,7 +247,7 @@ https://conda.anaconda.org/conda-forge/noarch/towncrier-24.8.0-pyhd8ed1ab_1.cond https://conda.anaconda.org/conda-forge/linux-64/compilers-1.11.0-ha770c72_0.conda#fdcf2e31dd960ef7c5daa9f2c95eff0e https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.26.11-h6d08254_0.conda#971da16e7fc43161329213557688d315 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_12.conda#db484eb7d5c23ca2a3129ddf5943de76 https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.0-pyhd8ed1ab_0.conda#134b2b57b7865d2316a7cce1915a51ed https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 diff --git a/build_tools/github/debian_32bit_lock.txt b/build_tools/github/debian_32bit_lock.txt index f2a579708302a..f8e81f7a7d8de 100644 --- a/build_tools/github/debian_32bit_lock.txt +++ b/build_tools/github/debian_32bit_lock.txt @@ -4,7 +4,7 @@ # # pip-compile --output-file=build_tools/github/debian_32bit_lock.txt build_tools/github/debian_32bit_requirements.txt # -coverage[toml]==7.13.5 +coverage[toml]==7.14.0 # via pytest-cov cython==3.2.4 # via -r build_tools/github/debian_32bit_requirements.txt @@ -18,7 +18,7 @@ meson==1.11.1 # via meson-python meson-python==0.19.0 # via -r build_tools/github/debian_32bit_requirements.txt -narwhals==2.20.0 +narwhals==2.21.0 # via -r build_tools/github/debian_32bit_requirements.txt ninja==1.13.0 # via -r build_tools/github/debian_32bit_requirements.txt diff --git a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock index 165e7dc4e42cf..865de8d575e9a 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_linux-64_conda.lock @@ -8,7 +8,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77 https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-headers-1.26.0-ha770c72_0.conda#cb93c6e226a7bed5557601846555153d https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.12.0-h54a6638_1.conda#16c2a0e9c4a166e53632cfca4f68d020 -https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_11.conda#4a1793b78e4309bbdb99bd033226f0d2 +https://conda.anaconda.org/conda-forge/linux-64/onemkl-license-2025.3.1-hf2ce2f3_12.conda#95321ce2d03500a23a6e80034cbd4804 https://conda.anaconda.org/conda-forge/noarch/pybind11-abi-11-hc364b38_1.conda#f0599959a2447c1e544e216bddf393fa https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda#0539938c55b6b1a59b560e843ad864a4 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 @@ -16,8 +16,8 @@ https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.4-h4922eb0_0.conda#fa2c5c7f8d5319ab9c9fcbbd04022abf -https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_11.conda#c0004c583be9ac82ad2115bc08f3d77d +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.5-h4922eb0_1.conda#f66101d2eb5de2924c10a63bbfa2926e +https://conda.anaconda.org/conda-forge/linux-64/mkl-include-2025.3.1-hf2ce2f3_12.conda#c6e7262ad8afd5fe1d64554cfa456060 https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 @@ -25,7 +25,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.2-h25fd6f3_2.conda#c2a01a08fc991620a74b32420e97868a https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda#57736f29cc2b0ec0b6c2952d3f101b6a https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.12.6-hb03c661_0.conda#e36ad70a7e0b48f091ed6902f04c23b8 https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 @@ -35,8 +35,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libbrotlicommon-1.2.0-hb03c661_1 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda#331ee9b72b9dff570d56b1302c5ab37d +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda#85072b0ad177c966294f129b7c04a2d5 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb @@ -45,7 +45,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libntlm-1.8-hb9d3cd8_0.conda#7c7 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda#5794b3bdc38177caf969dabd3af08549 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.11.3-hfe17d71_0.conda#1247168fe4a0b8912e3336bccdbf98a5 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda#0f03292cc56bf91a077a134ea8747118 @@ -77,10 +77,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949 https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172bf1cd1ff8629f2b1179945ed45055 https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda#42bf7eca1a951735fa06c0e3c0d5c8e6 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_19.conda#e5ce228e579726c07255dbf90dc62101 https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda#9de5350a85c4a20c685259b889aa6393 @@ -116,8 +116,8 @@ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_ https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.2-hb711507_0.conda#608e0ef8256b81d04456e8d211eee3e8 https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda#861fb6ccbc677bb9a9fb2468430b9c6a -https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.6.0-h9b893ba_1.conda#cd4946050ecfcb3c6fd09106ae6a261e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.12-h4bacb7b_1.conda#7bc920933e5fb225aba86a788164a8f1 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.7.0-h9b893ba_0.conda#60076118b1579967748f0c9a2912de7c +https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.10.13-h4bacb7b_0.conda#77f70a9ab785a146dbf66fba00131403 https://conda.anaconda.org/conda-forge/noarch/backports.zstd-1.4.0-py314h680f03e_0.conda#b712198b257f378e9bd8cde277218296 https://conda.anaconda.org/conda-forge/linux-64/brotli-1.2.0-hed03a55_1.conda#8ccf913aaba749a5496c17629d859ed1 https://conda.anaconda.org/conda-forge/linux-64/brotli-python-1.2.0-py314h3de4e8d_1.conda#8910d2c46f7e7b519129f486e0fe927a @@ -140,7 +140,7 @@ https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py314h97ea11e_0.conda#7397e418cab519b8d789936cf2dde6f6 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19.1-h0c24ade_0.conda#f92f984b558e6e6204014b16d212b271 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda#c3cc2864f82a944bc90a7beb4d3b0e88 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c @@ -150,7 +150,7 @@ https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ce https://conda.anaconda.org/conda-forge/linux-64/mpfr-4.2.2-he0a73b1_0.conda#85ce2ffa51ab21da5efa4a9edc5946aa https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.0-pyhcf101f3_0.conda#d2ec42db1d2fcd69003c8b069fb4301c https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/linux-64/nodejs-24.14.1-h3d65ac4_0.conda#fa4e76aac348ef9c27e72c79b02833fc https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd @@ -177,11 +177,11 @@ https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda#34e54f03dfea3e7a2dcf1453a85f1085 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda#ba231da7fccf9ea1e768caf5c7099b84 https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda#96d57aba173e878a2089d5638016dc5e -https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-h2d2dd48_2.conda#675ea6d90900350b1dcfa8231a5ea2dd -https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-he9ea9c5_1.conda#8e77514673f5773b40ff8953583938b6 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.10.1-ha62d5e7_3.conda#55eaf7066da1299d217ab32baedc7fa8 +https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.15.2-hc1936db_2.conda#9120bc47b6f837f3cea90928c3e9a8fa https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.16.2-h206d751_0.conda#5492abf806c45298ae642831c670bba0 https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py314h67df5f8_0.conda#78f547b78ace7541c4f54c4268ac9d2e +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.14.0-py314h67df5f8_0.conda#7f8715a1928f6f126323320a4c5ada3a https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc43f0b53b6e3a7bc7dce5e4f1dc9 @@ -191,7 +191,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928 https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda#27ac5ae872a21375d980bd4a6f99edf3 https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.78.1-h1d1128b_0.conda#b5fb6d6c83f63d83ef2721dca6ff7091 https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.12.2-default_hafda6a7_1000.conda#0ed3aa3e3e6bc85050d38881673a692f -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.5-hf7376ad_1.conda#6adc0202fa7fcf0a5fce8c31ef2ed866 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/libxslt-1.1.43-h711ed8c_1.conda#87e6096ec6d542d1c1f8b33245fe8300 https://conda.anaconda.org/conda-forge/linux-64/mpc-1.4.0-he0a73b1_0.conda#770d00bf57b5599c4544d61b61d8c6c6 @@ -214,65 +214,65 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.cond https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda#e192019153591938acf7322b6459d36e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda#665d152b9c6e78da404086088077c844 https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda#aaa2a381ccc56eac91d63b6c1240312f -https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.11.5-h6d69fc9_5.conda#4c5c16bf1133dcfe100f33dd4470998e +https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.12.2-he6ee468_1.conda#50ae8372984b8b98e056ac8f6b70ab29 https://conda.anaconda.org/conda-forge/linux-64/azure-identity-cpp-1.13.3-hed0cdb0_1.conda#68bfb556bdf56d56e9f38da696e752ca https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.12.0-ha7a2c86_1.conda#6400f73fe5ebe19fe7aca3616f1f1de7 https://conda.anaconda.org/conda-forge/linux-64/gmpy2-2.3.0-py314h28848ee_1.conda#a99b82fda10aecd4ed853172bf4f6a28 https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.5-default_h746c552_0.conda#c3df118cdc65584a78028bf225111b1b https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda#53e7cbb2beb03d69a478631e23e340e9 https://conda.anaconda.org/conda-forge/linux-64/libopentelemetry-cpp-1.26.0-h9692893_0.conda#c360be6f9e0947b64427603e91f9651f https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 https://conda.anaconda.org/conda-forge/linux-64/libvulkan-loader-1.4.341.0-h5279c79_0.conda#31ad065eda3c2d88f8215b1289df9c89 https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.0-py314h9891dd4_0.conda#e13172f02effa3c9f07571ed0ddef44d +https://conda.anaconda.org/conda-forge/linux-64/optree-0.19.1-py314h9891dd4_0.conda#44ffc8b345a7844a847d4fdf469d64ea https://conda.anaconda.org/conda-forge/noarch/playwright-python-1.59.0-pyhcf101f3_0.conda#313ba7b8e2a4fed359c935202853932c https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/linux-64/tbb-2023.0.0-h51de99f_1.conda#6383c1684badc0d94408b12850cf07f1 -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda#cbb88288f74dbe6ada1c6c7d0a97223e https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda#7bbe9a0cc0df0ac5f5a8ad6d6a11af2f -https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.37.4-h4c8aef7_3.conda#798a499cf76e530a992365d557ba5827 +https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.38.3-h745e52d_1.conda#6a65b3595a8933808c03ff065dfb7702 https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.16.0-hdd73cc9_1.conda#939d9ce324e51961c7c4c0046733dbb7 https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda#b513eb83b3137eca1192c34bf4f013a7 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-3.3.0-h25dbb67_1.conda#b2baa4ce6a9d9472aaa602b88f8d40ac -https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_11.conda#1065cab1a38320768d811d740b18b213 +https://conda.anaconda.org/conda-forge/linux-64/mkl-2025.3.1-h0e700b2_12.conda#1a4a54fad5e36b8282ec6208dcb9bfb7 https://conda.anaconda.org/conda-forge/linux-64/polars-runtime-32-1.40.0-py310hffdcd12_0.conda#8eacf9ff4d4e1ca1b52f8f3ba3e0c993 https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.3.0-pyhd8ed1ab_0.conda#50d191b852fccb4bf9ab7b59b030c99d https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 https://conda.anaconda.org/conda-forge/noarch/requests-2.33.1-pyhcf101f3_1.conda#9659f587a8ceacc21864260acd02fc67 https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 -https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-hc3785e1_3.conda#cfffedbfd03d5a6bb74157c14b6f0cdf +https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.747-h41c0014_4.conda#169a79ea1127077d8dc36dc963ff55ac https://conda.anaconda.org/conda-forge/linux-64/azure-storage-files-datalake-cpp-12.14.0-h52c5a47_1.conda#6d10339800840562b7dad7775f5d2c16 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h5875eb1_mkl.conda#d03e4571f7876dcd4e530f3d07faf333 https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-3.3.0-hdbdcf42_1.conda#da94b149c8eea6ceef10d9e408dcfeb3 -https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_11.conda#21de02ba3b4c8b8eee6dc6e77790babd +https://conda.anaconda.org/conda-forge/linux-64/mkl-devel-2025.3.1-ha770c72_12.conda#db484eb7d5c23ca2a3129ddf5943de76 https://conda.anaconda.org/conda-forge/noarch/polars-1.40.0-pyh58ad624_0.conda#fd16be490f5403adfbf27dd4901bbe34 https://conda.anaconda.org/conda-forge/noarch/pytest-base-url-2.1.0-pyhd8ed1ab_1.conda#057f32e4c376ce0c4c4a32a9f06bf34e https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.11.0-pl5321h16c4a6b_4.conda#c81127acb50fdc7760682495fc9ab088 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-24.0.0-ha7f89c6_0_cpu.conda#8aeb79715524b48267068fb0fd185956 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-24.0.0-h0935d00_1_cpu.conda#aed984d45692d6211ebf013b62c9fa02 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_hfef963f_mkl.conda#72cf77ee057f87d826f9b98cacd67a59 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h5e43f62_mkl.conda#8b13738802df008211c9ecd08775ca21 https://conda.anaconda.org/conda-forge/linux-64/pyside6-6.11.0-py314h3987850_2.conda#c77e1fe23b6cf0b6077e5f924ac420c9 https://conda.anaconda.org/conda-forge/noarch/pytest-playwright-0.7.2-pyhd8ed1ab_1.conda#34d1d3c36ffccb8dc02c3f8da7ae1e5c -https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-24.0.0-h53684a4_0_cpu.conda#73e0aeaa603ff40128e75435a3c5ac77 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-compute-24.0.0-h53684a4_1_cpu.conda#0aac1926c3b2f8c35570af6be677f8ad https://conda.anaconda.org/conda-forge/linux-64/liblapacke-3.11.0-6_hdba1596_mkl.conda#5efff83ae645656f28c826aa192e7651 -https://conda.anaconda.org/conda-forge/linux-64/libparquet-24.0.0-h7376487_0_cpu.conda#c828cca50cd3a7c53d12ce8f0872c6ec +https://conda.anaconda.org/conda-forge/linux-64/libparquet-24.0.0-h7376487_1_cpu.conda#5e60f3c311d00d456f089177bb75ebaf https://conda.anaconda.org/conda-forge/linux-64/libtorch-2.10.0-cpu_mkl_h7058990_103.conda#2df90510834746b1f52c5299bc99a81f https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda#36f5b7eb328bdc204954a2225cf908e2 https://conda.anaconda.org/conda-forge/noarch/array-api-strict-2.5-pyhcf101f3_0.conda#e65c7d49168ef8014ad0563ea0d94ff1 https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_hcf00494_mkl.conda#b789b886f2b45c3a9c91935639717808 https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.3.3-py314h97ea11e_4.conda#95bede9cdb7a30a4b611223d52a01aa4 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-24.0.0-h635bf11_0_cpu.conda#178d7e3f5c392e606ccd0aaff4331019 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-24.0.0-h635bf11_1_cpu.conda#fa76d2ed4b435617a0fe5b8e7b9ae9c1 https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py314hb4ffadd_0.conda#41ee6fe2a848876bc9f524c5a500b85b https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-24.0.0-py314h969be7f_0_cpu.conda#b066370d80ec7fca3c1d4028dc09164f https://conda.anaconda.org/conda-forge/linux-64/pytorch-2.10.0-cpu_mkl_py314_h6018c46_103.conda#a3c40f317db763f9631d078d0fb2759e https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda#d0510124f87c75403090e220db1e9d41 https://conda.anaconda.org/conda-forge/noarch/scipy-doctest-2.2.0-pyhcf101f3_0.conda#21ac538af5bad73af42729841772de89 https://conda.anaconda.org/conda-forge/linux-64/blas-2.306-mkl.conda#51424ae4b1ba5521ee838721d63d4390 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-24.0.0-h635bf11_0_cpu.conda#dc226b80ae51753ce2bd8193dcc42a88 +https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-24.0.0-h635bf11_1_cpu.conda#021214e64486a6ba4df95d64b703f1fb https://conda.anaconda.org/conda-forge/linux-64/matplotlib-base-3.10.9-py314h1194b4b_0.conda#11a821746ad11e642fcc615c3d66aa44 https://conda.anaconda.org/conda-forge/linux-64/pyamg-5.3.0-py314h3a4f467_1.conda#478c6ef795065cd15cdbe1e214b30175 https://conda.anaconda.org/conda-forge/linux-64/pytorch-cpu-2.10.0-cpu_mkl_hd61e0f4_103.conda#54ad123774a53ce33aa7e99b6e53b4a6 -https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-24.0.0-hb4dd7c2_0_cpu.conda#cb5a9557a2ffa1b18b4e05621354c6bd +https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-24.0.0-hb4dd7c2_1_cpu.conda#e3e42803a838c2177759e6aef1363512 https://conda.anaconda.org/conda-forge/linux-64/matplotlib-3.10.9-py314hdafbbf9_0.conda#2046de06d7f4149a29c5d0e2cc26d6dd https://conda.anaconda.org/conda-forge/linux-64/pyarrow-24.0.0-py314hdafbbf9_0.conda#6629041b133a9d65d68c4f2269432378 diff --git a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock index 4f1b21398254a..a95c1f15d7b8d 100644 --- a/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_mkl_no_openmp_osx-64_conda.lock @@ -9,7 +9,7 @@ https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda#4173a https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda#627eca44e62e2b665eeec57a984a7f00 https://conda.anaconda.org/conda-forge/osx-64/libbrotlicommon-1.2.0-h8616949_1.conda#f157c098841474579569c85a60ece586 -https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.4-h19cb2f5_0.conda#4394b1ba4b9604ac4e1c5bdc74451279 +https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.5-h19cb2f5_1.conda#56fa8b3e43d26c97da88aea4e958f616 https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda#31aa65919a729dc48180893f62c25221 https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.8.0-hcc62823_0.conda#d2e01f78c1daaeb4d2aa870125ebcd7e https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda#66a0dc7464927d0853b590b6f53ba3ea @@ -19,7 +19,7 @@ https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.3-hbb4bfdb_0.conda#bec https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda#ec88ba8a245855935b871a7324373105 https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda#7bb6608cf1f83578587297a158a6630b https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda#30439ff30578e504ee5e0b390afc8c65 -https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.4-h0d3cbff_0.conda#fac1a640081b85688ead36a88c4d20ff +https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.5-h0d3cbff_1.conda#d801d0ce2eab00dbb0178b196d0ce754 https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.6-hcc0dc9a_0.conda#31b8740cf1b2588d4e61c81191004061 https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-h00291cd_1002.conda#8bcf980d2c6b17094961198284b8e862 https://conda.anaconda.org/conda-forge/osx-64/xorg-libxau-1.0.12-h8616949_1.conda#47f1b8b4a76ebd0cd22bd7153e54a4dc @@ -44,7 +44,7 @@ https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda#727109 https://conda.anaconda.org/conda-forge/osx-64/brotli-bin-1.2.0-h8616949_1.conda#34803b20dfec7af32ba675c5ccdbedbf https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.6-h894318c_0.conda#8ae9dfcda989b435223605126a97a963 https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.3-h58fbd8d_0.conda#27515b8ab8bf4abd8d3d90cf11212411 -https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda#9a5cb96e43f5c2296690186e15b3296f +https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_19.conda#4bf33d5ca73f4b89d3495285a42414a4 https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda#9d4344f94de4ab1330cdc41c40152ea6 https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.3-h953d39d_0.conda#33f30d4878d1f047da82a669c33b307d https://conda.anaconda.org/conda-forge/osx-64/python-3.14.4-h7c6738f_100_cp314.conda#d4e8506d0ac094be21451682eed9ce4d @@ -55,13 +55,13 @@ https://conda.anaconda.org/conda-forge/osx-64/cython-3.2.4-py314hf0dd12f_0.conda https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a57b4be42619213a94f31d2c69c5dda7 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.5.0-py314hd6e1bd6_0.conda#25a8718587d3d0d9114b25dfa93b864c -https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.19-h5ea7634_0.conda#f05fc88b6b2480486c006a9bf04db0b7 +https://conda.anaconda.org/conda-forge/osx-64/lcms2-2.19.1-h5ea7634_0.conda#3ae3b6db0dcada986f1e3b608e1cb0fc https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.3-h694c41f_0.conda#63b822fcf984c891f0afab2eedfcfaf4 -https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda#ca52daf58cea766656266c8771d8be81 +https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_19.conda#1cddb3f7e54f5871297afc0fafa61c2c https://conda.anaconda.org/conda-forge/osx-64/libhwloc-2.12.2-default_h273dbb7_1000.conda#56aaf4b7cc4c24e30cecc185bb08668d https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.0-pyhcf101f3_0.conda#d2ec42db1d2fcd69003c8b069fb4301c https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.4-h52bb76a_0.conda#46e628da6e796c948fa8ec9d6d10bda3 https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e59a063366f1fc4f45ac86bd9485f @@ -76,12 +76,12 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b53 https://conda.anaconda.org/conda-forge/osx-64/tornado-6.5.5-py314h217eccc_0.conda#9fdead77ed9fd152b131289c6984ed7c https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-64/unicodedata2-17.0.1-py314h4f144dc_0.conda#773e3141f292d9698e706da094ada8c1 -https://conda.anaconda.org/conda-forge/osx-64/coverage-7.13.5-py314h77fa6c7_0.conda#c5d3ea7d5f490c69a6af7c056624fca4 +https://conda.anaconda.org/conda-forge/osx-64/coverage-7.14.0-py314h77fa6c7_0.conda#8c42f6115a718f67602c792c0ab2cc14 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 https://conda.anaconda.org/conda-forge/osx-64/freetype-2.14.3-h694c41f_0.conda#6ab1403cc6cb284d56d0464f19251075 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda#34a9f67498721abcfef00178bcf4b190 +https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_19.conda#d362f41203d0a1d2d4940446f95374c9 https://conda.anaconda.org/conda-forge/osx-64/pillow-12.2.0-py314hc904d5e_0.conda#fb32d458ddac23248e07a0830c6ffc7b https://conda.anaconda.org/conda-forge/noarch/pyproject-metadata-0.11.0-pyhd8ed1ab_0.conda#cd6dae6c673c8f12fe7267eac3503961 https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda#5b8d21249ff20967101ffa321cab24e8 diff --git a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock index 9c28d4790b1b0..c050c895a380f 100644 --- a/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock +++ b/build_tools/github/pylatest_conda_forge_osx-arm64_conda.lock @@ -11,7 +11,7 @@ https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad65 https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda#620b85a3f45526a8bc4d23fd78fc22f0 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlicommon-1.2.0-hc919400_1.conda#006e7ddd8a110771134fcc4e1e3a6ffa -https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.4-h55c6f16_0.conda#448a1af83a9205655ee1cf48d3875ca3 +https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.5-h55c6f16_1.conda#ff484b683fecf1e875dfc7aa01d19796 https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda#de91b5ce46dc7968b6e311f9add055a2 https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda#a6130c709305cd9828b4e1bd9ba0000c https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.0-hf6b4638_0.conda#65466e82c09e888ca7560c11a97d5450 @@ -23,7 +23,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda#c0d87c3c8e075daf1daf6c31b53e8083 https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda#e5e7d467f80da752be17796b87fe6385 https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda#bc5a5721b6439f2f62a84f2548136082 -https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.4-hc7d1edf_0.conda#46d04a647df7a4525e487d88068d19ef +https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.5-hc7d1edf_1.conda#8a4e2a54034b35bc6fa5bf9282913f45 https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda#343d10ed5b44030a2f67193905aea159 https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-hd74edd7_1002.conda#415816daf82e0b23a736a069a75e9da7 https://conda.anaconda.org/conda-forge/osx-arm64/xorg-libxau-1.0.12-hc919400_1.conda#78b548eed8227a689f93775d5d23ae09 @@ -56,7 +56,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda#ab1 https://conda.anaconda.org/conda-forge/osx-arm64/brotli-bin-1.2.0-hc919400_1.conda#377d015c103ad7f3371be1777f8b584c https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.6-h414bf82_0.conda#1628795893a799313a719264fd7f2227 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.3-hdfa99f5_0.conda#e98ba7b5f09a5f450eca083d5a1c4649 -https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda#92df6107310b1fff92c4cc84f0de247b +https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_19.conda#644058123986582db33aebd4ae2ca184 https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-6.33.5-h4a5acfd_0.conda#b839e3295b66434f20969c8b940f056a https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda#c08557d00807785decafb932b5be7ef5 https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda#e2a72ab2fa54ecb6abab2b26cde93500 @@ -73,16 +73,16 @@ https://conda.anaconda.org/conda-forge/noarch/filelock-3.29.0-pyhd8ed1ab_0.conda https://conda.anaconda.org/conda-forge/noarch/fsspec-2026.4.0-pyhd8ed1ab_0.conda#2c11aa96ea85ced419de710c1c3a78ff https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.5.0-py314hf8a3a22_0.conda#eb1465d8a644ef290d18fb86af6e9bc4 -https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.19-hdfa7624_0.conda#57baad99764cf6057227e50b11e2ec5b +https://conda.anaconda.org/conda-forge/osx-arm64/lcms2-2.19.1-hdfa7624_0.conda#e5ba982008c0ac1a1c0154617371bab5 https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.3-hce30654_0.conda#f73b109d49568d5d1dda43bb147ae37f -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda#c4a6f7989cffb0544bfd9207b6789971 +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_19.conda#ba36d8c606a6a53fe0b8c12d47267b3d https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda#d1d9b233830f6631800acc1e081a9444 https://conda.anaconda.org/conda-forge/osx-arm64/markupsafe-3.0.3-py314h6e9b3f0_1.conda#d33c0a15882b70255abdd54711b06a45 https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/osx-arm64/mpc-1.4.0-h169892a_0.conda#2845c3a1d0d8da1db92aba8323892475 https://conda.anaconda.org/conda-forge/noarch/mpmath-1.3.0-pyhd8ed1ab_1.conda#3585aa87c43ab15b167b574cd73b057b https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.0-pyhcf101f3_0.conda#d2ec42db1d2fcd69003c8b069fb4301c https://conda.anaconda.org/conda-forge/noarch/networkx-3.6.1-pyhcf101f3_0.conda#a2c1eeadae7a309daed9d62c96012a2b https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.4-hd9e9057_0.conda#4b5d3a91320976eec71678fad1e3569b https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 @@ -100,7 +100,7 @@ https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda#b53 https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.5-py314h6c2aa35_0.conda#3f81f8b2fe2c26a82c0abf57ab2b9610 https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/osx-arm64/unicodedata2-17.0.1-py314h6c2aa35_0.conda#4fffb3ba871bb05f34ffb705534dfef5 -https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.13.5-py314h6e9b3f0_0.conda#cdbafe4a3e605024e7372c9580f9d734 +https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.14.0-py314h6e9b3f0_0.conda#70cf43e2d03269a3dfb33c284ce05dff https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/fonttools-4.62.1-pyh7db6752_0.conda#14cf1ac7a1e29553c6918f7860aab6d8 https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.14.3-hce30654_0.conda#6dcc75ba2e04c555e881b72793d3282f @@ -109,7 +109,7 @@ https://conda.anaconda.org/conda-forge/noarch/jinja2-3.1.6-pyhcf101f3_1.conda#04 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_4.conda#eaf3d06e3a8a10dee7565e8d76ae618d https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_9.conda#ddb70ebdcbf3a44bddc2657a51faf490 -https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda#26981599908ed2205366e8fc91b37fc6 +https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_19.conda#1ea03f87cdb1078fbc0e2b2deb63752c https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda#8237b150fcd7baf65258eef9a0fc76ef https://conda.anaconda.org/conda-forge/osx-arm64/pillow-12.2.0-py314hab283cf_0.conda#adf49537da0e0c34cf735e71fe579506 https://conda.anaconda.org/conda-forge/noarch/pybind11-3.0.1-pyh7a1b43c_0.conda#70ece62498c769280f791e836ac53fff @@ -121,7 +121,7 @@ https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_4. https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.32-openmp_he657e61_0.conda#3a1111a4b6626abebe8b978bb5a323bf https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda#3e3ac06efc5fdc1aa675ca30bf7d53df https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.conda#369afcc2d4965e7a6a075ab82e2a26b8 -https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.19.0-py314h6cfcd04_0.conda#0c8942bc23758aaeafed2707902fc48e +https://conda.anaconda.org/conda-forge/osx-arm64/optree-0.19.1-py314h6cfcd04_0.conda#7f58db69263708a3bd66bb7e547bf0a7 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e https://conda.anaconda.org/conda-forge/noarch/sympy-1.14.0-pyh2585a3b_106.conda#32d866e43b25275f61566b9391ccb7b5 https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_he8a363d_4.conda#76c651b923e048f3f3e0ecb22c966f70 diff --git a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock index 5efc792915dda..38a724e6c6d4c 100644 --- a/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock +++ b/build_tools/github/pylatest_pip_openblas_pandas_linux-64_conda.lock @@ -5,19 +5,19 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.13-8_cp313.conda#94305520c52a4aa3f6c2b1ff6008d9f8 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda#faac990cb7aedc7f3a2224f2c9b0c26c https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda#57736f29cc2b0ec0b6c2952d3f101b6a https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda#2c21e66f50753a083cbe6b80f38268fa https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda#5794b3bdc38177caf969dabd3af08549 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.2-h35e630c_0.conda#da1b85b6a87e141f5140bb9924cecab0 @@ -32,20 +32,20 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e # pip babel @ https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl#sha256=e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35 # pip certifi @ https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl#sha256=3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a # pip charset-normalizer @ https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd -# pip coverage @ https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3 +# pip coverage @ https://files.pythonhosted.org/packages/6f/5f/b5370068b2f57787454592ed7dcd1002f0f1703b7db1fa30f6a325a4ca6e/coverage-7.14.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl#sha256=9d1aa57a1dc8e05bdc42e81c5d671d849577aeedf279f4c449d6d286f9ed88ca # pip cycler @ https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl#sha256=85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30 # pip cython @ https://files.pythonhosted.org/packages/7a/d2/16fa02f129ed2b627e88d9d9ebd5ade3eeb66392ae5ba85b259d2d52b047/cython-3.2.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=f81eda419b5ada7b197bbc3c5f4494090e3884521ffd75a3876c93fbf66c9ca8 # pip docutils @ https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl#sha256=d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de # pip execnet @ https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl#sha256=67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec # pip fonttools @ https://files.pythonhosted.org/packages/e2/98/8b1e801939839d405f1f122e7d175cebe9aeb4e114f95bfc45e3152af9a7/fonttools-4.62.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=6706d1cb1d5e6251a97ad3c1b9347505c5615c112e66047abbef0f8545fa30d1 -# pip idna @ https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl#sha256=892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3 +# pip idna @ https://files.pythonhosted.org/packages/6c/3c/3f62dee257eb3d6b2c1ef2a09d36d9793c7111156a73b5654d2c2305e5ce/idna-3.14-py3-none-any.whl#sha256=e677eaf072e290f7b725f9acf0b3a2bd55f9fd6f7c70abe5f0e34823d0accf69 # pip imagesize @ https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl#sha256=5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96 # pip iniconfig @ https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl#sha256=f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 # pip joblib @ https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl#sha256=5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713 # pip kiwisolver @ https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3 # pip markupsafe @ https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl#sha256=ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676 # pip meson @ https://files.pythonhosted.org/packages/5e/cd/f3a881ff5e601d6bbeff63b38ee2362e1167c47d9cde03eddf8d71a4ffb0/meson-1.11.1-py3-none-any.whl#sha256=9b3a023657e393dbc5335b95c561337d49b7a458f5541e47ec44f2cc566e0d80 -# pip narwhals @ https://files.pythonhosted.org/packages/d0/69/f24d3d1c38ad69e256138b4ec2452a8c7cf66be49dc214771ae99dd4f0a0/narwhals-2.20.0-py3-none-any.whl#sha256=16e750ea5507d4ba6e8d03455b5f93a535e0405976561baea235bca5dc9f475d +# pip narwhals @ https://files.pythonhosted.org/packages/c7/e1/68c2256b69a314eba133673377ba9118c356f6342a0c02b61de449cf2bf2/narwhals-2.21.0-py3-none-any.whl#sha256=1e6617d0fca68ae1fda29e5397c4eaacd3ffc9fffe6bcd6ded0c690475e853be # pip ninja @ https://files.pythonhosted.org/packages/ed/de/0e6edf44d6a04dabd0318a519125ed0415ce437ad5a1ec9b9be03d9048cf/ninja-1.13.0-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl#sha256=fb46acf6b93b8dd0322adc3a4945452a4e774b75b91293bafcc7b7f8e6517dfa # pip numpy @ https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83 # pip packaging @ https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl#sha256=5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e @@ -63,7 +63,7 @@ https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh145f28c_0.conda#2e7e # pip sphinxcontrib-qthelp @ https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl#sha256=b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb # pip sphinxcontrib-serializinghtml @ https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl#sha256=6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331 # pip threadpoolctl @ https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl#sha256=43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb -# pip urllib3 @ https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl#sha256=bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4 +# pip urllib3 @ https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl#sha256=9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897 # pip array-api-strict @ https://files.pythonhosted.org/packages/22/a3/ed2786497cb3cb90f13ff3eb5f3cf92b447ae3f8451307c0e94eeb2bb445/array_api_strict-2.5-py3-none-any.whl#sha256=0438dd48df521c710ca33d13e8f7e41dd74a9c2427a5d8f549d6f2fe93f8d945 # pip contourpy @ https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl#sha256=4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9 # pip jinja2 @ https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl#sha256=85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 diff --git a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock index a88df2667c8ed..247299b6caf53 100644 --- a/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock +++ b/build_tools/github/pymin_conda_forge_arm_linux-aarch64_conda.lock @@ -7,7 +7,7 @@ https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed3 https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2#4d59c254e01d9cde7957100457e2d5fb https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda#49023d73832ef61042f6a237cb2687e7 https://conda.anaconda.org/conda-forge/linux-aarch64/libglvnd-1.7.0-hd24410f_2.conda#9e115653741810778c9a915a2f8439e7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_18.conda#4faa39bf919939602e594253bd673958 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgomp-15.2.0-h8acb6b2_19.conda#c5e8a379c4a2ec2aea4ba22758c001d9 https://conda.anaconda.org/conda-forge/linux-aarch64/libzlib-1.3.2-hdc9db2a_2.conda#502006882cf5461adced436e410046d1 https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 @@ -19,7 +19,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libopengl-1.7.0-hd24410f_2. https://conda.anaconda.org/conda-forge/linux-aarch64/zstd-1.5.7-h85ac4a6_6.conda#c3655f82dcea2aa179b291e7099c1fcc https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-aarch64/ld_impl_linux-aarch64-2.45.1-default_h1979696_102.conda#a21644fc4a83da26452a718dc9468d5f -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_18.conda#552567ea2b61e3a3035759b2fdb3f9a6 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-15.2.0-h8acb6b2_19.conda#f35b3f52d0a2ec4ffe3c89ba135cdb9a https://conda.anaconda.org/conda-forge/linux-aarch64/alsa-lib-1.2.15.3-he30d5cf_0.conda#4a98cbc4ade694520227402ff8880630 https://conda.anaconda.org/conda-forge/linux-aarch64/bzip2-1.0.8-h4777abc_9.conda#840d8fc0d7b3209be93080bc20e07f2d https://conda.anaconda.org/conda-forge/linux-aarch64/keyutils-1.6.3-h86ecc28_0.conda#e7df0aab10b9cbb73ab2a467ebfaf8c7 @@ -27,8 +27,8 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlicommon-1.2.0-he30d https://conda.anaconda.org/conda-forge/linux-aarch64/libdeflate-1.25-h1af38f5_0.conda#a9138815598fe6b91a1d6782ca657b0c https://conda.anaconda.org/conda-forge/linux-aarch64/libexpat-2.8.0-hfae3067_0.conda#3bacd6171f0a3f8fddd06c3d5ae01955 https://conda.anaconda.org/conda-forge/linux-aarch64/libffi-3.5.2-h376a255_0.conda#2f364feefb6a7c00423e80dcb12db62a -https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_18.conda#4feebd0fbf61075a1a9c2e9b3936c257 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_18.conda#574d88ce3348331e962cfa5ed451b247 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgcc-ng-15.2.0-he9431aa_19.conda#770cf892e5530f43e63cadc673e85653 +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran5-15.2.0-h1b7bec0_19.conda#779dbb494de6d3d6477cab52eb34285a https://conda.anaconda.org/conda-forge/linux-aarch64/libiconv-1.18-h90929bb_2.conda#5a86bf847b9b926f3a4f203339748d78 https://conda.anaconda.org/conda-forge/linux-aarch64/libjpeg-turbo-3.1.4.1-he30d5cf_0.conda#a85ba48648f6868016f2741fd9170250 https://conda.anaconda.org/conda-forge/linux-aarch64/liblzma-5.8.3-he30d5cf_0.conda#76298a9e6d71ee6e832a8d0d7373b261 @@ -36,7 +36,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libnsl-2.0.1-h86ecc28_1.con https://conda.anaconda.org/conda-forge/linux-aarch64/libpciaccess-0.18-h86ecc28_0.conda#5044e160c5306968d956c2a0a2a440d6 https://conda.anaconda.org/conda-forge/linux-aarch64/libpng-1.6.58-h1abf092_0.conda#f51503ac45a4888bce71af9027a2ecc9 https://conda.anaconda.org/conda-forge/linux-aarch64/libsqlite-3.53.1-h022381a_0.conda#2ec1119217d8f0d086e9a62f3cb0e5ea -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_18.conda#f56573d05e3b735cb03efeb64a15f388 +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-15.2.0-hef695bb_19.conda#543fbc8d71f2a0baf04cf88ce96cb8bb https://conda.anaconda.org/conda-forge/linux-aarch64/libuuid-2.42-h1022ec0_0.conda#a0b5de740d01c390bdbb46d7503c9fab https://conda.anaconda.org/conda-forge/linux-aarch64/libwebp-base-1.6.0-ha2e29f5_0.conda#24e92d0942c799db387f5c9d7b81f1af https://conda.anaconda.org/conda-forge/linux-aarch64/ncurses-6.6-hf8d1292_0.conda#b2a43456aa56fe80c2477a5094899eff @@ -57,10 +57,10 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libbrotlienc-1.2.0-he30d5cf https://conda.anaconda.org/conda-forge/linux-aarch64/libdrm-2.4.125-he30d5cf_1.conda#2079727b538f6dd16f3fa579d4c3c53f https://conda.anaconda.org/conda-forge/linux-aarch64/libedit-3.1.20250104-pl5321h976ea20_0.conda#fb640d776fc92b682a14e001980825b1 https://conda.anaconda.org/conda-forge/linux-aarch64/libfreetype6-2.14.3-hdae7a39_0.conda#b99ed99e42dafb27889483b3098cace7 -https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_18.conda#41f261f5e4e2e8cbd236c2f1f15dae1b +https://conda.anaconda.org/conda-forge/linux-aarch64/libgfortran-15.2.0-he9431aa_19.conda#c7a5b5decf969ead5ecada83654164cf https://conda.anaconda.org/conda-forge/linux-aarch64/libhiredis-1.3.0-h5ad3122_1.conda#c11818b31f7c054ce220041b2459aacb https://conda.anaconda.org/conda-forge/linux-aarch64/libntlm-1.4-hf897c2e_1002.tar.bz2#835c7c4137821de5c309f4266a51ba89 -https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_18.conda#699d294376fe18d80b7ce7876c3a875d +https://conda.anaconda.org/conda-forge/linux-aarch64/libstdcxx-ng-15.2.0-hdbbeba8_19.conda#c82ed61c3ec470c5ec624580e6ba16e4 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcb-1.17.0-h262b8f6_0.conda#cd14ee5cca2464a425b1dbfc24d90db2 https://conda.anaconda.org/conda-forge/linux-aarch64/libxcrypt-4.4.36-h31becfc_1.conda#b4df5d7d4b63579d081fd3a4cf99740e https://conda.anaconda.org/conda-forge/linux-aarch64/ninja-1.13.2-hdc560ac_0.conda#8b5222a41b5d51fb1a5a2c514e770218 @@ -96,14 +96,14 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/fontconfig-2.17.1-hba86a56_ https://conda.anaconda.org/conda-forge/linux-aarch64/freetype-2.14.3-h8af1aa0_0.conda#f11edf8adf0d119148b97f745548390d https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-aarch64/kiwisolver-1.5.0-py311h229e7f7_0.conda#aeade47300d466d9d6ba01daaca31a86 -https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.19-h9d5b58d_0.conda#6bc596d689e559787079968b885e75d8 +https://conda.anaconda.org/conda-forge/linux-aarch64/lcms2-2.19.1-h9d5b58d_0.conda#b1f8bee3c53a6d2c103fb4a1ae44f5c4 https://conda.anaconda.org/conda-forge/linux-aarch64/libblas-3.11.0-6_haddc8a3_openblas.conda#652bb20bb4618cacd11e17ae070f47ce https://conda.anaconda.org/conda-forge/linux-aarch64/libcups-2.3.3-h4f2b762_6.conda#67828c963b17db7dc989fe5d509ef04a https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-1.7.0-hd24410f_2.conda#1d4269e233636148696a67e2d30dad2a https://conda.anaconda.org/conda-forge/linux-aarch64/libxml2-2.15.3-h869d058_0.conda#2cffef27cb2eb9ed1e315a1e269d4335 https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.0-pyhcf101f3_0.conda#d2ec42db1d2fcd69003c8b069fb4301c https://conda.anaconda.org/conda-forge/linux-aarch64/openblas-0.3.32-pthreads_h3a8cbd8_0.conda#62e1383bcaf8f5244d2598bbda509e3b https://conda.anaconda.org/conda-forge/linux-aarch64/openjpeg-2.5.4-h5da879a_0.conda#cea962410e327262346d48d01f05936c https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 @@ -124,7 +124,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxext-1.3.7-he30d5cf https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxfixes-6.0.2-he30d5cf_0.conda#e8b4056544341daf1d415eaeae7a040c https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrender-0.9.12-h86ecc28_0.conda#ae2c2dd0e2d38d249887727db2af960e https://conda.anaconda.org/conda-forge/linux-aarch64/cairo-1.18.4-h0b6afd8_1.conda#043c13ed3a18396994be9b4fab6572ad -https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.13.5-py311h2dad8b0_0.conda#d3bcad889948820993ded0b13c2ae906 +https://conda.anaconda.org/conda-forge/linux-aarch64/coverage-7.14.0-py311h2dad8b0_0.conda#600e7eeee7b96c872a8097d76822b532 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-aarch64/fonttools-4.62.1-py311h164a683_0.conda#247d8664e397d43269288370ffe81ac3 https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 @@ -132,7 +132,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/libcblas-3.11.0-6_hd72aa62_ https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-1.7.0-hd24410f_2.conda#0d00176464ebb25af83d40736a2cd3bb https://conda.anaconda.org/conda-forge/linux-aarch64/libglx-devel-1.7.0-hd24410f_2.conda#1f9ddbb175a63401662d1c6222cef6ff https://conda.anaconda.org/conda-forge/linux-aarch64/liblapack-3.11.0-6_h88aeb00_openblas.conda#e23a27b52fb320687239e2c5ae4d7540 -https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.4-hfd2ba90_0.conda#6985556a15653f1df6639744cabef3f9 +https://conda.anaconda.org/conda-forge/linux-aarch64/libllvm22-22.1.5-hfd2ba90_1.conda#b033ae799252b9b2fa63a9b6502aba75 https://conda.anaconda.org/conda-forge/linux-aarch64/libxkbcommon-1.13.1-h3c6a4c8_0.conda#22c1ce28d481e490f3635c1b6a2bb23f https://conda.anaconda.org/conda-forge/linux-aarch64/libxslt-1.1.43-h6700d25_1.conda#0f31501ccd51a40f0a91381080ae7368 https://conda.anaconda.org/conda-forge/linux-aarch64/openldap-2.6.13-h2fb54aa_0.conda#67eea19865a3463f75ca0d3a1d096350 @@ -148,7 +148,7 @@ https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxi-1.8.2-h57736b2_0 https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxrandr-1.5.5-he30d5cf_0.conda#1f64c613f0b8d67e9fb0e165d898fb6b https://conda.anaconda.org/conda-forge/linux-aarch64/xorg-libxxf86vm-1.1.7-he30d5cf_0.conda#b15ca02584678f38df6e114c32f93959 https://conda.anaconda.org/conda-forge/linux-aarch64/harfbuzz-14.2.0-h1134a53_0.conda#1775defbef30aa990498e753a948cb18 -https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.4-default_h94a09a5_0.conda#e15885f06e02c0d6b7e1fc3bc8a97efb +https://conda.anaconda.org/conda-forge/linux-aarch64/libclang13-22.1.5-default_h94a09a5_0.conda#40c3f0e6e00f8e296f20237902034865 https://conda.anaconda.org/conda-forge/linux-aarch64/libgl-devel-1.7.0-hd24410f_2.conda#5d8323dff6a93596fb6f985cf6e8521a https://conda.anaconda.org/conda-forge/linux-aarch64/liblapacke-3.11.0-6_hb558247_openblas.conda#12da32239ec4cc63d4f94d83b8425947 https://conda.anaconda.org/conda-forge/linux-aarch64/libpq-18.3-h7d4fc67_0.conda#7eb18b198b1d35da9352062c69c4ee64 diff --git a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock index d491bd3fd99bb..c157438e9ed8c 100644 --- a/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_min_dependencies_linux-64_conda.lock @@ -12,14 +12,14 @@ https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda#a7970cd949a077b7cb9696379d338681 https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda#434ca7e50e40f4918ab701e3facd59a0 https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec -https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.4-h4922eb0_0.conda#fa2c5c7f8d5319ab9c9fcbbd04022abf +https://conda.anaconda.org/conda-forge/linux-64/llvm-openmp-22.1.5-h4922eb0_1.conda#f66101d2eb5de2924c10a63bbfa2926e https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-7_kmp_llvm.conda#887b70e1d607fba7957aa02f9ee0d939 https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda#c151d5eb730e9b7480e6d48c0fc44048 https://conda.anaconda.org/conda-forge/linux-64/libopengl-1.7.0-ha4b6fd6_2.conda#7df50d44d4a14d6c31a2c54f2cd92157 https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda#57736f29cc2b0ec0b6c2952d3f101b6a https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.15.3-hb03c661_0.conda#dcdc58c15961dbf17a0621312b01f5cb https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda#920bb03579f15389b9e512095ad995b7 @@ -30,8 +30,8 @@ https://conda.anaconda.org/conda-forge/linux-64/libcap-2.77-hd0affe5_1.conda#499 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda#331ee9b72b9dff570d56b1302c5ab37d +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda#85072b0ad177c966294f129b7c04a2d5 https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda#915f5995e94f60e9a4826e0b0920ee88 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb @@ -43,7 +43,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libopus-1.6.1-h280c20c_0.conda#2 https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda#70e3400cbbfa03e96dcde7fc13e38c7b https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda#5794b3bdc38177caf969dabd3af08549 https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-hf23e847_1.conda#b1aa0faa95017bca11369bd080487ec4 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 @@ -70,10 +70,10 @@ https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda#172b https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda#a1cfcc585f0c42bf8d5546bb1dfb668d https://conda.anaconda.org/conda-forge/linux-64/libflac-1.5.0-he200343_1.conda#47595b9d53054907a00d95e4d47af1d6 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda#42bf7eca1a951735fa06c0e3c0d5c8e6 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda#eecce068c7e4eddeb169591baac20ac4 -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda#6235adb93d064ecdf3d44faee6f468de +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_19.conda#e5ce228e579726c07255dbf90dc62101 https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-257.13-hd0affe5_0.conda#8ee3cb7f64be0e8c4787f3a4dbe024e6 https://conda.anaconda.org/conda-forge/linux-64/libudev1-257.13-hd0affe5_0.conda#2c2270f93d6f9073cbf72d821dfc7d72 https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda#b4ecbefe517ed0157c37f8182768271c @@ -100,7 +100,7 @@ https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda#fb5 https://conda.anaconda.org/conda-forge/linux-64/libabseil-20240116.2-cxx17_he02047a_1.conda#c48fc56ec03229f294176923c3265c05 https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2#c965a5aa0d5c1c37ffc62dff36e28400 https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda#e289f3d17880e44b633ba911d57a321b -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_18.conda#26d7b228de99d6fb032ba4d5c1679040 +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-15.2.0-h69a702a_19.conda#35d07243abf828674d273aecd1dd537e https://conda.anaconda.org/conda-forge/linux-64/libglib-2.88.1-h0d30a3d_1.conda#6016ea5ee9e986bc683879408cc87529 https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda#2a45e7f8af083626f009645a6481f12d https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc7d488a_2.conda#067590f061c9f6ea7e61e3b2112ed6b3 @@ -110,7 +110,7 @@ https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.3-hca6bf5a_0.con https://conda.anaconda.org/conda-forge/linux-64/lz4-c-1.9.4-hcb278e6_0.conda#318b08df404f9c9be5712aaa5a6f0bb0 https://conda.anaconda.org/conda-forge/linux-64/nss-3.118-h445c969_0.conda#567fbeed956c200c1db5782a424e58ee https://conda.anaconda.org/conda-forge/linux-64/python-3.11.15-hd63d673_0_cpython.conda#a5ebcefec0c12a333bcd6d7bf3bddc1f -https://conda.anaconda.org/conda-forge/linux-64/rdma-core-61.0-h192683f_0.conda#d487d93d170e332ab39803e05912a762 +https://conda.anaconda.org/conda-forge/linux-64/rdma-core-62.0-h192683f_0.conda#46a9d3342a5945cf6067f9277989900c https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.1-h4f16b4b_2.conda#fdc27cb255a7a2cc73b7919a968b48f0 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.1-hb711507_0.conda#ad748ccca349aec3e91743e08b5e2b50 https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.10-hb711507_0.conda#0e0cbe0564d03a99afd5fd7b362feecd @@ -135,7 +135,7 @@ https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.5.0-py311h724c32c_0.conda#3d82751e8d682068b58f049edc924ce4 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19.1-h0c24ade_0.conda#f92f984b558e6e6204014b16d212b271 https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda#49c553b47ff679a6a1e9fc80b9c5a2d4 https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.20.0-hcf29cc6_0.conda#c3cc2864f82a944bc90a7beb4d3b0e88 https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda#c8013e438185f33b13814c5c488acd5c @@ -173,7 +173,7 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.4.2-h767128 https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.8.2-he17ee6b_6.conda#4e3d1bb2ade85619ac2163e695c2cc1b https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda#bb6c4808bfa69d6f7f6b07e5846ced37 https://conda.anaconda.org/conda-forge/linux-64/cffi-2.0.0-py311h03d9500_1.conda#3912e4373de46adafd8f1e97e4bd166b -https://conda.anaconda.org/conda-forge/linux-64/coverage-7.13.5-py311h3778330_0.conda#e32c4e7639b1c1b5680fabdaa6081e56 +https://conda.anaconda.org/conda-forge/linux-64/coverage-7.14.0-py311h3778330_0.conda#f566275adc487ec7b8dfaf9257967fcf https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.62.1-py311h3778330_0.conda#dd214022a8f01bc2ebed383dfdc8deea https://conda.anaconda.org/conda-forge/linux-64/glib-2.88.1-h435ced3_1.conda#7d844a122c6cf1d8d2fb024f85757225 @@ -181,7 +181,7 @@ https://conda.anaconda.org/conda-forge/noarch/h2-4.3.0-pyhcf101f3_0.conda#164fc4 https://conda.anaconda.org/conda-forge/noarch/joblib-1.3.0-pyhd8ed1ab_1.conda#fb4caf6da228ccc487350eade569abae https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-20_linux64_openblas.conda#2b7bb4f7562c8cf334fc2e20c2d28abc https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda#928b8be80851f5d8ffb016f9c81dae7a -https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.4-hf7376ad_0.conda#80a690c83cba58ba483b90a07e59e721 +https://conda.anaconda.org/conda-forge/linux-64/libllvm22-22.1.5-hf7376ad_1.conda#6adc0202fa7fcf0a5fce8c31ef2ed866 https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda#2bca1fbb221d9c3c8e3a155784bbc2e9 https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.25-pthreads_h7a3da1a_0.conda#87661673941b5e702275fdf0fc095ad0 https://conda.anaconda.org/conda-forge/linux-64/openldap-2.6.13-hbde042b_0.conda#680608784722880fbfe1745067570b00 @@ -201,8 +201,8 @@ https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.10.4-hcd6a914_8.con https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.26.11-h29cf534_0.conda#1e0e854b77451ac918b4a68f28932b1d https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-14.2.0-h6083320_0.conda#e194f6a2f498f0c7b1e6498bd0b12645 https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-20_linux64_openblas.conda#36d486d72ab64ffea932329a1d3729a3 -https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.4-default_h99862b1_0.conda#fe7972688e6e3dd9b97d1fcce2d88235 -https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.4-default_h746c552_0.conda#1a39f14c89cf0a54aee5ef6f679f1030 +https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp22.1-22.1.5-default_h99862b1_0.conda#eb9e3f61562dcf3a5d313e45cf7b0dd6 +https://conda.anaconda.org/conda-forge/linux-64/libclang13-22.1.5-default_h746c552_0.conda#c3df118cdc65584a78028bf225111b1b https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.62.2-h15f2491_0.conda#8dabe607748cb3d7002ad73cd06f1325 https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-20_linux64_openblas.conda#6fabc51f5e647d09cc010c40061557e0 https://conda.anaconda.org/conda-forge/linux-64/libpq-18.3-h9abb657_0.conda#405ec206d230d9d37ad7c2636114cbf4 diff --git a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock index de20b0e719bfd..b3cd980aa1325 100644 --- a/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_ubuntu_2204_linux-64_conda.lock @@ -5,24 +5,24 @@ https://conda.anaconda.org/conda-forge/noarch/python_abi-3.11-8_cp311.conda#8fcb6b0e2161850556231336dae58358 https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda#ad659d0a2b3e47e38d829aa8cad2d610 https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.4.22-hbd8a1cb_0.conda#e18ad67cf881dcadee8b8d9e2f8e5f73 -https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda#239c5e9546c38a1e884d69effcf4c882 +https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda#faac990cb7aedc7f3a2224f2c9b0c26c https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda#d87ff7921124eccd67248aa483c23fec https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda#a9f577daf3de00bca7c3c76c0ecbd1de https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda#4a13eeac0b5c8e5b8ab496e6c4ddd829 https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda#18335a698559cdbcd86150a48bf54ba6 -https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda#0aa00f03f9e39fb9876085dee11a85d4 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda#57736f29cc2b0ec0b6c2952d3f101b6a https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda#d2ffd7602c02f2b316fd921d39876885 https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda#6c77a605a7a689d17d4819c0f8ac9a00 https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.0-hecca717_0.conda#a3b390520c563d78cc58974de95a03e5 https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda#a360c33a5abe61c07959e449fa1453eb -https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda#d5e96b1ed75ca01906b3d2469b4ce493 -https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda#646855f357199a12f02a87382d429b75 +https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_19.conda#331ee9b72b9dff570d56b1302c5ab37d +https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_19.conda#85072b0ad177c966294f129b7c04a2d5 https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.4.1-hb03c661_0.conda#6178c6f2fb254558238ef4e6c56fb782 https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda#b88d90cad08e6bc8ad540cb310a761fb https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hb9d3cd8_1.conda#d864d34357c3b65a4b731f78c0801dc4 https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.58-h421ea60_0.conda#eba48a68a1a2b9d3c0d9511548db85db https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.1-h0c1763c_0.conda#7dc38adcbf71e6b38748e919e16e0dce -https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda#1b08cd684f34175e4514474793d44bcb +https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda#5794b3bdc38177caf969dabd3af08549 https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42-h5347b49_0.conda#38ffe67b78c9d4de527be8315e5ada2c https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda#aea31d2e5b1091feca96fcfe945c3cf9 https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda#fc21868a1a5aacc937e7a18747acb8a5 @@ -34,7 +34,7 @@ https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.c https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda#607e13a8caac17f9a664bcab5302ce06 https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda#a752488c68f2e7c456bcbd8f16eec275 https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda#fb16b4b69e3f1dcfe79d80db8fd0c55d -https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda#9063115da5bc35fdc3e1002e69b9ef6e +https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_19.conda#42bf7eca1a951735fa06c0e3c0d5c8e6 https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda#aa342fcf3bc583660dbfdb2eae6be48e https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda#92ed62436b625154323d40d5f2f11dd7 https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda#5aa797f8787fe7a17d1b0821485b5adc @@ -61,11 +61,11 @@ https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.1.0-pyhd8ed1ab_0.cond https://conda.anaconda.org/conda-forge/noarch/idna-3.13-pyhcf101f3_0.conda#fb7130c190f9b4ec91219840a05ba3ac https://conda.anaconda.org/conda-forge/noarch/imagesize-2.0.0-pyhd8ed1ab_0.conda#92617c2ba2847cca7a6ed813b6f4ab79 https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 -https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19-h0c24ade_0.conda#f302dbf397ac82eaf9618575d0b5fe33 +https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.19.1-h0c24ade_0.conda#f92f984b558e6e6204014b16d212b271 https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda#6d6d225559bfa6e2f3c90ee9c03d4e2e https://conda.anaconda.org/conda-forge/linux-64/markupsafe-3.0.3-py311h3778330_1.conda#f9efdf9b0f3d0cc309d56af6edf2a6b0 https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.0-pyhcf101f3_0.conda#d2ec42db1d2fcd69003c8b069fb4301c https://conda.anaconda.org/conda-forge/linux-64/openblas-0.3.32-pthreads_h6ec200e_0.conda#2e9cf6ff9a29b98a4faf627f2eb2cdb7 https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.4-h55fea9a_0.conda#11b3379b191f63139e29c0d19dee24cd https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 @@ -95,7 +95,7 @@ https://conda.anaconda.org/conda-forge/noarch/meson-python-0.19.0-pyh7e86bf3_2.c https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py311h2e04523_0.conda#cfc8f864dea571677095ebae8e6f0c07 https://conda.anaconda.org/conda-forge/noarch/pip-26.1.1-pyh8b19718_0.conda#35870d32aed92041d31cbb15e822dca3 https://conda.anaconda.org/conda-forge/noarch/pytest-9.0.3-pyhc364b38_1.conda#6a991452eadf2771952f39d43615bb3e -https://conda.anaconda.org/conda-forge/noarch/urllib3-2.6.3-pyhd8ed1ab_0.conda#9272daa869e03efe68833e3dc7a02130 +https://conda.anaconda.org/conda-forge/noarch/urllib3-2.7.0-pyhd8ed1ab_0.conda#cbb88288f74dbe6ada1c6c7d0a97223e https://conda.anaconda.org/conda-forge/linux-64/blas-devel-3.11.0-6_h1ea3ea9_openblas.conda#064f82e2cd0146b28a0bda3ca9b6fb7e https://conda.anaconda.org/conda-forge/linux-64/pandas-3.0.2-py311h8032f78_0.conda#138e5d98884407fcc8ccc6088574b1c7 https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.8.0-pyhd8ed1ab_0.conda#8375cfbda7c57fbceeda18229be10417 diff --git a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock index b47e814a5bea5..8f0ee4e66e505 100644 --- a/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock +++ b/build_tools/github/pymin_conda_forge_openblas_win-64_conda.lock @@ -14,7 +14,7 @@ https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.con https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda#8a86073cf3b343b87d03f41790d8b4e5 https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda#242d9f25d2ae60c76b38a5e42858e51d https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2#fee5683a3f04bd15cbd8318b096a27ab -https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_18.conda#939fb173e2a4d4e980ef689e99b35223 +https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_19.conda#f1147651e3fdd585e2f442c0c2fc8f2d https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda#37eb311485d2d8b2c419449582046a42 https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda#1626967b574d1784b578b52eaeb071e7 https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda#1e610f2416b6acdd231c5f573d754a0f @@ -27,7 +27,7 @@ https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.2.0-hfd05255_1.c https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda#e77030e67343e28b084fabd7db0ce43e https://conda.anaconda.org/conda-forge/win-64/libexpat-2.8.0-hac47afa_0.conda#264e350e035092b5135a2147c238aec4 https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda#720b39f5ec0610457b725eb3f396219a -https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda#b085746891cca3bd2704a450a7b4b5ce +https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_19.conda#cc5d690fc1c629038f13c68e88e65f44 https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda#64571d1dd6cdcfa25d0664a5950fdaa2 https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.4.1-hfd05255_0.conda#25a127bad5470852b30b239f030ec95b https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.3-hfd05255_0.conda#8f83619ab1588b98dd99c90b0bfc5c6d @@ -64,7 +64,7 @@ https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.2-pyhd8ed1ab_0.conda#a https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.3.0-pyhd8ed1ab_0.conda#9614359868482abba1bd15ce465e3c42 https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.5.0-py311h275cad7_0.conda#e50d15677f2673c114f18d60c88d9196 https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-6_h2a8eebe_openblas.conda#56ab25cf3cbce9e3a809e3e89739b5a8 -https://conda.anaconda.org/conda-forge/win-64/libclang13-22.1.4-default_ha2db4b5_0.conda#8759fc24d708cc4af95af5d86f5441d1 +https://conda.anaconda.org/conda-forge/win-64/libclang13-22.1.5-default_ha2db4b5_0.conda#74229a56cbbfda28f75bed42ac5cacc7 https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_0.conda#f9975a0177ee6cdda10c86d1db1186b0 https://conda.anaconda.org/conda-forge/win-64/libglib-2.88.1-h7ce1215_1.conda#574ba3f468b639cfaf65c0f2b04d8e9d https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-6_hd232482_openblas.conda#06d2ad5bf21e9b86c46783833b2e3c42 @@ -73,7 +73,7 @@ https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda#a69 https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.3-h8ef44ab_0.conda#95591ca5671d2213f5b2d5aa7818420d https://conda.anaconda.org/conda-forge/noarch/meson-1.11.1-pyhcf101f3_0.conda#ced6358cc61d7e381e68fc128f7b63db https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyhd8ed1ab_1.conda#37293a85a0f4f77bbd9cf7aaefc62609 -https://conda.anaconda.org/conda-forge/noarch/narwhals-2.20.0-pyhcf101f3_0.conda#6cac1a50359219d786453c6fef819f98 +https://conda.anaconda.org/conda-forge/noarch/narwhals-2.21.0-pyhcf101f3_0.conda#d2ec42db1d2fcd69003c8b069fb4301c https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda#4c06a92e74452cfa53623a81592e8934 https://conda.anaconda.org/conda-forge/noarch/pluggy-1.6.0-pyhf9edf01_1.conda#d7585b6550ad04c8c5e21097ada2888e https://conda.anaconda.org/conda-forge/noarch/pygments-2.20.0-pyhd8ed1ab_0.conda#16c18772b340887160c79a6acc022db0 @@ -87,10 +87,10 @@ https://conda.anaconda.org/conda-forge/win-64/tornado-6.5.5-py311h3485c13_0.cond https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.15.0-pyhcf101f3_0.conda#0caa1af407ecff61170c9437a808404d https://conda.anaconda.org/conda-forge/win-64/unicodedata2-17.0.1-py311h3485c13_0.conda#e6badeb53d9bc5cccebe46a62c5a7336 https://conda.anaconda.org/conda-forge/win-64/brotli-1.2.0-h2d644bc_1.conda#bc58fdbced45bb096364de0fba1637af -https://conda.anaconda.org/conda-forge/win-64/coverage-7.13.5-py311h3f79411_0.conda#32eaff69a4a2426c01748784090a5e76 +https://conda.anaconda.org/conda-forge/win-64/coverage-7.14.0-py311h3f79411_0.conda#219ec381b22d8fae397333ef23f4ac79 https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.3.1-pyhd8ed1ab_0.conda#8e662bd460bda79b1ea39194e3c4c9ab https://conda.anaconda.org/conda-forge/noarch/joblib-1.5.3-pyhd8ed1ab_0.conda#615de2a4d97af50c350e5cf160149e77 -https://conda.anaconda.org/conda-forge/win-64/lcms2-2.19-hf2c6c5f_0.conda#cc37ca38374ac2a5dbe11f9abb10110f +https://conda.anaconda.org/conda-forge/win-64/lcms2-2.19.1-hf2c6c5f_0.conda#29f2c366a0da954bafd69a0d549c0ab3 https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_0.conda#d9f70dd06674e26b6d5a657ddd22b568 https://conda.anaconda.org/conda-forge/win-64/liblapacke-3.11.0-6_hbb0e6ff_openblas.conda#7111f949f68a554498655d268b5fa7a5 https://conda.anaconda.org/conda-forge/win-64/libxslt-1.1.43-h0fbe4c1_1.conda#46034d9d983edc21e84c0b36f1b4ba61 From 13f20d7d95f78f4d45e40ebb018810c6ae1a4de1 Mon Sep 17 00:00:00 2001 From: Arthur Lacote <arthur.lcte@gmail.com> Date: Mon, 11 May 2026 14:22:29 +0200 Subject: [PATCH 456/462] MNT move sorting functions from `tree/` to `utils/_sorting.pyx` (#33979) --- sklearn/tree/_criterion.pyx | 2 +- sklearn/tree/_partitioner.pxd | 5 -- sklearn/tree/_partitioner.pyx | 116 +------------------------ sklearn/tree/tests/test_tree.py | 23 ----- sklearn/utils/_sorting.pxd | 6 ++ sklearn/utils/_sorting.pyx | 126 ++++++++++++++++++++++++++-- sklearn/utils/tests/test_sorting.py | 28 +++++++ 7 files changed, 156 insertions(+), 150 deletions(-) create mode 100644 sklearn/utils/tests/test_sorting.py diff --git a/sklearn/tree/_criterion.pyx b/sklearn/tree/_criterion.pyx index 8c0da50ad3260..46a9b57d362d1 100644 --- a/sklearn/tree/_criterion.pyx +++ b/sklearn/tree/_criterion.pyx @@ -13,7 +13,7 @@ from scipy.special.cython_special cimport xlogy from sklearn.tree._utils cimport log from sklearn.tree._utils cimport WeightedFenwickTree -from sklearn.tree._partitioner cimport sort +from sklearn.utils._sorting cimport sort # EPSILON is used in the Poisson criterion cdef float64_t EPSILON = 10 * np.finfo('double').eps diff --git a/sklearn/tree/_partitioner.pxd b/sklearn/tree/_partitioner.pxd index 75f4e683d99dc..d36ffc799c4d8 100644 --- a/sklearn/tree/_partitioner.pxd +++ b/sklearn/tree/_partitioner.pxd @@ -3,8 +3,6 @@ # See _partitioner.pyx for details. -from cython cimport floating - from sklearn.utils._typedefs cimport ( float32_t, float64_t, int32_t, intp_t, uint8_t ) @@ -171,9 +169,6 @@ cdef class SparsePartitioner: ) noexcept nogil -cdef void sort(floating* feature_values, intp_t* samples, intp_t n) noexcept nogil - - ctypedef fused array_data_type: intp_t float32_t diff --git a/sklearn/tree/_partitioner.pyx b/sklearn/tree/_partitioner.pyx index 00719348696c7..4a81d06cb03c0 100644 --- a/sklearn/tree/_partitioner.pyx +++ b/sklearn/tree/_partitioner.pyx @@ -21,6 +21,7 @@ cnp.import_array() from scipy.sparse import issparse from sklearn.tree._splitter cimport SplitRecord +from sklearn.utils._sorting cimport sort # Constant to switch between algorithm non zero value extract algorithm # in SparsePartitioner @@ -694,125 +695,12 @@ cdef inline void sparse_swap(intp_t[::1] index_to_samples, intp_t[::1] samples, index_to_samples[samples[pos_2]] = pos_2 -def _py_sort(float32_t[::1] feature_values, intp_t[::1] samples, intp_t n): - """Used for testing sort.""" - sort(&feature_values[0], &samples[0], n) - - -# Sort n-element arrays pointed to by feature_values and samples, simultaneously, -# by the values in feature_values. Algorithm: Introsort (Musser, SP&E, 1997). -cdef void sort(floating* feature_values, intp_t* samples, intp_t n) noexcept nogil: - if n == 0: - return - cdef intp_t maxd = 2 * <intp_t>log2(n) - introsort(feature_values, samples, n, maxd) - - -cdef inline void swap(floating* feature_values, intp_t* samples, +cdef inline void swap(float32_t* feature_values, intp_t* samples, intp_t i, intp_t j) noexcept nogil: - # Helper for sort feature_values[i], feature_values[j] = feature_values[j], feature_values[i] samples[i], samples[j] = samples[j], samples[i] -cdef inline floating median3(floating* feature_values, intp_t n) noexcept nogil: - # Median of three pivot selection, after Bentley and McIlroy (1993). - # Engineering a sort function. SP&E. Requires 8/3 comparisons on average. - cdef floating a = feature_values[0], b = feature_values[n / 2], c = feature_values[n - 1] - if a < b: - if b < c: - return b - elif a < c: - return c - else: - return a - elif b < c: - if a < c: - return a - else: - return c - else: - return b - - -# Introsort with median of 3 pivot selection and 3-way partition function -# (robust to repeated elements, e.g. lots of zero features). -cdef void introsort(floating* feature_values, intp_t *samples, - intp_t n, intp_t maxd) noexcept nogil: - cdef floating pivot - cdef intp_t i, l, r - - while n > 1: - if maxd <= 0: # max depth limit exceeded ("gone quadratic") - heapsort(feature_values, samples, n) - return - maxd -= 1 - - pivot = median3(feature_values, n) - - # Three-way partition. - i = l = 0 - r = n - while i < r: - if feature_values[i] < pivot: - swap(feature_values, samples, i, l) - i += 1 - l += 1 - elif feature_values[i] > pivot: - r -= 1 - swap(feature_values, samples, i, r) - else: - i += 1 - - introsort(feature_values, samples, l, maxd) - feature_values += r - samples += r - n -= r - - -cdef inline void sift_down(floating* feature_values, intp_t* samples, - intp_t start, intp_t end) noexcept nogil: - # Restore heap order in feature_values[start:end] by moving the max element to start. - cdef intp_t child, maxind, root - - root = start - while True: - child = root * 2 + 1 - - # find max of root, left child, right child - maxind = root - if child < end and feature_values[maxind] < feature_values[child]: - maxind = child - if child + 1 < end and feature_values[maxind] < feature_values[child + 1]: - maxind = child + 1 - - if maxind == root: - break - else: - swap(feature_values, samples, root, maxind) - root = maxind - - -cdef void heapsort(floating* feature_values, intp_t* samples, intp_t n) noexcept nogil: - cdef intp_t start, end - - # heapify - start = (n - 2) / 2 - end = n - while True: - sift_down(feature_values, samples, start, end) - if start == 0: - break - start -= 1 - - # sort by shrinking the heap, putting the max element immediately after it - end = n - 1 - while end > 0: - swap(feature_values, samples, 0, end) - sift_down(feature_values, samples, 0, end) - end = end - 1 - - cdef void swap_array_slices( array_data_type[::1] array, intp_t start, intp_t end, intp_t n, char[::1] buffer diff --git a/sklearn/tree/tests/test_tree.py b/sklearn/tree/tests/test_tree.py index f132c795dbfaf..b2086f3a6bdcf 100644 --- a/sklearn/tree/tests/test_tree.py +++ b/sklearn/tree/tests/test_tree.py @@ -42,7 +42,6 @@ SPARSE_SPLITTERS, ) from sklearn.tree._criterion import _py_precompute_absolute_errors -from sklearn.tree._partitioner import _py_sort from sklearn.tree._tree import ( NODE_DTYPE, TREE_LEAF, @@ -2909,28 +2908,6 @@ def test_build_pruned_tree_infinite_loop(): _build_pruned_tree_py(pruned_tree, tree.tree_, leave_in_subtree) -def test_sort_log2_build(): - """Non-regression test for gh-30554. - - Using log2 and log in sort correctly sorts feature_values, but the tie breaking is - different which can results in placing samples in a different order. - """ - rng = np.random.default_rng(75) - some = rng.normal(loc=0.0, scale=10.0, size=10).astype(np.float32) - feature_values = np.concatenate([some] * 5) - samples = np.arange(50, dtype=np.intp) - _py_sort(feature_values, samples, 50) - # fmt: off - # no black reformatting for this specific array - expected_samples = [ - 0, 40, 30, 20, 10, 29, 39, 19, 49, 9, 45, 15, 35, 5, 25, 11, 31, - 41, 1, 21, 22, 12, 2, 42, 32, 23, 13, 43, 3, 33, 6, 36, 46, 16, - 26, 4, 14, 24, 34, 44, 27, 47, 7, 37, 17, 8, 38, 48, 28, 18 - ] - # fmt: on - assert_array_equal(samples, expected_samples) - - def test_absolute_errors_precomputation_function(global_random_seed): """ Test the main bit of logic of the MAE(RegressionCriterion) class diff --git a/sklearn/utils/_sorting.pxd b/sklearn/utils/_sorting.pxd index 43b24dddad22f..377618236a52e 100644 --- a/sklearn/utils/_sorting.pxd +++ b/sklearn/utils/_sorting.pxd @@ -7,3 +7,9 @@ cdef int simultaneous_sort( intp_t *idx, intp_t size, ) noexcept nogil + +cdef void sort( + floating* feature_values, + intp_t* samples, + intp_t n, +) noexcept nogil diff --git a/sklearn/utils/_sorting.pyx b/sklearn/utils/_sorting.pyx index 13b2d872392b9..ad4d5751bfc1e 100644 --- a/sklearn/utils/_sorting.pyx +++ b/sklearn/utils/_sorting.pyx @@ -1,5 +1,10 @@ +from libc.math cimport log2 + from cython cimport floating +from sklearn.utils._typedefs cimport float32_t, intp_t + + cdef inline void dual_swap( floating* darr, intp_t *iarr, @@ -7,13 +12,8 @@ cdef inline void dual_swap( intp_t b, ) noexcept nogil: """Swap the values at index a and b of both darr and iarr""" - cdef floating dtmp = darr[a] - darr[a] = darr[b] - darr[b] = dtmp - - cdef intp_t itmp = iarr[a] - iarr[a] = iarr[b] - iarr[b] = itmp + darr[a], darr[b] = darr[b], darr[a] + iarr[a], iarr[b] = iarr[b], iarr[a] cdef int simultaneous_sort( @@ -91,3 +91,115 @@ cdef int simultaneous_sort( indices + pivot_idx + 1, size - pivot_idx - 1) return 0 + + +def _py_sort(float32_t[::1] feature_values, intp_t[::1] samples, intp_t n): + """Used for testing sort.""" + sort(&feature_values[0], &samples[0], n) + + +# Sort n-element arrays pointed to by feature_values and samples, simultaneously, +# by the values in feature_values. Algorithm: Introsort (Musser, SP&E, 1997). +cdef void sort(floating* feature_values, intp_t* samples, intp_t n) noexcept nogil: + if n == 0: + return + cdef intp_t maxd = 2 * <intp_t>log2(n) + introsort(feature_values, samples, n, maxd) + + +cdef inline floating median3(floating* feature_values, intp_t n) noexcept nogil: + # Median of three pivot selection, after Bentley and McIlroy (1993). + # Engineering a sort function. SP&E. Requires 8/3 comparisons on average. + cdef floating a = feature_values[0], b = feature_values[n / 2], c = feature_values[n - 1] + if a < b: + if b < c: + return b + elif a < c: + return c + else: + return a + elif b < c: + if a < c: + return a + else: + return c + else: + return b + + +# Introsort with median of 3 pivot selection and 3-way partition function +# (robust to repeated elements, e.g. lots of zero features). +cdef void introsort(floating* feature_values, intp_t *samples, + intp_t n, intp_t maxd) noexcept nogil: + cdef floating pivot + cdef intp_t i, l, r + + while n > 1: + if maxd <= 0: # max depth limit exceeded ("gone quadratic") + heapsort(feature_values, samples, n) + return + maxd -= 1 + + pivot = median3(feature_values, n) + + # Three-way partition. + i = l = 0 + r = n + while i < r: + if feature_values[i] < pivot: + dual_swap(feature_values, samples, i, l) + i += 1 + l += 1 + elif feature_values[i] > pivot: + r -= 1 + dual_swap(feature_values, samples, i, r) + else: + i += 1 + + introsort(feature_values, samples, l, maxd) + feature_values += r + samples += r + n -= r + + +cdef inline void sift_down(floating* feature_values, intp_t* samples, + intp_t start, intp_t end) noexcept nogil: + # Restore heap order in feature_values[start:end] by moving the max element to start. + cdef intp_t child, maxind, root + + root = start + while True: + child = root * 2 + 1 + + # find max of root, left child, right child + maxind = root + if child < end and feature_values[maxind] < feature_values[child]: + maxind = child + if child + 1 < end and feature_values[maxind] < feature_values[child + 1]: + maxind = child + 1 + + if maxind == root: + break + else: + dual_swap(feature_values, samples, root, maxind) + root = maxind + + +cdef void heapsort(floating* feature_values, intp_t* samples, intp_t n) noexcept nogil: + cdef intp_t start, end + + # heapify + start = (n - 2) / 2 + end = n + while True: + sift_down(feature_values, samples, start, end) + if start == 0: + break + start -= 1 + + # sort by shrinking the heap, putting the max element immediately after it + end = n - 1 + while end > 0: + dual_swap(feature_values, samples, 0, end) + sift_down(feature_values, samples, 0, end) + end = end - 1 diff --git a/sklearn/utils/tests/test_sorting.py b/sklearn/utils/tests/test_sorting.py new file mode 100644 index 0000000000000..080e92a407e49 --- /dev/null +++ b/sklearn/utils/tests/test_sorting.py @@ -0,0 +1,28 @@ +import numpy as np +from numpy.testing import assert_array_equal + +from sklearn.utils._sorting import _py_sort + + +def test_sort_log2_build(): + """Non-regression test for gh-30554. + + Using log2 and log in sort correctly sorts feature_values, but the tie breaking is + different which can results in placing samples in a different order. + """ + rng = np.random.default_rng(75) + some = rng.normal(loc=0.0, scale=10.0, size=10).astype(np.float32) + feature_values = np.concatenate([some] * 5) + samples = np.arange(50, dtype=np.intp) + + _py_sort(feature_values, samples, 50) + + # fmt: off + # no black reformatting for this specific array + expected_samples = [ + 0, 40, 30, 20, 10, 29, 39, 19, 49, 9, 45, 15, 35, 5, 25, 11, 31, + 41, 1, 21, 22, 12, 2, 42, 32, 23, 13, 43, 3, 33, 6, 36, 46, 16, + 26, 4, 14, 24, 34, 44, 27, 47, 7, 37, 17, 8, 38, 48, 28, 18 + ] + # fmt: on + assert_array_equal(samples, expected_samples) From f19574120630160eb600849073fcd2e8394a4f83 Mon Sep 17 00:00:00 2001 From: Arthur Lacote <arthur.lcte@gmail.com> Date: Mon, 11 May 2026 18:39:36 +0200 Subject: [PATCH 457/462] TST remove test enforcing unmotivated constraints on sort (#33983) --- sklearn/utils/tests/test_sorting.py | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 sklearn/utils/tests/test_sorting.py diff --git a/sklearn/utils/tests/test_sorting.py b/sklearn/utils/tests/test_sorting.py deleted file mode 100644 index 080e92a407e49..0000000000000 --- a/sklearn/utils/tests/test_sorting.py +++ /dev/null @@ -1,28 +0,0 @@ -import numpy as np -from numpy.testing import assert_array_equal - -from sklearn.utils._sorting import _py_sort - - -def test_sort_log2_build(): - """Non-regression test for gh-30554. - - Using log2 and log in sort correctly sorts feature_values, but the tie breaking is - different which can results in placing samples in a different order. - """ - rng = np.random.default_rng(75) - some = rng.normal(loc=0.0, scale=10.0, size=10).astype(np.float32) - feature_values = np.concatenate([some] * 5) - samples = np.arange(50, dtype=np.intp) - - _py_sort(feature_values, samples, 50) - - # fmt: off - # no black reformatting for this specific array - expected_samples = [ - 0, 40, 30, 20, 10, 29, 39, 19, 49, 9, 45, 15, 35, 5, 25, 11, 31, - 41, 1, 21, 22, 12, 2, 42, 32, 23, 13, 43, 3, 33, 6, 36, 46, 16, - 26, 4, 14, 24, 34, 44, 27, 47, 7, 37, 17, 8, 38, 48, 28, 18 - ] - # fmt: on - assert_array_equal(samples, expected_samples) From 8943d1246d7da8636fbd79511bdfd1d5952967f8 Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Mon, 11 May 2026 22:13:03 +0200 Subject: [PATCH 458/462] MNT move test on pandas sparse dataframe to validation - where it belongs (#33964) --- sklearn/linear_model/tests/test_base.py | 30 ------------------------- sklearn/utils/tests/test_validation.py | 26 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/sklearn/linear_model/tests/test_base.py b/sklearn/linear_model/tests/test_base.py index 0679c4debc009..88962f69b2380 100644 --- a/sklearn/linear_model/tests/test_base.py +++ b/sklearn/linear_model/tests/test_base.py @@ -1,8 +1,6 @@ # Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause -import warnings - import numpy as np import pytest from scipy import linalg, sparse @@ -371,34 +369,6 @@ def test_inplace_data_preprocessing(sparse_container, use_sw, global_random_seed assert_allclose(sample_weight, original_sw_data) -def test_linear_regression_pd_sparse_dataframe_warning(): - pd = pytest.importorskip("pandas") - - # Warning is raised only when some of the columns is sparse - df = pd.DataFrame({"0": np.random.randn(10)}) - for col in range(1, 4): - arr = np.random.randn(10) - arr[:8] = 0 - # all columns but the first column is sparse - if col != 0: - arr = pd.arrays.SparseArray(arr, fill_value=0) - df[str(col)] = arr - - msg = "pandas.DataFrame with sparse columns found." - - reg = LinearRegression() - with pytest.warns(UserWarning, match=msg): - reg.fit(df.iloc[:, 0:2], df.iloc[:, 3]) - - # does not warn when the whole dataframe is sparse - df["0"] = pd.arrays.SparseArray(df["0"], fill_value=0) - assert hasattr(df, "sparse") - - with warnings.catch_warnings(): - warnings.simplefilter("error", UserWarning) - reg.fit(df.iloc[:, 0:2], df.iloc[:, 3]) - - def test_preprocess_data(global_random_seed): rng = np.random.RandomState(global_random_seed) n_samples = 200 diff --git a/sklearn/utils/tests/test_validation.py b/sklearn/utils/tests/test_validation.py index 9553c94f80912..f74b0baa2eaab 100644 --- a/sklearn/utils/tests/test_validation.py +++ b/sklearn/utils/tests/test_validation.py @@ -1922,6 +1922,32 @@ def test_check_sparse_pandas_sp_format(sp_format): assert_allclose_dense_sparse(sp_mat, result) +def test_check_array_pd_sparse_dataframe_warning(): + """Test that check_array warns on pandas dataframe with sparse columns.""" + pd = pytest.importorskip("pandas") + + # Warning is raised only when some of the columns are sparse, not all of them. + # Construct a pandas.DataFrame with first column dense, all others sparse. + df = pd.DataFrame({"col_0": np.linspace(0, 1, 10)}) + for i in range(1, 4): + arr = np.zeros(10) + arr[:4] = np.arange(4) + arr = pd.arrays.SparseArray(arr, fill_value=0) + df[f"col_{i}"] = arr + + msg = "pandas.DataFrame with sparse columns found." + with pytest.warns(UserWarning, match=msg): + check_array(df, accept_sparse=True) + + # No warning when the whole dataframe is sparse + df = df.drop(columns="col_0") + assert hasattr(df, "sparse") + + with warnings.catch_warnings(): + warnings.simplefilter("error", UserWarning) + check_array(df, accept_sparse=True) + + @pytest.mark.parametrize( "ntype1, ntype2", [ From c70963a21c88c8ece6c8feae8086110ca420fe5c Mon Sep 17 00:00:00 2001 From: Christian Lorentzen <lorentzen.ch@gmail.com> Date: Tue, 12 May 2026 02:15:00 +0200 Subject: [PATCH 459/462] MNT remove tree DOUBLE and DTYPE (#33948) --- sklearn/ensemble/_forest.py | 13 ++++++------- sklearn/ensemble/_gb.py | 16 ++++++++-------- sklearn/ensemble/_iforest.py | 5 ++--- sklearn/tree/_classes.py | 19 ++++++++----------- sklearn/tree/_tree.pyx | 21 +++++++++------------ sklearn/tree/tests/test_tree.py | 14 +++++++------- 6 files changed, 40 insertions(+), 48 deletions(-) diff --git a/sklearn/ensemble/_forest.py b/sklearn/ensemble/_forest.py index 1be148428e0f0..28b9d0cbdf63f 100644 --- a/sklearn/ensemble/_forest.py +++ b/sklearn/ensemble/_forest.py @@ -64,7 +64,6 @@ class calls the ``fit`` method of each sub-estimator on random samples ExtraTreeClassifier, ExtraTreeRegressor, ) -from sklearn.tree._tree import DOUBLE, DTYPE from sklearn.utils import ( check_random_state, compute_class_weight, @@ -338,7 +337,7 @@ def fit(self, X, y, sample_weight=None): y, multi_output=True, accept_sparse="csc", - dtype=DTYPE, + dtype=np.float32, ensure_all_finite=False, ) # _compute_missing_values_in_feature_mask checks if X has missing values and @@ -393,8 +392,8 @@ def fit(self, X, y, sample_weight=None): y, expanded_class_weight = self._validate_y_class_weight(y, sample_weight) - if getattr(y, "dtype", None) != DOUBLE or not y.flags.contiguous: - y = np.ascontiguousarray(y, dtype=DOUBLE) + if getattr(y, "dtype", None) != np.float64 or not y.flags.contiguous: + y = np.ascontiguousarray(y, dtype=np.float64) # Combined _sample_weight = sample_weight * expanded_class_weight # (when provided) used in _parallel_build_trees to draw indices @@ -616,7 +615,7 @@ def _validate_X_predict(self, X): X = validate_data( self, X, - dtype=DTYPE, + dtype=np.float32, accept_sparse="csr", reset=False, ensure_all_finite=ensure_all_finite, @@ -1137,7 +1136,7 @@ def _compute_partial_dependence_recursion(self, grid, target_features): Parameters ---------- - grid : ndarray of shape (n_samples, n_target_features), dtype=DTYPE + grid : ndarray of shape (n_samples, n_target_features), dtype=np.float32 The grid points on which the partial dependence should be evaluated. target_features : ndarray of shape (n_target_features), dtype=np.intp @@ -1149,7 +1148,7 @@ def _compute_partial_dependence_recursion(self, grid, target_features): averaged_predictions : ndarray of shape (n_samples,) The value of the partial dependence function on each grid point. """ - grid = np.asarray(grid, dtype=DTYPE, order="C") + grid = np.asarray(grid, dtype=np.float32, order="C") target_features = np.asarray(target_features, dtype=np.intp, order="C") averaged_predictions = np.zeros( shape=grid.shape[0], dtype=np.float64, order="C" diff --git a/sklearn/ensemble/_gb.py b/sklearn/ensemble/_gb.py index 0ab11c3dd7d32..9ac0dad723f32 100644 --- a/sklearn/ensemble/_gb.py +++ b/sklearn/ensemble/_gb.py @@ -50,7 +50,7 @@ from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder from sklearn.tree import DecisionTreeRegressor -from sklearn.tree._tree import DOUBLE, DTYPE, TREE_LEAF +from sklearn.tree._tree import TREE_LEAF from sklearn.utils import check_array, check_random_state, column_or_1d from sklearn.utils._param_validation import HasMethods, Hidden, Interval, StrOptions from sklearn.utils.multiclass import check_classification_targets @@ -679,7 +679,7 @@ def fit(self, X, y, sample_weight=None, monitor=None): X, y, accept_sparse=["csr", "csc", "coo"], - dtype=DTYPE, + dtype=np.float32, multi_output=True, ) sample_weight_is_none = sample_weight is None @@ -794,7 +794,7 @@ def fit(self, X, y, sample_weight=None, monitor=None): # matrices. Finite values have already been checked in _validate_data. X_train = check_array( X_train, - dtype=DTYPE, + dtype=np.float32, order="C", accept_sparse="csr", ensure_all_finite=False, @@ -1011,7 +1011,7 @@ def _staged_raw_predict(self, X, check_input=True): """ if check_input: X = validate_data( - self, X, dtype=DTYPE, order="C", accept_sparse="csr", reset=False + self, X, dtype=np.float32, order="C", accept_sparse="csr", reset=False ) raw_predictions = self._raw_predict_init(X) for i in range(self.estimators_.shape[0]): @@ -1084,7 +1084,7 @@ def _compute_partial_dependence_recursion(self, grid, target_features): "Got init=%s." % self.init, UserWarning, ) - grid = np.asarray(grid, dtype=DTYPE, order="C") + grid = np.asarray(grid, dtype=np.float32, order="C") n_estimators, n_trees_per_stage = self.estimators_.shape averaged_predictions = np.zeros( (n_trees_per_stage, grid.shape[0]), dtype=np.float64, order="C" @@ -1596,7 +1596,7 @@ def decision_function(self, X): array of shape (n_samples,). """ X = validate_data( - self, X, dtype=DTYPE, order="C", accept_sparse="csr", reset=False + self, X, dtype=np.float32, order="C", accept_sparse="csr", reset=False ) raw_predictions = self._raw_predict(X) if raw_predictions.shape[1] == 1: @@ -2138,7 +2138,7 @@ def __init__( def _encode_y(self, y=None, sample_weight=None): # Just convert y to the expected dtype self.n_trees_per_iteration_ = 1 - y = y.astype(DOUBLE, copy=False) + y = y.astype(np.float64, copy=False) return y def _get_loss(self, sample_weight): @@ -2163,7 +2163,7 @@ def predict(self, X): The predicted values. """ X = validate_data( - self, X, dtype=DTYPE, order="C", accept_sparse="csr", reset=False + self, X, dtype=np.float32, order="C", accept_sparse="csr", reset=False ) # In regression we can directly return the raw value from the trees. return self._raw_predict(X).ravel() diff --git a/sklearn/ensemble/_iforest.py b/sklearn/ensemble/_iforest.py index 578fbd1fab073..0ff9a86f2c5c8 100644 --- a/sklearn/ensemble/_iforest.py +++ b/sklearn/ensemble/_iforest.py @@ -12,7 +12,6 @@ from sklearn.base import OutlierMixin, _fit_context from sklearn.ensemble._bagging import BaseBagging from sklearn.tree import ExtraTreeRegressor -from sklearn.tree._tree import DTYPE as tree_dtype from sklearn.utils import check_array, check_random_state, gen_batches from sklearn.utils._chunking import get_chunk_n_rows from sklearn.utils._param_validation import Interval, RealNotInt, StrOptions @@ -319,7 +318,7 @@ def fit(self, X, y=None, sample_weight=None): Fitted estimator. """ X = validate_data( - self, X, accept_sparse=["csc"], dtype=tree_dtype, ensure_all_finite=False + self, X, accept_sparse=["csc"], dtype=np.float32, ensure_all_finite=False ) if sample_weight is not None: @@ -528,7 +527,7 @@ def score_samples(self, X): self, X, accept_sparse="csr", - dtype=tree_dtype, + dtype=np.float32, reset=False, ensure_all_finite=False, ) diff --git a/sklearn/tree/_classes.py b/sklearn/tree/_classes.py index 588ee45c7b048..313072da4a9cc 100644 --- a/sklearn/tree/_classes.py +++ b/sklearn/tree/_classes.py @@ -25,7 +25,7 @@ clone, is_classifier, ) -from sklearn.tree import _criterion, _splitter, _tree +from sklearn.tree import _criterion, _splitter from sklearn.tree._criterion import Criterion from sklearn.tree._splitter import Splitter from sklearn.tree._tree import ( @@ -64,9 +64,6 @@ # Types and constants # ============================================================================= -DTYPE = _tree.DTYPE -DOUBLE = _tree.DOUBLE - CRITERIA_CLF = { "gini": _criterion.Gini, "log_loss": _criterion.Entropy, @@ -193,7 +190,7 @@ def _compute_missing_values_in_feature_mask(self, X, estimator_name=None): Parameter --------- - X : array-like of shape (n_samples, n_features), dtype=DOUBLE + X : array-like of shape (n_samples, n_features) Input data. estimator_name : str or None, default=None @@ -244,7 +241,7 @@ def _fit( # _compute_missing_values_in_feature_mask will check for finite values and # compute the missing mask if the tree supports missing values check_X_params = dict( - dtype=DTYPE, accept_sparse="csc", ensure_all_finite=False + dtype=np.float32, accept_sparse="csc", ensure_all_finite=False ) check_y_params = dict(ensure_2d=False, dtype=None) X, y = validate_data( @@ -312,8 +309,8 @@ def _fit( self.n_classes_ = np.array(self.n_classes_, dtype=np.intp) - if getattr(y, "dtype", None) != DOUBLE or not y.flags.contiguous: - y = np.ascontiguousarray(y, dtype=DOUBLE) + if getattr(y, "dtype", None) != np.float64 or not y.flags.contiguous: + y = np.ascontiguousarray(y, dtype=np.float64) max_depth = np.iinfo(np.int32).max if self.max_depth is None else self.max_depth @@ -356,7 +353,7 @@ def _fit( ) if sample_weight is not None: - sample_weight = _check_sample_weight(sample_weight, X, dtype=DOUBLE) + sample_weight = _check_sample_weight(sample_weight, X, dtype=np.float64) if expanded_class_weight is not None: if sample_weight is not None: @@ -487,7 +484,7 @@ def _validate_X_predict(self, X, check_input): X = validate_data( self, X, - dtype=DTYPE, + dtype=np.float32, accept_sparse="csr", reset=False, ensure_all_finite=ensure_all_finite, @@ -1428,7 +1425,7 @@ def _compute_partial_dependence_recursion(self, grid, target_features): averaged_predictions : ndarray of shape (n_samples,), dtype=np.float64 The value of the partial dependence function on each grid point. """ - grid = np.asarray(grid, dtype=DTYPE, order="C") + grid = np.asarray(grid, dtype=np.float32, order="C") averaged_predictions = np.zeros( shape=grid.shape[0], dtype=np.float64, order="C" ) diff --git a/sklearn/tree/_tree.pyx b/sklearn/tree/_tree.pyx index 764c0f3ba25fe..11d7968949357 100644 --- a/sklearn/tree/_tree.pyx +++ b/sklearn/tree/_tree.pyx @@ -39,9 +39,6 @@ cdef extern from "numpy/arrayobject.h": # Types and constants # ============================================================================= -from numpy import float32 as DTYPE -from numpy import float64 as DOUBLE - cdef float64_t EPSILON = np.finfo('double').eps # Some handy constants (BestFirstTreeBuilder) @@ -97,19 +94,19 @@ cdef class TreeBuilder: X = X.tocsc() X.sort_indices() - if X.data.dtype != DTYPE: - X.data = np.ascontiguousarray(X.data, dtype=DTYPE) + if X.data.dtype != np.float32: + X.data = np.ascontiguousarray(X.data, dtype=np.float32) if X.indices.dtype != np.int32 or X.indptr.dtype != np.int32: raise ValueError("No support for np.int64 index based " "sparse matrices") - elif X.dtype != DTYPE: + elif X.dtype != np.float32: # since we have to copy we will make it fortran for efficiency - X = np.asfortranarray(X, dtype=DTYPE) + X = np.asfortranarray(X, dtype=np.float32) if sample_weight is not None and not sample_weight.base.flags.contiguous: - sample_weight = np.asarray(sample_weight, dtype=DOUBLE, order="C") + sample_weight = np.asarray(sample_weight, dtype=np.float64, order="C") return X, y, sample_weight @@ -962,7 +959,7 @@ cdef class Tree: raise ValueError("X should be in np.ndarray format, got %s" % type(X)) - if X.dtype != DTYPE: + if X.dtype != np.float32: raise ValueError("X.dtype should be np.float32, got %s" % X.dtype) # Extract input @@ -1006,7 +1003,7 @@ cdef class Tree: raise ValueError("X should be in CSR sparse format, got %s" % type(X)) - if X.dtype != DTYPE: + if X.dtype != np.float32: raise ValueError("X.dtype should be np.float32, got %s" % X.dtype) # Extract input @@ -1082,7 +1079,7 @@ cdef class Tree: raise ValueError("X should be in np.ndarray format, got %s" % type(X)) - if X.dtype != DTYPE: + if X.dtype != np.float32: raise ValueError("X.dtype should be np.float32, got %s" % X.dtype) # Extract input @@ -1141,7 +1138,7 @@ cdef class Tree: raise ValueError("X should be in CSR sparse format, got %s" % type(X)) - if X.dtype != DTYPE: + if X.dtype != np.float32: raise ValueError("X.dtype should be np.float32, got %s" % X.dtype) # Extract input diff --git a/sklearn/tree/tests/test_tree.py b/sklearn/tree/tests/test_tree.py index b2086f3a6bdcf..eb6d52c49a037 100644 --- a/sklearn/tree/tests/test_tree.py +++ b/sklearn/tree/tests/test_tree.py @@ -620,7 +620,7 @@ def test_error(): def test_min_samples_split(): """Test min_samples_split parameter""" - X = np.asfortranarray(iris.data, dtype=tree._tree.DTYPE) + X = np.asfortranarray(iris.data, dtype=np.float32) y = iris.target # test both DepthFirstTreeBuilder and BestFirstTreeBuilder @@ -651,7 +651,7 @@ def test_min_samples_split(): def test_min_samples_leaf(): # Test if leaves contain more than leaf_count training examples - X = np.asfortranarray(iris.data, dtype=tree._tree.DTYPE) + X = np.asfortranarray(iris.data, dtype=np.float32) y = iris.target # test both DepthFirstTreeBuilder and BestFirstTreeBuilder @@ -1621,7 +1621,7 @@ def test_min_weight_leaf_split_level(name, sparse_container): @pytest.mark.parametrize("name", ALL_TREES) def test_public_apply_all_trees(name): - X_small32 = X_small.astype(tree._tree.DTYPE, copy=False) + X_small32 = X_small.astype(np.float32, copy=False) est = ALL_TREES[name]() est.fit(X_small, y_small) @@ -1631,7 +1631,7 @@ def test_public_apply_all_trees(name): @pytest.mark.parametrize("name", SPARSE_TREES) @pytest.mark.parametrize("csr_container", CSR_CONTAINERS) def test_public_apply_sparse_trees(name, csr_container): - X_small32 = csr_container(X_small.astype(tree._tree.DTYPE, copy=False)) + X_small32 = csr_container(X_small.astype(np.float32, copy=False)) est = ALL_TREES[name]() est.fit(X_small, y_small) @@ -1992,13 +1992,13 @@ def assert_is_subtree(tree, subtree): @pytest.mark.parametrize("sparse_container", [None] + CSC_CONTAINERS + CSR_CONTAINERS) def test_apply_path_readonly_all_trees(name, splitter, sparse_container): dataset = DATASETS["clf_small"] - X_small = dataset["X"].astype(tree._tree.DTYPE, copy=False) + X_small = dataset["X"].astype(np.float32, copy=False) if sparse_container is None: X_readonly = create_memmap_backed_data(X_small) else: X_readonly = sparse_container(dataset["X"]) - X_readonly.data = np.array(X_readonly.data, dtype=tree._tree.DTYPE) + X_readonly.data = np.array(X_readonly.data, dtype=np.float32) ( X_readonly.data, X_readonly.indices, @@ -2007,7 +2007,7 @@ def test_apply_path_readonly_all_trees(name, splitter, sparse_container): (X_readonly.data, X_readonly.indices, X_readonly.indptr) ) - y_readonly = create_memmap_backed_data(np.array(y_small, dtype=tree._tree.DTYPE)) + y_readonly = create_memmap_backed_data(np.array(y_small, dtype=np.float32)) est = ALL_TREES[name](splitter=splitter) est.fit(X_readonly, y_readonly) assert_array_equal(est.predict(X_readonly), est.predict(X_small)) From b42224511662fbbf40227afaeba0a64a19bcc531 Mon Sep 17 00:00:00 2001 From: Arthur Lacote <arthur.lcte@gmail.com> Date: Tue, 12 May 2026 12:34:46 +0200 Subject: [PATCH 460/462] TST: Fix flakyness of array-API poisson regression compliance test (#33929) Co-authored-by: Olivier Grisel <olivier.grisel@ensta.org> --- sklearn/linear_model/_glm/tests/test_glm.py | 30 ++++++++++++--------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/sklearn/linear_model/_glm/tests/test_glm.py b/sklearn/linear_model/_glm/tests/test_glm.py index 0c8cdf77650b9..1d85aeb454493 100644 --- a/sklearn/linear_model/_glm/tests/test_glm.py +++ b/sklearn/linear_model/_glm/tests/test_glm.py @@ -1162,14 +1162,20 @@ def test_poisson_regressor_array_api_compliance( array_namespace, device_name, dtype_name, + global_random_seed, ): xp, device = _array_api_for_tests(array_namespace, device_name, dtype_name) - X_np, y_np = make_regression( - n_samples=107, n_features=20, n_informative=20, noise=0.5, random_state=2 - ) - # make y positive - y_np = np.abs(y_np) + 1.0 - n_samples = X_np.shape[0] + rng = np.random.default_rng(global_random_seed) + n_samples = 1000 + n_features = 3 + X_np = rng.normal(size=(n_samples, n_features)) + beta = np.array([0.5, -0.3, 0.8]) # true coefficients + intercept = 1.0 + mu = np.exp(X_np @ beta + intercept) # Poisson mean with log-link. + y_np = rng.poisson(mu) + # Ensure that we have non-zero targets for meaningful testing: + assert (y_np > 0).mean() > 0.1 + X_np = X_np.astype(dtype_name, copy=False) y_np = y_np.astype(dtype_name, copy=False) X_xp = xp.asarray(X_np, device=device) @@ -1177,15 +1183,15 @@ def test_poisson_regressor_array_api_compliance( if use_sample_weight: sample_weight = ( - np.random.default_rng(0) - .uniform(-1, 5, size=n_samples) + rng.uniform(-1, 5, size=n_samples) .clip(0, None) # over-represent null weights to cover edge-cases. .astype(dtype_name) ) else: sample_weight = None - params = dict(alpha=1, solver="lbfgs", tol=1e-12, max_iter=500) + params = dict(alpha=1, solver="lbfgs", max_iter=500) + params["tol"] = 3e-6 if dtype_name == "float32" else 1e-13 glm_np = PoissonRegressor(**params).fit(X_np, y_np, sample_weight=sample_weight) assert glm_np.n_iter_ < glm_np.max_iter @@ -1193,13 +1199,13 @@ def test_poisson_regressor_array_api_compliance( assert np.abs(glm_np.coef_).max() > 0.1 predict_np = glm_np.predict(X_np) - atol = _atol_for_type(dtype_name) * 10 - rtol = 3e-3 if dtype_name == "float32" else 1e-6 + atol = _atol_for_type(dtype_name) + rtol = 2e-3 if dtype_name == "float32" else 3e-7 with config_context(array_api_dispatch=True): glm_xp = PoissonRegressor(**params).fit(X_xp, y_xp, sample_weight=sample_weight) if dtype_name == "float64": - assert glm_xp.n_iter_ == glm_np.n_iter_ + assert abs(glm_xp.n_iter_ - glm_np.n_iter_) <= 1 for attr_name in ("coef_", "intercept_"): attr_xp = getattr(glm_xp, attr_name) From a75111fe68986aa9f7a5f552f8b7bf7e411ac170 Mon Sep 17 00:00:00 2001 From: Eric Prestat <eric.prestat@gmail.com> Date: Tue, 12 May 2026 12:09:31 +0100 Subject: [PATCH 461/462] MNT Fix NMF error with SciPy dev after SVD output memory layout change (#33260) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémie du Boisberranger <jeremie@probabl.ai> --- sklearn/decomposition/_nmf.py | 8 +++++--- sklearn/decomposition/tests/test_nmf.py | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/sklearn/decomposition/_nmf.py b/sklearn/decomposition/_nmf.py index df271a02987ae..99c3f8bc05bd3 100644 --- a/sklearn/decomposition/_nmf.py +++ b/sklearn/decomposition/_nmf.py @@ -480,9 +480,11 @@ def _fit_coordinate_descent( Cichocki, Andrzej, and P. H. A. N. Anh-Huy. IEICE transactions on fundamentals of electronics, communications and computer sciences 92.3: 708-721, 2009. """ - # so W and Ht are both in C order in memory - Ht = check_array(H.T, order="C") - X = check_array(X, accept_sparse="csr") + # ensure that W and Ht are both in C order in memory and that X is csr + W = np.ascontiguousarray(W) + Ht = np.ascontiguousarray(H.T) + if sp.issparse(X) and X.format == "csc": + X = X.tocsr() rng = check_random_state(random_state) diff --git a/sklearn/decomposition/tests/test_nmf.py b/sklearn/decomposition/tests/test_nmf.py index 17be798b3f392..f287b19c184eb 100644 --- a/sklearn/decomposition/tests/test_nmf.py +++ b/sklearn/decomposition/tests/test_nmf.py @@ -1008,3 +1008,18 @@ def test_nmf_custom_init_shape_error(): with pytest.raises(ValueError, match="Array with wrong second dimension passed"): nmf.fit(X, H=H, W=rng.random_sample((6, 3))) + + +@pytest.mark.parametrize("init", (None, "nndsvd", "nndsvda", "nndsvdar", "random")) +@pytest.mark.parametrize("shape", ((30, 10), (10, 30)), ids=("tall", "wide")) +@pytest.mark.parametrize("solver", ("cd", "mu")) +def test_nmf_smoke(init, shape, solver): + """Smoke test NMF with all inits, solvers on tall/wide arrays.""" + rng = np.random.RandomState(0) + X = np.abs(rng.random_sample(shape)) + + nmf = NMF(n_components=5, init=init, random_state=0, solver=solver) + W = nmf.fit_transform(X) + + assert W.shape == (shape[0], 5) + assert nmf.components_.shape == (5, shape[1]) From e67ae2f1412a4c67ce4c24061ce44af2af3d5bcb Mon Sep 17 00:00:00 2001 From: Arthur Lacote <arthur.lcte@gmail.com> Date: Tue, 12 May 2026 13:15:53 +0200 Subject: [PATCH 462/462] FIX: Use intro sort for `simultaneous_sort` (2 way partitioning) (#33252) --- .../sklearn.metrics/33252.fix.rst | 5 + .../sklearn.neighbors/33252.fix.rst | 6 + sklearn/neighbors/_binary_tree.pxi.tp | 6 +- sklearn/tree/_criterion.pyx | 4 +- sklearn/tree/_partitioner.pyx | 21 +- sklearn/utils/_sorting.pxd | 13 +- sklearn/utils/_sorting.pyx | 336 +++++++++++------- sklearn/utils/tests/test_sorting.py | 61 ++++ 8 files changed, 295 insertions(+), 157 deletions(-) create mode 100644 doc/whats_new/upcoming_changes/sklearn.metrics/33252.fix.rst create mode 100644 doc/whats_new/upcoming_changes/sklearn.neighbors/33252.fix.rst create mode 100644 sklearn/utils/tests/test_sorting.py diff --git a/doc/whats_new/upcoming_changes/sklearn.metrics/33252.fix.rst b/doc/whats_new/upcoming_changes/sklearn.metrics/33252.fix.rst new file mode 100644 index 0000000000000..b29d09c8c77f4 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.metrics/33252.fix.rst @@ -0,0 +1,5 @@ +- Fixed :func:`metrics.pairwise_distances_argmin` and + :func:`metrics.pairwise_distances_argmin_min` to avoid a quadratic-time path + when many distances are identical, which could lead to severe slowdowns or + even a stack overflow (segmentation fault) on large inputs. + By :user:`Arthur Lacote <cakedev0>`. diff --git a/doc/whats_new/upcoming_changes/sklearn.neighbors/33252.fix.rst b/doc/whats_new/upcoming_changes/sklearn.neighbors/33252.fix.rst new file mode 100644 index 0000000000000..641d17cc8bdc4 --- /dev/null +++ b/doc/whats_new/upcoming_changes/sklearn.neighbors/33252.fix.rst @@ -0,0 +1,6 @@ +- Fixed a quadratic-time path in the internal ``simultaneous_sort`` used by + :class:`neighbors.BallTree` and :class:`neighbors.KDTree` queries when many + distances are identical, which could lead to severe slowdowns or even a stack + overflow (segmentation fault) on large inputs. Neighbor searches with tied + distances no longer degrade badly in runtime. + By :user:`Arthur Lacote <cakedev0>`. diff --git a/sklearn/neighbors/_binary_tree.pxi.tp b/sklearn/neighbors/_binary_tree.pxi.tp index 80b5a273abd5f..daf9fe039d556 100644 --- a/sklearn/neighbors/_binary_tree.pxi.tp +++ b/sklearn/neighbors/_binary_tree.pxi.tp @@ -583,9 +583,9 @@ cdef class NeighborsHeap{{name_suffix}}: cdef intp_t row for row in range(self.distances.shape[0]): _simultaneous_sort( - dist=&self.distances[row, 0], - idx=&self.indices[row, 0], - size=self.distances.shape[1], + values=&self.distances[row, 0], + indices=&self.indices[row, 0], + n=self.distances.shape[1], ) return 0 diff --git a/sklearn/tree/_criterion.pyx b/sklearn/tree/_criterion.pyx index 46a9b57d362d1..b4c13b99f37c7 100644 --- a/sklearn/tree/_criterion.pyx +++ b/sklearn/tree/_criterion.pyx @@ -13,7 +13,7 @@ from scipy.special.cython_special cimport xlogy from sklearn.tree._utils cimport log from sklearn.tree._utils cimport WeightedFenwickTree -from sklearn.utils._sorting cimport sort +from sklearn.utils._sorting cimport simultaneous_sort # EPSILON is used in the Poisson criterion cdef float64_t EPSILON = 10 * np.finfo('double').eps @@ -1138,7 +1138,7 @@ cdef inline void compute_ranks( cdef intp_t i for i in range(n): sorted_indices[i] = i - sort(sorted_y, sorted_indices, n) + simultaneous_sort(sorted_y, sorted_indices, n, use_three_way_partition=True) for i in range(n): ranks[sorted_indices[i]] = i diff --git a/sklearn/tree/_partitioner.pyx b/sklearn/tree/_partitioner.pyx index 4a81d06cb03c0..266928b1055aa 100644 --- a/sklearn/tree/_partitioner.pyx +++ b/sklearn/tree/_partitioner.pyx @@ -21,7 +21,7 @@ cnp.import_array() from scipy.sparse import issparse from sklearn.tree._splitter cimport SplitRecord -from sklearn.utils._sorting cimport sort +from sklearn.utils._sorting cimport simultaneous_sort # Constant to switch between algorithm non zero value extract algorithm # in SparsePartitioner @@ -100,7 +100,12 @@ cdef class DensePartitioner: for i in range(self.start, self.end): feature_values[i] = X[samples[i], current_feature] - sort(&feature_values[self.start], &samples[self.start], self.end - self.start - n_missing) + simultaneous_sort( + &feature_values[self.start], + &samples[self.start], + self.end - self.start - n_missing, + use_three_way_partition=True, + ) self.n_missing = n_missing cdef void shift_missing_to_the_left(self) noexcept nogil: @@ -331,12 +336,18 @@ cdef class SparsePartitioner: self.extract_nnz(current_feature) # Sort the positive and negative parts of `feature_values` - sort(&feature_values[self.start], &samples[self.start], self.end_negative - self.start) + simultaneous_sort( + &feature_values[self.start], + &samples[self.start], + self.end_negative - self.start, + use_three_way_partition=True, + ) if self.start_positive < self.end: - sort( + simultaneous_sort( &feature_values[self.start_positive], &samples[self.start_positive], - self.end - self.start_positive + self.end - self.start_positive, + use_three_way_partition=True, ) # Update index_to_samples to take into account the sort diff --git a/sklearn/utils/_sorting.pxd b/sklearn/utils/_sorting.pxd index 377618236a52e..ee900b6387429 100644 --- a/sklearn/utils/_sorting.pxd +++ b/sklearn/utils/_sorting.pxd @@ -2,14 +2,9 @@ from sklearn.utils._typedefs cimport intp_t from cython cimport floating -cdef int simultaneous_sort( - floating *dist, - intp_t *idx, - intp_t size, -) noexcept nogil - -cdef void sort( - floating* feature_values, - intp_t* samples, +cdef void simultaneous_sort( + floating* values, + intp_t* indices, intp_t n, + bint use_three_way_partition=*, ) noexcept nogil diff --git a/sklearn/utils/_sorting.pyx b/sklearn/utils/_sorting.pyx index ad4d5751bfc1e..66187874f3275 100644 --- a/sklearn/utils/_sorting.pyx +++ b/sklearn/utils/_sorting.pyx @@ -2,165 +2,181 @@ from libc.math cimport log2 from cython cimport floating -from sklearn.utils._typedefs cimport float32_t, intp_t +from sklearn.utils._typedefs cimport intp_t -cdef inline void dual_swap( - floating* darr, - intp_t *iarr, - intp_t a, - intp_t b, -) noexcept nogil: - """Swap the values at index a and b of both darr and iarr""" - darr[a], darr[b] = darr[b], darr[a] - iarr[a], iarr[b] = iarr[b], iarr[a] - - -cdef int simultaneous_sort( +cdef void simultaneous_sort( floating* values, intp_t* indices, - intp_t size, + intp_t n, + bint use_three_way_partition=False, ) noexcept nogil: - """ - Perform a recursive quicksort on the values array as to sort them ascendingly. - This simultaneously performs the swaps on both the values and the indices arrays. + """Sort values and indices simultaneously by values. The numpy equivalent is: + def simultaneous_sort(values, indices): + i = np.argsort(values) + return values[i], indices[i] - def simultaneous_sort(dist, idx): - i = np.argsort(dist) - return dist[i], idx[i] + Algorithm: Introsort (Musser, SP&E, 1997) with two variants for the + quicksort part: + + - If use_three_way_partition is True, use 3-way partitioning: + [x < pivot] [x == pivot] [x > pivot]. This variant is fast when + working with many duplicate values, otherwise it's slower. + - If use_three_way_partition is False, use 2-way partitioning: + [x <= pivot] [pivot] [x >= pivot]. There are three parts too, but the middle + part is only the selected pivot element, not all values equal to the pivot. Notes ----- - Arrays are manipulated via a pointer to there first element and their size - as to ease the processing of dynamically allocated buffers. + Arrays are manipulated via a pointer to their first element and their size + to ease the processing of dynamically allocated buffers. + + TODO: In order to support discrete distance metrics, we need to have a + simultaneous sort which breaks ties on indices when distances are + identical. The best might be using a std::stable_sort and a Comparator + which might need an Array of Structures (AoS) instead of the Structure of + Arrays (SoA) currently used. An alternative would be to implement a stable + sort ourselves, like the radix sort for instance. """ - # TODO: In order to support discrete distance metrics, we need to have a - # simultaneous sort which breaks ties on indices when distances are identical. - # The best might be using a std::stable_sort and a Comparator which might need - # an Array of Structures (AoS) instead of the Structure of Arrays (SoA) - # currently used. - cdef: - intp_t pivot_idx, i, store_idx - floating pivot_val - - # in the small-array case, do things efficiently - if size <= 1: - pass - elif size == 2: - if values[0] > values[1]: - dual_swap(values, indices, 0, 1) - elif size == 3: - if values[0] > values[1]: - dual_swap(values, indices, 0, 1) - if values[1] > values[2]: - dual_swap(values, indices, 1, 2) - if values[0] > values[1]: - dual_swap(values, indices, 0, 1) - else: - # Determine the pivot using the median-of-three rule. - # The smallest of the three is moved to the beginning of the array, - # the middle (the pivot value) is moved to the end, and the largest - # is moved to the pivot index. - pivot_idx = size // 2 - if values[0] > values[size - 1]: - dual_swap(values, indices, 0, size - 1) - if values[size - 1] > values[pivot_idx]: - dual_swap(values, indices, size - 1, pivot_idx) - if values[0] > values[size - 1]: - dual_swap(values, indices, 0, size - 1) - pivot_val = values[size - 1] - - # Partition indices about pivot. At the end of this operation, - # pivot_idx will contain the pivot value, everything to the left - # will be smaller, and everything to the right will be larger. - store_idx = 0 - for i in range(size - 1): - if values[i] < pivot_val: - dual_swap(values, indices, i, store_idx) - store_idx += 1 - dual_swap(values, indices, store_idx, size - 1) - pivot_idx = store_idx - - # Recursively sort each side of the pivot - if pivot_idx > 1: - simultaneous_sort(values, indices, pivot_idx) - if pivot_idx + 2 < size: - simultaneous_sort(values + pivot_idx + 1, - indices + pivot_idx + 1, - size - pivot_idx - 1) - return 0 - - -def _py_sort(float32_t[::1] feature_values, intp_t[::1] samples, intp_t n): - """Used for testing sort.""" - sort(&feature_values[0], &samples[0], n) - - -# Sort n-element arrays pointed to by feature_values and samples, simultaneously, -# by the values in feature_values. Algorithm: Introsort (Musser, SP&E, 1997). -cdef void sort(floating* feature_values, intp_t* samples, intp_t n) noexcept nogil: if n == 0: return cdef intp_t maxd = 2 * <intp_t>log2(n) - introsort(feature_values, samples, n, maxd) + if use_three_way_partition: + introsort_3way(values, indices, n, maxd) + else: + introsort_2way(values, indices, n, maxd) -cdef inline floating median3(floating* feature_values, intp_t n) noexcept nogil: - # Median of three pivot selection, after Bentley and McIlroy (1993). - # Engineering a sort function. SP&E. Requires 8/3 comparisons on average. - cdef floating a = feature_values[0], b = feature_values[n / 2], c = feature_values[n - 1] - if a < b: - if b < c: - return b - elif a < c: - return c - else: - return a - elif b < c: - if a < c: - return a - else: - return c - else: - return b +def _py_simultaneous_sort( + floating[::1] values, + intp_t[::1] indices, + intp_t n, + *, + bint use_three_way_partition, +): + """Python wrapper used for testing.""" + simultaneous_sort(&values[0], &indices[0], n, use_three_way_partition) + +cdef void introsort_2way( + floating* values, + intp_t* indices, + intp_t n, + intp_t maxd, +) noexcept nogil: + cdef floating pivot + cdef intp_t pivot_idx, i, j -# Introsort with median of 3 pivot selection and 3-way partition function -# (robust to repeated elements, e.g. lots of zero features). -cdef void introsort(floating* feature_values, intp_t *samples, - intp_t n, intp_t maxd) noexcept nogil: + while n > 15: + if maxd <= 0: # max depth limit exceeded ("gone quadratic") + heapsort(values, indices, n) + return + maxd -= 1 + + pivot = inplace_median3(values, indices, n) + + i = 1 # the median3 step ensures values[0] <= pivot + j = n - 2 # the median3 step ensures values[-1] >= pivot + while True: + # Find element >= pivot from left + while i <= j and values[i] < pivot: + i += 1 + # Find element <= pivot from right + while i <= j and values[j] > pivot: + j -= 1 + if i >= j: + break + swap(values, indices, i, j) + i += 1 + j -= 1 + + # Put pivot at pivot_idx + pivot_idx = i + swap(values, indices, pivot_idx, n - 1) + + # Recursively sort left side of the pivot + introsort_2way(values, indices, pivot_idx, maxd) + + # Continue with right side: + values += pivot_idx + 1 + indices += pivot_idx + 1 + n -= pivot_idx + 1 + + # in the small-array case, insertion sort is faster + insertion_sort(values, indices, n) + + +cdef void introsort_3way( + floating* values, intp_t *indices, + intp_t n, intp_t maxd +) noexcept nogil: + """ + Introsort with median of 3 pivot selection and 3-way partition function + (fast for repeated elements, e.g. lots of zeros). + """ cdef floating pivot cdef intp_t i, l, r - while n > 1: + while n > 15: if maxd <= 0: # max depth limit exceeded ("gone quadratic") - heapsort(feature_values, samples, n) + heapsort(values, indices, n) return maxd -= 1 - pivot = median3(feature_values, n) + pivot = median3(values, n) - # Three-way partition. i = l = 0 r = n while i < r: - if feature_values[i] < pivot: - dual_swap(feature_values, samples, i, l) + if values[i] < pivot: + swap(values, indices, i, l) i += 1 l += 1 - elif feature_values[i] > pivot: + elif values[i] > pivot: r -= 1 - dual_swap(feature_values, samples, i, r) + swap(values, indices, i, r) else: i += 1 - introsort(feature_values, samples, l, maxd) - feature_values += r - samples += r + # Three-way partition: + # - values[:l] contains elements < pivot + # - values[l:r] contains elements == pivot + # - values[r:] contains elements > pivot + + # Recursively sort left side: + introsort_3way(values, indices, l, maxd) + + # Continue with right side: + values += r + indices += r n -= r + # in the small-array case, insertion sort is faster + insertion_sort(values, indices, n) + +# ------------ HEAP SORT ------------- + +cdef void heapsort(floating* feature_values, intp_t* samples, intp_t n) noexcept nogil: + cdef intp_t start, end + + # heapify + start = (n - 2) / 2 + end = n + while True: + sift_down(feature_values, samples, start, end) + if start == 0: + break + start -= 1 + + # sort by shrinking the heap, putting the max element immediately after it + end = n - 1 + while end > 0: + swap(feature_values, samples, 0, end) + sift_down(feature_values, samples, 0, end) + end = end - 1 + cdef inline void sift_down(floating* feature_values, intp_t* samples, intp_t start, intp_t end) noexcept nogil: @@ -181,25 +197,69 @@ cdef inline void sift_down(floating* feature_values, intp_t* samples, if maxind == root: break else: - dual_swap(feature_values, samples, root, maxind) + swap(feature_values, samples, root, maxind) root = maxind -cdef void heapsort(floating* feature_values, intp_t* samples, intp_t n) noexcept nogil: - cdef intp_t start, end +# ------------ HELPERS ------------- - # heapify - start = (n - 2) / 2 - end = n - while True: - sift_down(feature_values, samples, start, end) - if start == 0: - break - start -= 1 +cdef inline floating inplace_median3(floating* values, intp_t* indices, intp_t n) noexcept nogil: + # # Median of three pivot selection + # The smallest of the three is moved to the beginning of the array, + # the middle (the pivot value) is moved to the end, and the largest + # is moved to the pivot index. + pivot_idx = n // 2 + if values[0] > values[n - 1]: + swap(values, indices, 0, n - 1) + if values[n - 1] > values[pivot_idx]: + swap(values, indices, n - 1, pivot_idx) + if values[0] > values[n - 1]: + swap(values, indices, 0, n - 1) + return values[n - 1] - # sort by shrinking the heap, putting the max element immediately after it - end = n - 1 - while end > 0: - dual_swap(feature_values, samples, 0, end) - sift_down(feature_values, samples, 0, end) - end = end - 1 + +cdef inline floating median3(floating* feature_values, intp_t n) noexcept nogil: + # Median of three pivot selection, after Bentley and McIlroy (1993). + # Engineering a sort function. SP&E. Requires 8/3 comparisons on average. + cdef floating a = feature_values[0], b = feature_values[n / 2], c = feature_values[n - 1] + if a < b: + if b < c: + return b + elif a < c: + return c + else: + return a + elif b < c: + if a < c: + return a + else: + return c + else: + return b + + +cdef inline void swap(floating* values, intp_t* indices, + intp_t i, intp_t j) noexcept nogil: + # Helper for sort + values[i], values[j] = values[j], values[i] + indices[i], indices[j] = indices[j], indices[i] + + +cdef inline void insertion_sort( + floating* values, intp_t *indices, intp_t n +) noexcept nogil: + cdef intp_t i, j, temp_idx + cdef floating temp_val + + for i in range(1, n): + temp_val = values[i] + temp_idx = indices[i] + + j = i + while j > 0 and values[j - 1] > temp_val: + values[j] = values[j - 1] + indices[j] = indices[j - 1] + j -= 1 + + values[j] = temp_val + indices[j] = temp_idx diff --git a/sklearn/utils/tests/test_sorting.py b/sklearn/utils/tests/test_sorting.py new file mode 100644 index 0000000000000..6bd25a2778878 --- /dev/null +++ b/sklearn/utils/tests/test_sorting.py @@ -0,0 +1,61 @@ +# SPDX-License-Identifier: BSD-3-Clause + +import numpy as np +import pytest +from numpy.testing import assert_array_equal + +from sklearn.utils._sorting import _py_simultaneous_sort + + +@pytest.mark.parametrize("kind", ["2-way", "3-way"]) +def test_simultaneous_sort_correctness(kind): + rng = np.random.default_rng(0) + for x in [ + rng.uniform(size=3), + rng.uniform(size=10), + rng.uniform(size=1000), + # with duplicates: + rng.geometric(0.2, size=100).astype("float32"), + rng.integers(0, 2, size=1000).astype("float32"), + ]: + n = x.size + ind = np.arange(n, dtype=np.intp) + x_sorted = x.copy() + _py_simultaneous_sort(x_sorted, ind, n, use_three_way_partition=kind == "3-way") + assert (x_sorted[:-1] <= x_sorted[1:]).all() + assert_array_equal(x[ind], x_sorted) + assert_array_equal(np.sort(ind), np.arange(n, dtype=np.intp)) + + +@pytest.mark.parametrize("kind", ["2-way", "3-way"]) +def test_simultaneous_sort_no_stackoverflow(kind): + """Check that worst case inputs do not exceed the recursion stack limit.""" + n = 1_000_000 + # worst case pattern (i.e. triggers the quadratic path) + # for naive 2-way partitioning quicksort: + values = np.zeros(n) + indices = np.arange(n, dtype=np.intp) + _py_simultaneous_sort( + values, indices, values.shape[0], use_three_way_partition=kind == "3-way" + ) + + # worst case pattern for the better (numpy-style) 2-way partitioning: + values = np.roll(np.arange(n), -1).astype(np.float32) + indices = np.arange(n, dtype=np.intp) + _py_simultaneous_sort( + values, indices, values.shape[0], use_three_way_partition=kind == "3-way" + ) + + # worst case pattern for the 3-way partitioning quicksort + # with median-of-3 pivot: + k = n // 2 + values = np.array( + [i if i % 2 == 1 else k + i - 1 for i in range(1, k + 1)] + + [i for i in range(1, 2 * k + 1) if i % 2 == 0] + ).astype(np.float64) + # (very unlikely in real-world non-adversarial data) + indices = np.arange(n, dtype=np.intp) + assert values.size == indices.size + _py_simultaneous_sort( + values, indices, values.shape[0], use_three_way_partition=kind == "3-way" + )