Skip to content

{Packaging} Support Python 3.14 in CI, packaging, and metadata#33313

Open
YangAn-microsoft wants to merge 3 commits into
Azure:devfrom
YangAn-microsoft:feature/python314-support
Open

{Packaging} Support Python 3.14 in CI, packaging, and metadata#33313
YangAn-microsoft wants to merge 3 commits into
Azure:devfrom
YangAn-microsoft:feature/python314-support

Conversation

@YangAn-microsoft
Copy link
Copy Markdown
Contributor

@YangAn-microsoft YangAn-microsoft commented May 4, 2026

Description

Bumps Azure CLI's supported Python from 3.13 → 3.14 across CI, packaging, metadata, and docs, plus one robustness fix for the Windows MSI build on the win32 embeddable Python 3.14 distribution.

Note on the 3.14 parallel-import deadlock

CPython 3.14's importlib now raises _DeadlockError on certain re-entrant module-lock acquisitions instead of silently hanging. Earlier revisions of this PR included an _prewarm_shared_imports() mitigation in azure-cli-core. That code has been dropped from this PR — #33250 (restore sequential module loading) is the correct fix and supersedes the prewarm workaround. This PR now only covers the packaging/CI move to 3.14 and the MSI build fix above; the deadlock is handled out-of-band by #33250.

Version bumps

  • CI (azure-pipelines*.yml, breaking-change-tests.yml, regression_test.yml): versionSpec 3.13 → '3.14' (quoted to preserve the trailing zero); add Python314 matrix entries; add AutomationFullTestPython314ProfileLatest.
  • Packaging: embedded Python 3.13.13 → 3.14.5 (Windows MSI, Debian); macOS pipelines and helper scripts updated 3.13 → 3.14.
  • Metadata: add Programming Language :: Python :: 3.14 classifier to all setup.py files.
  • Docs: supported range 3.10 ~ 3.13 → 3.10 ~ 3.14.

Testing Guide

Run CI and confirm the new Python 3.14 jobs pass. The x86 MSI build exercises the embed-Python _pth fix; test_azure_cli_installation on Linux 3.14 covers the rest of the packaging/metadata changes.

History Notes

No customer-facing API changes. Internal CI, packaging, compatibility, and a Windows MSI build fix for embeddable Python 3.14.

@azure-client-tools-bot-prd
Copy link
Copy Markdown

azure-client-tools-bot-prd Bot commented May 4, 2026

️✔️AzureCLI-FullTest
️✔️acr
️✔️latest
️✔️3.12
️✔️3.14
️✔️acs
️✔️latest
️✔️3.12
️✔️3.14
️✔️advisor
️✔️latest
️✔️3.12
️✔️3.14
️✔️ams
️✔️latest
️✔️3.12
️✔️3.14
️✔️apim
️✔️latest
️✔️3.12
️✔️3.14
️✔️appconfig
️✔️latest
️✔️3.12
️✔️3.14
️✔️appservice
️✔️latest
️✔️3.12
️✔️3.14
️✔️aro
️✔️latest
️✔️3.12
️✔️3.14
️✔️backup
️✔️latest
️✔️3.12
️✔️3.14
️✔️batch
️✔️latest
️✔️3.12
️✔️3.14
️✔️batchai
️✔️latest
️✔️3.12
️✔️3.14
️✔️billing
️✔️latest
️✔️3.12
️✔️3.14
️✔️botservice
️✔️latest
️✔️3.12
️✔️3.14
️✔️cdn
️✔️latest
️✔️3.12
️✔️3.14
️✔️cloud
️✔️latest
️✔️3.12
️✔️3.14
️✔️cognitiveservices
️✔️latest
️✔️3.12
️✔️3.14
️✔️compute_recommender
️✔️latest
️✔️3.12
️✔️3.14
️✔️computefleet
️✔️latest
️✔️3.12
️✔️3.14
️✔️config
️✔️latest
️✔️3.12
️✔️3.14
️✔️configure
️✔️latest
️✔️3.12
️✔️3.14
️✔️consumption
️✔️latest
️✔️3.12
️✔️3.14
️✔️container
️✔️latest
️✔️3.12
️✔️3.14
️✔️containerapp
️✔️latest
️✔️3.12
️✔️3.14
️✔️core
️✔️latest
️✔️3.12
️✔️3.14
️✔️cosmosdb
️✔️latest
️✔️3.12
️✔️3.14
️✔️databoxedge
️✔️latest
️✔️3.12
️✔️3.14
️✔️dls
️✔️latest
️✔️3.12
️✔️3.14
️✔️dms
️✔️latest
️✔️3.12
️✔️3.14
️✔️eventgrid
️✔️latest
️✔️3.12
️✔️3.14
️✔️eventhubs
️✔️latest
️✔️3.12
️✔️3.14
️✔️feedback
️✔️latest
️✔️3.12
️✔️3.14
️✔️find
️✔️latest
️✔️3.12
️✔️3.14
️✔️hdinsight
️✔️latest
️✔️3.12
️✔️3.14
️✔️identity
️✔️latest
️✔️3.12
️✔️3.14
️✔️iot
️✔️latest
️✔️3.12
️✔️3.14
️✔️keyvault
️✔️latest
️✔️3.12
️✔️3.14
️✔️lab
️✔️latest
️✔️3.12
️✔️3.14
️✔️managedservices
️✔️latest
️✔️3.12
️✔️3.14
️✔️maps
️✔️latest
️✔️3.12
️✔️3.14
️✔️marketplaceordering
️✔️latest
️✔️3.12
️✔️3.14
️✔️monitor
️✔️latest
️✔️3.12
️✔️3.14
️✔️mysql
️✔️latest
️✔️3.12
️✔️3.14
️✔️netappfiles
️✔️latest
️✔️3.12
️✔️3.14
️✔️network
️✔️latest
️✔️3.12
️✔️3.14
️✔️policyinsights
️✔️latest
️✔️3.12
️✔️3.14
️✔️postgresql
️✔️latest
️✔️3.12
️✔️3.14
️✔️privatedns
️✔️latest
️✔️3.12
️✔️3.14
️✔️profile
️✔️latest
️✔️3.12
️✔️3.14
️✔️rdbms
️✔️latest
️✔️3.12
️✔️3.14
️✔️redis
️✔️latest
️✔️3.12
️✔️3.14
️✔️relay
️✔️latest
️✔️3.12
️✔️3.14
️✔️resource
️✔️latest
️✔️3.12
️✔️3.14
️✔️role
️✔️latest
️✔️3.12
️✔️3.14
️✔️search
️✔️latest
️✔️3.12
️✔️3.14
️✔️security
️✔️latest
️✔️3.12
️✔️3.14
️✔️servicebus
️✔️latest
️✔️3.12
️✔️3.14
️✔️serviceconnector
️✔️latest
️✔️3.12
️✔️3.14
️✔️servicefabric
️✔️latest
️✔️3.12
️✔️3.14
️✔️signalr
️✔️latest
️✔️3.12
️✔️3.14
️✔️sql
️✔️latest
️✔️3.12
️✔️3.14
️✔️sqlvm
️✔️latest
️✔️3.12
️✔️3.14
️✔️storage
️✔️latest
️✔️3.12
️✔️3.14
️✔️synapse
️✔️latest
️✔️3.12
️✔️3.14
️✔️telemetry
️✔️latest
️✔️3.12
️✔️3.14
️✔️util
️✔️latest
️✔️3.12
️✔️3.14
️✔️vm
️✔️latest
️✔️3.12
️✔️3.14

@azure-client-tools-bot-prd
Copy link
Copy Markdown

azure-client-tools-bot-prd Bot commented May 4, 2026

️✔️AzureCLI-BreakingChangeTest
️✔️Non Breaking Changes

@yonzhan
Copy link
Copy Markdown
Collaborator

yonzhan commented May 4, 2026

Thank you for your contribution! We will review the pull request and get back to you soon.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR.

Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions).
After that please run the following commands to enable git hooks:

pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>

@microsoft-github-policy-service microsoft-github-policy-service Bot added the Auto-Assign Auto assign by bot label May 4, 2026
@YangAn-microsoft YangAn-microsoft changed the title Support Python 3.14 in CI, packaging, and metadata [Packaging] Support Python 3.14 in CI, packaging, and metadata May 5, 2026
@YangAn-microsoft YangAn-microsoft changed the title [Packaging] Support Python 3.14 in CI, packaging, and metadata {Packaging} Support Python 3.14 in CI, packaging, and metadata May 5, 2026
@YangAn-microsoft YangAn-microsoft force-pushed the feature/python314-support branch 2 times, most recently from 986de78 to dac4c3c Compare May 9, 2026 01:19
@YangAn-microsoft YangAn-microsoft force-pushed the feature/python314-support branch from 333da22 to 333ad06 Compare May 15, 2026 04:13
@YangAn-microsoft
Copy link
Copy Markdown
Contributor Author

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@YangAn-microsoft YangAn-microsoft force-pushed the feature/python314-support branch 3 times, most recently from b5a863b to 35c2919 Compare May 18, 2026 05:11
@YangAn-microsoft YangAn-microsoft mentioned this pull request May 18, 2026
14 tasks
@YangAn-microsoft YangAn-microsoft marked this pull request as ready for review May 18, 2026 05:55
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates Azure CLI to officially support Python 3.14 by bumping CI/pipeline Python versions, packaging scripts, docs, and PyPI metadata, and adds a core startup mitigation for Python 3.14’s importlib deadlock detection when loading command modules in parallel.

Changes:

  • Add Python 3.14 support metadata (PyPI classifiers) and update documentation to reflect the supported Python range.
  • Update Azure Pipelines/test matrices and macOS/DEB/Homebrew packaging scripts to build/test with Python 3.14.
  • Pre-warm common Azure SDK imports in azure-cli-core before parallel module loading to avoid Python 3.14 _DeadlockError.

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/azure-cli/setup.py Adds Python 3.14 classifier to package metadata.
src/azure-cli-core/setup.py Adds Python 3.14 classifier to core package metadata.
src/azure-cli-telemetry/setup.py Adds Python 3.14 classifier to telemetry package metadata.
src/azure-cli-testsdk/setup.py Adds Python 3.14 classifier to testsdk package metadata.
src/azure-cli-core/azure/cli/core/init.py Pre-warms shared imports prior to parallel command-module loading to avoid Python 3.14 import deadlocks.
azure-pipelines.yml Switches primary pipeline Python version to 3.14 and expands job matrices to include 3.14.
azure-pipelines-full-tests.yml Adds a full-test job targeting Python 3.14 (latest profile).
.azure-pipelines/breaking-change-tests.yml Updates breaking-change pipeline to Python 3.14.
.azure-pipelines/macos-standalone-release.yml Updates default Homebrew Python version to 3.14 for macOS standalone release.
.azure-pipelines/templates/macos/macos-build-jobs.yml Updates default macOS build template Python version and docs to 3.14.
.azure-pipelines/templates/macos/macos-cask-generation-and-tests.yml Updates default macOS cask template Python version to 3.14.
.azure-pipelines/templates/macos/macos-publish-jobs.yml Updates default macOS publish template Python version to 3.14.
.azure-pipelines/templates/macos/macos-sign-notarize-jobs.yml Updates default macOS sign/notarize template Python version to 3.14.
scripts/release/debian/build.sh Bumps Debian build Python version to 3.14.4.
scripts/release/homebrew/docker/formula_generate.py Updates Homebrew formula generation to target Python 3.14.
scripts/release/macos/build_binary_tar_gz.py Updates macOS tarball build defaults/docs to Python 3.14.
scripts/release/macos/cask_generate.py Updates CLI help text example to Python 3.14.
scripts/regression_test/regression_test.yml Updates regression test pipeline to use Python 3.14.
doc/command_guidelines.md Updates documented supported Python range to include 3.14.
doc/extensions/authoring.md Updates extension authoring guidance/examples to Python 3.14.
doc/install_linux_prerequisites.md Updates supported Python range to include 3.14.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/azure-cli-core/azure/cli/core/__init__.py Outdated
Comment thread azure-pipelines-full-tests.yml
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 5 comments.

Comments suppressed due to low confidence (5)

azure-pipelines.yml:520

  • This job matrix drops Python 3.13 (now only 3.12 + 3.14). That conflicts with the PR description (“alongside 3.12 and 3.13”) and with docs that still claim support for 3.10–3.14 (including 3.13). If 3.13 remains supported, please add it back to the matrix here.
    name: ${{ variables.ubuntu_pool }}
  strategy:
    matrix:
      Python312:
        python.version: '3.12'
      Python314:
        python.version: '3.14'

azure-pipelines.yml:537

  • This job matrix drops Python 3.13 (now only 3.12 + 3.14). That conflicts with the PR description (“alongside 3.12 and 3.13”) and with docs that still claim support for 3.10–3.14 (including 3.13). If 3.13 remains supported, please add it back to the matrix here.
    name: ${{ variables.ubuntu_pool }}
  strategy:
    matrix:
      Python312:
        python.version: '3.12'
      Python314:
        python.version: '3.14'

azure-pipelines.yml:557

  • This job matrix drops Python 3.13 (now only 3.12 + 3.14). That conflicts with the PR description (“alongside 3.12 and 3.13”) and with docs that still claim support for 3.10–3.14 (including 3.13). If 3.13 remains supported, please add it back to the matrix here.
    name: ${{ variables.ubuntu_pool }}
  strategy:
    matrix:
      Python312:
        python.version: '3.12'
      Python314:
        python.version: '3.14'

azure-pipelines.yml:578

  • This job matrix drops Python 3.13 (now only 3.12 + 3.14). That conflicts with the PR description (“alongside 3.12 and 3.13”) and with docs that still claim support for 3.10–3.14 (including 3.13). If 3.13 remains supported, please add it back to the matrix here.
  pool:
    name: ${{ variables.ubuntu_pool }}
  strategy:
    matrix:
      Python314:
        python.version: '3.14'

azure-pipelines.yml:1141

  • This job matrix drops Python 3.13 (now only 3.12 + 3.14). That conflicts with the PR description (“alongside 3.12 and 3.13”) and with docs that still claim support for 3.10–3.14 (including 3.13). If 3.13 remains supported, please add it back to the matrix here.
  strategy:
    matrix:
      Python312:
        python.version: '3.12'
      Python314:
        python.version: '3.14'

Comment thread src/azure-cli-core/azure/cli/core/__init__.py Outdated
Comment thread src/azure-cli-core/azure/cli/core/__init__.py Outdated
Comment thread src/azure-cli-core/azure/cli/core/__init__.py Outdated
Comment thread azure-pipelines.yml
Comment thread azure-pipelines.yml Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.

Comment thread build_scripts/windows/scripts/build.cmd Outdated
Comment thread build_scripts/windows/scripts/build.cmd
@YangAn-microsoft YangAn-microsoft marked this pull request as ready for review May 20, 2026 05:06
@jiasli
Copy link
Copy Markdown
Member

jiasli commented May 20, 2026

CPython 3.14 changed importlib to raise _DeadlockError (instead of blocking) when threads concurrently import the same module (What's New)

  1. I cannot seem to find a description of this behavior in https://docs.python.org/3.14/whatsnew/3.14.html. Could you directly quote it here or provide more information?
  2. Is it merely "concurrently import the same module" that triggers the _DeadlockError? Isn't a circular import needed to trigger deadlock? Do we know where the deadlock/circular import comes from?
  3. What will happen in Python 3.13 when deadlock happens? Will Azure CLI hang?
  4. Even if some modules are added to _REQUIRED_PREWARM_MODULES and pre-loaded, this solution is fragile as SDK can change its internal dependency and structure without user-facing notification.
  5. {Core} Restore sequential module loading #33250 is trying to restore sequential module loading. If it gets merged, _prewarm_shared_imports() will no longer be necessary.

AI comments:

Here is a review of the comment you (@jiasli) left at #issuecomment-4496078686, along with analysis and context for each of your five points:


Review of Your Comment on PR #33313

Your comment raises excellent technical questions about Fix 1: the _prewarm_shared_imports() approach. Here's an assessment of each point:


Point 1: CPython 3.14 _DeadlockError documentation reference

Assessment: Valid concern.

The PR description links to the general Python 3.14 What's New page but doesn't quote the specific text. The relevant change is actually in CPython issue #99953 — in Python 3.14, importlib._bootstrap was changed so that when a thread tries to acquire a module lock that another thread already holds for the same module, instead of blocking (which could cause hangs/deadlocks), it raises _DeadlockError. The "What's New" page doesn't call this out prominently. Requesting a direct quote or a more precise reference (e.g., the CPython changelog/bpo issue) is a very reasonable ask.


Point 2: Does "concurrent import of the same module" alone trigger _DeadlockError?

Assessment: Correct — a circular import or re-entrant lock situation is required.

Simply importing the same module from two threads concurrently does not trigger _DeadlockError — Python's import system already uses per-module locks to serialize concurrent importers, and threads safely block waiting for the first importer to finish. _DeadlockError is only raised when there is a deadlock cycle — e.g., Thread A holds the lock for module X and waits for module Y, while Thread B holds the lock for module Y and waits for module X (a circular dependency). This is an important distinction: the PR description's claim that "concurrently import the same module" triggers the error is imprecise. The author should clarify where the actual circular import chain exists.


Point 3: What happens in Python 3.13 when deadlock occurs?

Assessment: Spot on.

In Python ≤3.13, the threads would simply hang indefinitely (the classic deadlock). Python 3.14 converts that silent hang into a raised exception, which is why the error became visible in 3.14. If this circular import truly exists, Azure CLI could theoretically deadlock on 3.13 as well — which is worth investigating. The pre-warm solution would suppress symptoms on 3.14 but the underlying circular dependency would remain.


Point 4: _REQUIRED_PREWARM_MODULES is fragile as SDK internals change

Assessment: Very valid long-term concern.

The list of modules to pre-warm is hardcoded and based on current SDK internal structure. As Azure SDKs evolve (new shared trunks, restructured subpackages, new transitive dependencies), this list can silently become incomplete. Any new shared module that gets imported by multiple workers could re-introduce the deadlock. This is a maintenance burden with no automated safety net. Your observation that this is fragile without user-facing SDK notifications is entirely correct.


Point 5: PR #33250 may make this moot

Assessment: Critical blocker consideration.

PR #33250 is listed as targeting sequential module loading. If that PR restores sequential loading, the entire concurrency problem disappears and _prewarm_shared_imports() becomes dead code. This should be resolved before merging:


Summary

Your comment is technically well-founded across all five points. The core issue is that Fix 1 (_prewarm_shared_imports) treats a symptom (import deadlock crash on 3.14) without fully diagnosing the root cause (what is the actual circular import chain?) and without addressing the 3.13 silent-hang scenario. Additionally:

  • The relationship with PR {Core} Restore sequential module loading #33250 needs to be clarified before merge.
  • The fragility of the hardcoded module list is a real maintenance risk.
  • The documentation/justification in the PR needs to be more precise.

The rest of the PR (CI/pipeline updates, packaging bumps, docs, metadata classifiers) appears straightforward and correct.


Want me to:

  1. Draft a reply to the PR comment with suggestions for the author to address your points?
  2. Look at PR {Core} Restore sequential module loading #33250 to assess whether it conflicts or supersedes this fix?
  3. Dig into the actual code to identify what the circular import chain might be?

Comment thread build_scripts/windows/scripts/build.cmd Outdated
echo Installing setuptools wheel
%PYTHON_DIR%\python.exe -Im pip install setuptools wheel
if "%ARCH%"=="x86" (
%PYTHON_DIR%\python.exe -Im pip install "setuptools<82" wheel
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've raise the win32 wheel issue in yaml/pyyaml#888 (comment)

Hope the wheel can be published so we don't need to change the build script.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. The solution in this PR is aiming to build pyyaml in embedded Python 3.14. Is it not necessary at all.

pyyaml only releases pyyaml-6.0.3-cp313-cp313-win32.whl (https://pypi.org/project/PyYAML/#files). pyyaml should address the absence of win32 wheel for Python 3.14.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced the previous workaround stack with a one-line ._pth fix. Now whether pyyaml provides win32 wheel won't affect our build.

Root cause (verified empirically on fresh win32 embed 3.13 vs 3.14): the old script did del python*._pth. On 3.13 that was harmless — python.exe still resolved the stdlib via default path computation. On 3.14, removing the ._pth breaks pip's PEP 517 isolated BuildEnvironment subprocess: the child python.exe can no longer locate python314.zip, fails to import encodings, and aborts in init_fs_encoding. That subprocess failure surfaced downstream as the _socket / _ctypes / setuptools.build_meta errors we'd been working around.

Fix: keep the shipped ._pth and just append import site. That single line enables site.py, which adds Lib\site-packages to sys.path. The existing pythonXY.zip / . entries keep stdlib and .pyd modules discoverable in both the parent process and any subprocess pip spawns.

Dropped: PIP_CONSTRAINT + build-constraints.txt, the setuptools<82 x86 pin, --no-build-isolation x86 branch, and the pyyaml pre-build block — all four workarounds become unnecessary because the underlying path-bootstrapping failure no longer happens.

Diff is now a single line in build.cmd:

-    del python*._pth
+    for %%f in (python*._pth) do echo import site>> %%f

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note on the 3.14 parallel-import deadlock

CPython 3.14's importlib now raises _DeadlockError on certain re-entrant module-lock acquisitions instead of silently hanging. Earlier revisions of this PR included an _prewarm_shared_imports() mitigation in azure-cli-core. That code has been dropped from this PR — #33250 (restore sequential module loading) is the correct fix and supersedes the prewarm workaround. This PR now only covers the packaging/CI move to 3.14 and the MSI build fix above; the deadlock is handled out-of-band by #33250.

@YangAn-microsoft YangAn-microsoft force-pushed the feature/python314-support branch 2 times, most recently from 2c3ed95 to 863714e Compare May 21, 2026 03:08
@YangAn-microsoft YangAn-microsoft requested a review from Copilot May 21, 2026 03:25
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.

Comment thread build_scripts/windows/scripts/build.cmd Outdated
Comment thread scripts/regression_test/regression_test.yml Outdated
Comment thread scripts/regression_test/regression_test.yml Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants