Compare commits

..

56 Commits

Author SHA1 Message Date
Michał
f8b1d7ae09
pyenv-exec: add the --environment option for programs that embed libpython without a path (#3537)
---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: native-api <vano@mail.mipt.ru>
2026-10-02 11:17:30 +03:00
Ayush
6ff25c51d3
pyenv-binary: allow local definitions to override published packages (#3577) 2026-10-02 05:19:21 +03:00
Ivan Pozdeev
42c75f3c53 2.8.7 2026-10-01 09:22:36 +03:00
pyenv-bot[bot]
e258d55f1f
Add CPython 3.10.22, 3.11.17 (#3576)
Co-authored-by: native-api <2670332+native-api@users.noreply.github.com>
2026-10-01 09:18:55 +03:00
pyenv-bot[bot]
627e0aa921
Add CPython 3.14.8 (#3574)
---------

Co-authored-by: native-api <2670332+native-api@users.noreply.github.com>
Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2026-10-01 07:41:27 +03:00
pyenv-bot[bot]
3d51eb919b
Add CPython 3.12.15, 3.13.16 (#3575)
Co-authored-by: native-api <2670332+native-api@users.noreply.github.com>
2026-10-01 06:11:20 +03:00
Ayush
2e3d62a129
tests: python-buid: use helpers from core (#3572) 2026-09-30 06:28:46 +03:00
Zhaoqi Xu
699e27fb27
init: honor custom PYENV_ROOT in init setup tips (#3569) 2026-09-29 02:41:17 +03:00
native-api
d9b158620e
Speed up permission fix step (#3571)
Saves several seconds for large installations like Anaconda
2026-09-29 01:11:44 +03:00
Ivan Pozdeev
bb15db59a4 graalpython: make python* symlinks 2026-09-28 13:06:24 +03:00
Ivan Pozdeev
60bfb906e1 Use new fixture 2026-09-28 13:04:27 +03:00
exurd
2439bee2c5
Add PyPy v8.0.0 (#3552)
* remove OpenSSL source build
PyPy searches dependencies with pkg-config which XCode CLT do not ship, so it cannot build without Homebrew or MacPorts anyway
* Use Homebrew/MacPorts OpenSSL

---------

Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2026-09-28 02:01:44 +03:00
exurd
ab74141ab4
Fix minimum macOS version check for PyPy v7.3.8+ (#3570)
* Switch pypy*-7.3.8-aarch64 to -portable
Regular version is no longer available for download

---------

Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2026-09-27 12:11:20 +03:00
native-api
e9334284e1
Merge pull request #3561 from n0tl3ss/fix/python-build-download-progress
python-build: show download progress in interactive terminals
2026-09-27 11:31:14 +03:00
Nemanja Mikic
8339b9b033 python-build: show download progress in interactive terminals
---
Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-09-27 11:00:13 +03:00
Ivan Pozdeev
67dbc6e930 stub: support ** to match any number of arguments 2026-09-27 10:59:03 +03:00
Ayush
513364609d
pyenv-binary: install published CPython packages (#3567) 2026-09-25 23:45:13 +03:00
exurd
3d1dda120b
python-build: Add add_pypy.py for pypy versions (#3566)
* python-build: add `add_pypy.py` for pypy versions

couldn't help myself ;P

python-build; add_pypy.py: ensure ensurepip is correct

python-build; add_pypy.py: check file extension

python-build; add_pypy.py: update os x version check to 10.15

python-build; add_pypy.py: remove outdated comment

python-build; add_pypy.py: cleanup comment

* Update add_pypy.py

* Remove comments irrelevant to reading the code
2026-09-25 10:13:34 +03:00
exurd
5434a7e3e9
Add PyPy v7.3.21 (#3564)
---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-09-25 02:19:33 +03:00
native-api
49cc565e1c
Merge pull request #3553 from exurd/pr/pypy-v7.3.23
Add PyPy v7.3.23
2026-09-24 14:20:14 +03:00
Ivan Pozdeev
a55c9df84d CI: install gdbm as part of prerequisites 2026-09-24 12:19:13 +03:00
Ivan Pozdeev
08021a03ab python-build: Support automatically picking PyPy as bootstrap version 2026-09-24 12:18:57 +03:00
exurd
9ac7b27486 Add PyPy v7.3.23 2026-09-24 12:04:24 +03:00
native-api
df5372511c
python-build: create pypy* symlinks for PyPy (#3562)
Source and some older versions builds do not create them
2026-09-24 07:23:52 +03:00
native-api
a3c666e177
install-prerequisites: add an option for optional dependencies (#3560) 2026-09-24 00:12:25 +03:00
native-api
26370b7f24
python-build: create PEP 394 symlinks for PyPy (#3559) 2026-09-23 13:34:23 +03:00
Michael Šimáček
beb4f2ffd2
Add GraalPy 3.13 25.4.4 (#3558) 2026-09-23 09:50:21 +03:00
David Lawson
4eea9b7848
python-build: create PEP 394 symlinks for Pyston (#3557)
* Consolidate build_package_pyston2_2 into build_package_pyston
There's no longer a difference

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Ivan Pozdeev <vano@mail.mipt.ru>
2026-09-23 09:49:52 +03:00
Ayush
249f8d888e
CI: publish Apple Silicon macOS binaries (#3556)
* pyenv-binary: relocate macOS text paths
* CI: publish Apple Silicon macOS binaries
* pyenv-binary: preserve unrelated bytecode
* CI: stabilize macOS binary package names
2026-09-22 01:12:32 +03:00
Mingyang Wu
7db7714ff7
Fix rehash repair of individually corrupted shims (#3540) 2026-09-21 13:02:14 +03:00
Ivan Pozdeev
3787bacc91 2.8.6 2026-09-17 10:06:03 +03:00
Ivan Pozdeev
c3550235e4 README: document XCode 27 downstream patches 2026-09-17 08:23:37 +03:00
13steinj
7d55c1a7d9
Add miniconda3 26.7.1-0, 26.7.1-1 and miniforge3 26.5.3-0, 26.7.2-0 (#3550)
Adds latest miniconda releases 26.7.1-0, 26.7.1-1 for Python 3.10–3.14
and miniforge releases 26.5.3-0, 26.7.2-0.

Updates Python verification to 3.14 for miniforge3 starting with
26.5.3-0 and adds Linux riscv64 detection for 26.7.2-0.

Ref: https://github.com/conda-forge/miniforge/releases/tag/26.5.3-0
Ref: https://github.com/conda-forge/miniforge/releases/tag/26.7.2-0
Ref: https://www.anaconda.com/docs/getting-started/miniconda/release-notes
2026-09-17 08:20:51 +03:00
native-api
a99ef7fc4e
Backport XCode 27 support to 3.10 (#3549)
Adapted 3.11 downstream patch
2026-09-17 08:20:22 +03:00
native-api
f17a6499b0
Backport XCode 27 support to 3.11 (#3548)
Adapted 3.12 downstream patch
2026-09-17 04:58:50 +03:00
Ivan Pozdeev
36b89575a5 Merge branch 'master' of https://github.com/pyenv/pyenv 2026-09-17 04:47:16 +03:00
Ivan Pozdeev
733afbc04b Add a patch backport script 2026-09-17 04:47:05 +03:00
native-api
3d66ee1fdb
Backport XCode 27 support to 3.12 (#3547)
* Adapted upstream fix (3.13.15): e86913423b
and dependency patch (3.13.14): 7d265b6013
2026-09-17 02:33:37 +03:00
native-api
6c97017989
Backport XCode 27 support to 3.13 (#3546)
* Upstream fix (3.13.15): e86913423b
* Dependency patch (3.13.14): 7d265b6013
2026-09-17 02:31:45 +03:00
native-api
8bd6b02444
Backport XCode 27 support to 3.14 (#3545)
* Upstream fix (3.14.7): 51f6e01941
* Dependency patch (3.14.6): e29411d405

* Test on XCode 27
2026-09-16 20:39:57 +03:00
Ayush
676b71e7b5
pyenv-binary: use xz compression for archives (#3543) 2026-09-15 02:24:23 +03:00
Mingyang Wu
5d43b9a39d
python-build: honor explicitly configured OpenSSL on macOS (#3541)
* python-build: probe OpenSSL from standard dependency discovery

Assisted-by: OpenAI Codex
Signed-off-by: Mingyang Wu <129849514+aprylewu@users.noreply.github.com>
2026-09-15 02:20:52 +03:00
Ayush
eb36c1b1e8
CI: publish Ubuntu binary packages (#3539)
* CI: Add Ubuntu binary publishing workflow
2026-09-11 15:21:26 +03:00
native-api
ef4905cd81
Incorporate the pyenv-link plugin (#3538)
for use in linking binary installations
2026-09-09 02:43:22 +03:00
Ivan Pozdeev
88e9ab13e8 pwsh: Fix error in shell integration if pyenv is on PATH multiple times
Fixes "The term 'pyenv pyenv' is not recognized..."
2026-09-09 02:31:49 +03:00
macayu17
798a1ad603 Incorporate the pyenv-link plugin
* Adapt test_helper for use in plugins
* Add pyenv-link tests
* Add pyenv-link tests to CI
2026-09-09 02:30:53 +03:00
macayu17
fb7f2071fb Add 'plugins/pyenv-link/' from commit '2f8cb2cf1f093e955a72babf0b65a07f84f33522'
git-subtree-dir: plugins/pyenv-link
git-subtree-mainline: ef7a9f5d1417c4ef09d206298f8ec7a284994072
git-subtree-split: 2f8cb2cf1f093e955a72babf0b65a07f84f33522
2026-09-08 02:55:49 +05:30
Michael Newman
ef7a9f5d14
docs: Add link to list of available Python distributions (#3535)
Add a link to the python-build share directory in the intro section
so users can see which Python distributions are supported before
installing pyenv.
2026-09-06 22:14:47 +03:00
Ayush
265b0dcefa
python-build: add build prerequisite installer (#3532) 2026-09-02 17:56:35 +03:00
Michael Šimáček
2548d53706
Update graalpy URLs for 25.3.4.1 (#3533) 2026-09-02 14:47:33 +03:00
Mészáros Máté Róbert
2f8cb2cf1f
Handle osx specific ln option name (#1)
On OSX `ln` does not have `--symbolic` only `-s`.

* bin/pyenv-link-version

---------

Co-authored-by: yfprojects <62463991+real-yfprojects@users.noreply.github.com>
2023-07-07 14:18:02 +00:00
real-yfprojects
b8d8dee191
Fix output
* bin/pyenv-link-version
2023-06-06 16:59:25 +02:00
real-yfprojects
ba9099392a
Fix completions
* bin/pyenv-link
2023-06-06 16:56:16 +02:00
real-yfprojects
d428be59ec
Write README.
* README.md
2023-06-06 16:45:22 +02:00
real-yfprojects
dffc750fa2
Initial implementation
* bin/pyenv-link

* bin/pyenv-link-version
2023-06-06 16:22:52 +02:00
yfprojects
f46b669f1d
Initial commit 2023-06-06 11:09:59 +00:00
252 changed files with 24261 additions and 313 deletions

View File

@ -9,25 +9,23 @@ inputs:
runs: runs:
using: composite using: composite
steps: steps:
# The two OSes differ only in this step.
- if: runner.os == 'macOS'
shell: bash
run: |
#prerequisites
brew install openssl readline sqlite3 xz tcl-tk@8 libb2 zstd
- if: runner.os == 'Linux'
shell: bash
run: |
#prerequisites
sudo apt-get update -q; sudo apt install -yq make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
- shell: bash - shell: bash
run: | run: |
#envvars #envvars
export PYENV_ROOT="$GITHUB_WORKSPACE" export PYENV_ROOT="$GITHUB_WORKSPACE"
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
# The two OSes differ only in this step.
- if: runner.os == 'macOS'
shell: bash
run: |
#prerequisites
brew install openssl readline sqlite3 xz tcl-tk@8 libb2 zstd gdbm
- if: runner.os == 'Linux'
shell: bash
run: |
#prerequisites
pyenv install-prerequisites --all
- shell: bash - shell: bash
run: | run: |
#build #build

View File

@ -96,6 +96,7 @@ jobs:
- macos-15-intel - macos-15-intel
- macos-26 - macos-26
- macos-26-intel - macos-26-intel
- xcode-27
exclude: ${{fromJson(needs.discover_modified_scripts.outputs.versions_macos_build_exclude)}} exclude: ${{fromJson(needs.discover_modified_scripts.outputs.versions_macos_build_exclude)}}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
@ -107,7 +108,7 @@ jobs:
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
- run: | - run: |
#prerequisites #prerequisites
brew install openssl readline sqlite3 xz tcl-tk@8 libb2 zstd brew install openssl readline sqlite3 xz tcl-tk@8 libb2 zstd gdbm
if [[ "${{ matrix.python-version }}" =~ pypy.*-(src|dev) ]]; then if [[ "${{ matrix.python-version }}" =~ pypy.*-(src|dev) ]]; then
export PYENV_BOOTSTRAP_VERSION=pypy2.7-7 export PYENV_BOOTSTRAP_VERSION=pypy2.7-7
echo "PYENV_BOOTSTRAP_VERSION=$PYENV_BOOTSTRAP_VERSION" >> $GITHUB_ENV echo "PYENV_BOOTSTRAP_VERSION=$PYENV_BOOTSTRAP_VERSION" >> $GITHUB_ENV
@ -164,6 +165,7 @@ jobs:
- macos-15-intel - macos-15-intel
- macos-26 - macos-26
- macos-26-intel - macos-26-intel
- xcode-27
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v7 - uses: actions/checkout@v7
@ -220,10 +222,7 @@ jobs:
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
- run: | - run: |
#prerequisites #prerequisites
sudo apt-get update -q; sudo apt-get install -yq make build-essential \ pyenv install-prerequisites --all
libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \
curl llvm libncurses5-dev libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev
if [[ "${{ matrix.python-version }}" =~ pypy.*-(src|dev) ]]; then if [[ "${{ matrix.python-version }}" =~ pypy.*-(src|dev) ]]; then
export PYENV_BOOTSTRAP_VERSION=pypy2.7-7 export PYENV_BOOTSTRAP_VERSION=pypy2.7-7
echo "PYENV_BOOTSTRAP_VERSION=$PYENV_BOOTSTRAP_VERSION" >> $GITHUB_ENV echo "PYENV_BOOTSTRAP_VERSION=$PYENV_BOOTSTRAP_VERSION" >> $GITHUB_ENV
@ -283,10 +282,7 @@ jobs:
echo "_PYTHON_BUILD_FORCE_SKIP_XZ=1" >> $GITHUB_ENV echo "_PYTHON_BUILD_FORCE_SKIP_XZ=1" >> $GITHUB_ENV
- run: | - run: |
#prerequisites #prerequisites
sudo apt-get update -q; sudo apt-get install -yq make build-essential \ pyenv install-prerequisites
libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \
curl libncursesw5-dev \
xz-utils tk-dev libffi-dev liblzma-dev
- run: | - run: |
#build #build
pyenv --debug install ${{ matrix.python-version }} && rc=$? || rc=$? pyenv --debug install ${{ matrix.python-version }} && rc=$? || rc=$?

86
.github/workflows/publish_binary.yml vendored Normal file
View File

@ -0,0 +1,86 @@
name: Publish a binary package
on:
workflow_dispatch:
inputs:
version:
description: A CPython version accepted by `pyenv install`
required: true
type: string
platform:
description: Platform to build on
required: true
type: choice
default: ubuntu-24.04
options:
- ubuntu-24.04
- macos-15
permissions:
contents: read
jobs:
publish:
runs-on: ${{ inputs.platform }}
env:
PYENV_ROOT: ${{ github.workspace }}
VERSION: ${{ inputs.version }}
steps:
- uses: actions/checkout@v7
- name: Install Ubuntu build prerequisites
if: runner.os == 'Linux'
run: ./bin/pyenv install-prerequisites
- name: Install macOS build prerequisites
if: runner.os == 'macOS'
run: brew install openssl readline sqlite3 xz tcl-tk@8 libb2 zstd
- name: Build package
env:
PYTHON_CONFIGURE_OPTS: --enable-optimizations
run: |
VERSION="${VERSION%%:*}"
if [ "$RUNNER_OS" = "macOS" ]; then
entry="${VERSION}-${{ inputs.platform }}-$(uname -m)"
else
entry="$(./bin/pyenv binary package-name "$VERSION")"
fi
echo "entry=$entry" >> "$GITHUB_ENV"
mkdir dist
cd dist
"$GITHUB_WORKSPACE/bin/pyenv" binary package --verbose \
"$VERSION:$entry" \
--archive-base-url https://pyenv.github.io/pythons/binaries
- name: Generate GitHub token
uses: actions/create-github-app-token@v3
id: generate-token
with:
app-id: ${{ vars.PYENV_BOT_APP_ID }}
private-key: ${{ secrets.PYENV_BOT_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: pyenv.github.io
permission-contents: write
permission-pull-requests: write
- uses: actions/checkout@v7
with:
repository: pyenv/pyenv.github.io
token: ${{ steps.generate-token.outputs.token }}
path: site
- name: Update downloads
run: |
mkdir -p site/pythons/binaries
cp "dist/$entry.tar.xz" "dist/$entry.meta" "dist/$entry" \
site/pythons/binaries/
cd site/pythons
./update.sh
- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
with:
path: site
branch: auto_add_binary/${{ env.entry }}
title: Add CPython ${{ env.entry }}
commit-message: Add CPython ${{ env.entry }}
body: |
Built from pyenv/pyenv@${{ github.sha }} with profile-guided optimization enabled.
Part of pyenv/pyenv#2334.
token: ${{ steps.generate-token.outputs.token }}

View File

@ -1,5 +1,43 @@
# Version History # Version History
## Release v2.8.7
* Fix rehash repair of individually corrupted shims by @aprylewu in https://github.com/pyenv/pyenv/pull/3540
* CI: publish Apple Silicon macOS binaries by @macayu17 in https://github.com/pyenv/pyenv/pull/3556
* python-build: create PEP 394 symlinks for Pyston by @dmrlawson in https://github.com/pyenv/pyenv/pull/3557
* Add GraalPy 3.13 25.4.4 by @msimacek in https://github.com/pyenv/pyenv/pull/3558
* python-build: create PEP 394 symlinks for PyPy by @native-api in https://github.com/pyenv/pyenv/pull/3559
* install-prerequisites: add an option for optional dependencies by @native-api in https://github.com/pyenv/pyenv/pull/3560
* python-build: create pypy* symlinks for PyPy by @native-api in https://github.com/pyenv/pyenv/pull/3562
* Add PyPy v7.3.23 by @exurd in https://github.com/pyenv/pyenv/pull/3553
* Add PyPy v7.3.21 by @exurd in https://github.com/pyenv/pyenv/pull/3564
* python-build: Add `add_pypy.py` for pypy versions by @exurd in https://github.com/pyenv/pyenv/pull/3566
* pyenv-binary: install published CPython packages by @macayu17 in https://github.com/pyenv/pyenv/pull/3567
* python-build: show download progress in interactive terminals by @n0tl3ss in https://github.com/pyenv/pyenv/pull/3561
* Fix minimum macOS version check for PyPy v7.3.8+ by @exurd in https://github.com/pyenv/pyenv/pull/3570
* Add PyPy v8.0.0 by @exurd in https://github.com/pyenv/pyenv/pull/3552
* python-build: Speed up permission fix step by @native-api in https://github.com/pyenv/pyenv/pull/3571
* fix(init): honor custom PYENV_ROOT in init setup tips by @r3wretrhy in https://github.com/pyenv/pyenv/pull/3569
* tests: python-build: use helpers from core by @macayu17 in https://github.com/pyenv/pyenv/pull/3572
* Add CPython 3.12.15, 3.13.16 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3575
* Add CPython 3.14.8 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3574
* Add CPython 3.10.22, 3.11.17 by @pyenv-bot[bot] in https://github.com/pyenv/pyenv/pull/3576
## Release v2.8.6
* Update graalpy URLs for 25.3.4.1 by @msimacek in https://github.com/pyenv/pyenv/pull/3533
* python-build: add build prerequisite installer by @macayu17 in https://github.com/pyenv/pyenv/pull/3532
* docs: Add link to list of available Python distributions by @michaelbnewman in https://github.com/pyenv/pyenv/pull/3535
* Incorporate the `pyenv-link` plugin by @macayu17 in https://github.com/pyenv/pyenv/pull/3538
* CI: publish Ubuntu binary packages by @macayu17 in https://github.com/pyenv/pyenv/pull/3539
* python-build: honor explicitly configured OpenSSL on macOS by @aprylewu in https://github.com/pyenv/pyenv/pull/3541
* pyenv-binary: use xz compression for archives by @macayu17 in https://github.com/pyenv/pyenv/pull/3543
* Backport XCode 27 support to 3.14 by @native-api in https://github.com/pyenv/pyenv/pull/3545
* Backport XCode 27 support to 3.13; add missing 3.13.11t by @native-api in https://github.com/pyenv/pyenv/pull/3546
* Backport XCode 27 support to 3.12 by @native-api in https://github.com/pyenv/pyenv/pull/3547
* Backport XCode 27 support to 3.11 by @native-api in https://github.com/pyenv/pyenv/pull/3548
* Backport XCode 27 support to 3.10 by @native-api in https://github.com/pyenv/pyenv/pull/3549
* Add miniconda3 26.7.1-0, 26.7.1-1 and miniforge3 26.5.3-0, 26.7.2-0 by @13steinj in https://github.com/pyenv/pyenv/pull/3550
## Release v2.8.5 ## Release v2.8.5
* pyenv-binary: record direct system dependencies in Linux/FreeBSD by @macayu17 in https://github.com/pyenv/pyenv/pull/3520 * pyenv-binary: record direct system dependencies in Linux/FreeBSD by @macayu17 in https://github.com/pyenv/pyenv/pull/3520
* tests: Fix "cd: null directory" in OpenSUSE by @native-api in https://github.com/pyenv/pyenv/pull/3524 * tests: Fix "cd: null directory" in OpenSUSE by @native-api in https://github.com/pyenv/pyenv/pull/3524

View File

@ -315,7 +315,7 @@ Lists all Python versions with the given command installed.
## `pyenv exec` ## `pyenv exec`
Usage: pyenv exec <command> [arg1 arg2...] Usage: pyenv exec [-N|--environment] <command> [arg1 arg2...]
Runs an executable by first preparing PATH so that the selected Python Runs an executable by first preparing PATH so that the selected Python
version's `bin` directory is at the front. version's `bin` directory is at the front.
@ -326,7 +326,18 @@ For example, if the currently selected Python version is 3.9.7:
is equivalent to: is equivalent to:
PATH="$PYENV_ROOT/versions/3.9.7/bin:$PATH" pip install -r requirements.txt PYENV_VERSION="3.9.7" PATH="$PYENV_ROOT/versions/3.9.7/bin:$PATH" pip install -r requirements.txt
The `--environment` option sets `PYTHONHOME` and `LD_LIBRARY_PATH` (`DYLD_LIBRARY_PATH` in macOS) in the program's environment.
This is needed to run programs that embed Python by loading `libpython` without specifying rpath or an explicit path.
This breaks linking for programs that expect to link to a different `libpython` with the same name as one
in selected Python -- thus it's not done by default.
In macOS, System Integrity Protection (SIP) removes `DYLD_LIBRARY_PATH` from a process' environment
upon `exec` (not `fork`) if the executable being run is protected. The protection covers preinstalled system software
(including preinstalled shells) and does not cover user-installed apps and 3rd-party software. See
[About System Integrity Protection on your Mac - Apple Support](https://support.apple.com/en-us/102149)
for details.
## `pyenv root` ## `pyenv root`

View File

@ -10,11 +10,14 @@ TEST_PYTHON_BUILD_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuf
TEST_BINARY_DOCKER_PREFIX = test-binary-docker TEST_BINARY_DOCKER_PREFIX = test-binary-docker
TEST_BINARY_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_BINARY_DOCKER_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_BINARY_DOCKER_PREFIX))) TEST_BINARY_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_BINARY_DOCKER_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_BINARY_DOCKER_PREFIX)))
TEST_LINK_DOCKER_PREFIX = test-link-docker
TEST_LINK_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_LINK_DOCKER_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_LINK_DOCKER_PREFIX)))
TEST_BATS_IMAGE_PREFIX = test-pyenv-docker-image TEST_BATS_IMAGE_PREFIX = test-pyenv-docker-image
TEST_BATS_IMAGE_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_BATS_IMAGE_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_BATS_IMAGE_PREFIX))) TEST_BATS_IMAGE_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_BATS_IMAGE_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_BATS_IMAGE_PREFIX)))
.PHONY: test-docker .PHONY: test-docker
test-docker: $(TEST_UNIT_DOCKER_PREFIX) $(TEST_PYTHON_BUILD_DOCKER_PREFIX) $(TEST_BINARY_DOCKER_PREFIX) test-docker: $(TEST_UNIT_DOCKER_PREFIX) $(TEST_PYTHON_BUILD_DOCKER_PREFIX) $(TEST_BINARY_DOCKER_PREFIX) $(TEST_LINK_DOCKER_PREFIX)
.PHONY: $(TEST_UNIT_DOCKER_PREFIX) .PHONY: $(TEST_UNIT_DOCKER_PREFIX)
$(TEST_UNIT_DOCKER_PREFIX): $(TEST_UNIT_DOCKER_TARGETS) $(TEST_UNIT_DOCKER_PREFIX): $(TEST_UNIT_DOCKER_TARGETS)
@ -88,6 +91,29 @@ $(TEST_BINARY_DOCKER_TARGETS): $(TEST_BINARY_DOCKER_PREFIX)-% : $(TEST_BATS_IMAG
bats $${CI:+-F "/code/test/libexec/bats-format-tap-suite"} \ bats $${CI:+-F "/code/test/libexec/bats-format-tap-suite"} \
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/pyenv-binary/test/$${BATS_FILE_FILTER} $${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/pyenv-binary/test/$${BATS_FILE_FILTER}
.PHONY: $(TEST_LINK_DOCKER_PREFIX)
$(TEST_LINK_DOCKER_PREFIX): $(TEST_LINK_DOCKER_TARGETS)
.PHONY: $(TEST_LINK_DOCKER_TARGETS)
$(TEST_LINK_DOCKER_TARGETS): DOCKER_IMAGE = $(TEST_BATS_IMAGE_PREFIX)
$(TEST_LINK_DOCKER_TARGETS): GNU = $(if $(findstring -gnu-,$@),True,False)
$(TEST_LINK_DOCKER_TARGETS): BASH = $(filter $(TEST_BASH_VERSIONS),$(subst -, ,$@))
$(TEST_LINK_DOCKER_TARGETS): DOCKER_TAG = bash-$(BASH)-gnu-$(GNU)
$(TEST_LINK_DOCKER_TARGETS): INTERACTIVE = $(if $(findstring true,$(CI)),,-ti)
$(TEST_LINK_DOCKER_TARGETS): $(TEST_LINK_DOCKER_PREFIX)-% : $(TEST_BATS_IMAGE_PREFIX)-%
$(info Running test with docker image '$(DOCKER_IMAGE):$(DOCKER_TAG)')
docker run \
--init \
-v $(PWD):/code:ro \
-v /etc/passwd:/etc/passwd:ro \
-v /etc/group:/etc/group:ro \
-u "$$(id -u $$(whoami)):$$(id -g $$(whoami))" \
$${CI+-e CI="$${CI}"} \
$(INTERACTIVE) \
$(DOCKER_IMAGE):$(DOCKER_TAG) \
bats $${CI:+-F "/code/test/libexec/bats-format-tap-suite"} \
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/pyenv-link/test/$${BATS_FILE_FILTER}
# Build all images needed for bats under docker # Build all images needed for bats under docker
.PHONY: $(TEST_BATS_IMAGE_PREFIX) .PHONY: $(TEST_BATS_IMAGE_PREFIX)
$(TEST_BATS_IMAGE_PREFIX): $(TEST_BATS_IMAGE_TARGETS) $(TEST_BATS_IMAGE_PREFIX): $(TEST_BATS_IMAGE_TARGETS)
@ -110,13 +136,13 @@ $(TEST_BATS_IMAGE_TARGETS):
./ ; \ ./ ; \
fi fi
.PHONY: test test-unit test-python-build test-binary .PHONY: test test-unit test-python-build test-binary test-link
# Do not pass in user flags to build tests. # Do not pass in user flags to build tests.
unexport PYTHON_CFLAGS unexport PYTHON_CFLAGS
unexport PYTHON_CONFIGURE_OPTS unexport PYTHON_CONFIGURE_OPTS
test: test-unit test-python-build test-binary test: test-unit test-python-build test-binary test-link
test-unit: bats test-unit: bats
PATH="./bats/bin:$$PATH" test/run PATH="./bats/bin:$$PATH" test/run
@ -129,6 +155,10 @@ test-binary: bats
cd plugins/pyenv-binary && $(PWD)/bats/bin/bats $${CI:+-F "$(PWD)/test/libexec/bats-format-tap-suite"} \ cd plugins/pyenv-binary && $(PWD)/bats/bin/bats $${CI:+-F "$(PWD)/test/libexec/bats-format-tap-suite"} \
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER} $${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER}
test-link: bats
cd plugins/pyenv-link && $(PWD)/bats/bin/bats $${CI:+-F "$(PWD)/test/libexec/bats-format-tap-suite"} \
$${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER}
.SECONDARY: bats-$(TEST_BATS_VERSION) .SECONDARY: bats-$(TEST_BATS_VERSION)
bats-$(TEST_BATS_VERSION): bats-$(TEST_BATS_VERSION):
git clone --depth 1 --branch $(TEST_BATS_VERSION) https://github.com/bats-core/bats-core.git bats-$(TEST_BATS_VERSION) git clone --depth 1 --branch $(TEST_BATS_VERSION) https://github.com/bats-core/bats-core.git bats-$(TEST_BATS_VERSION)

View File

@ -13,6 +13,8 @@ This project was forked from [rbenv](https://github.com/rbenv/rbenv) and
* Lets you **change the global Python version** on a per-user basis. * Lets you **change the global Python version** on a per-user basis.
* Provides support for **per-project Python versions**. * Provides support for **per-project Python versions**.
* Supports **multiple Python distributions**: CPython, PyPy, Stackless Python, Jython, and more.
See the [full list of available versions](https://github.com/pyenv/pyenv/tree/master/plugins/python-build/share/python-build).
* Allows you to **override the Python version** with an environment * Allows you to **override the Python version** with an environment
variable. variable.
* Searches for commands from **multiple versions of Python at a time**. * Searches for commands from **multiple versions of Python at a time**.
@ -307,6 +309,7 @@ Though we don't actively maintain those patches, since existing releases never c
it's safe to assume that they will continue working until there are further incompatible changes it's safe to assume that they will continue working until there are further incompatible changes
in a later version of those environments. in a later version of those environments.
* *3.10.x-3.14.x* : XCode 27
* *3.7.8-3.7.15, 3.8.4-3.8.12, 3.9.0-3.9.7* : XCode 13.3 * *3.7.8-3.7.15, 3.8.4-3.8.12, 3.9.0-3.9.7* : XCode 13.3
* *3.5.10, 3.6.15* : MacOS 11+ and XCode 13.3 * *3.5.10, 3.6.15* : MacOS 11+ and XCode 13.3
* *2.7.18* : MacOS 10.15+ and Apple Silicon * *2.7.18* : MacOS 10.15+ and Apple Silicon

View File

@ -12,7 +12,7 @@
set -e set -e
[ -n "$PYENV_DEBUG" ] && set -x [ -n "$PYENV_DEBUG" ] && set -x
version="2.8.5" version="2.8.7"
git_revision="" git_revision=""
if cd "${BASH_SOURCE%/*}" 2>/dev/null && git remote -v 2>/dev/null | grep -q pyenv; then if cd "${BASH_SOURCE%/*}" 2>/dev/null && git remote -v 2>/dev/null | grep -q pyenv; then

View File

@ -2,7 +2,17 @@
# #
# Summary: Run an executable with the selected Python version # Summary: Run an executable with the selected Python version
# #
# Usage: pyenv exec <command> [arg1 arg2...] # Usage: pyenv exec [-N|--environment] <command> [arg1 arg2...]
#
# -N/--environment Set PYTHONHOME and LD_LIBRARY_PATH (DYLD_LIBRARY_PATH in macOS)
# envvars for the running command.
# This allows to run programs that embed Python without using rpath or
# exact library path to libpython.
# WARNING: For the running command and its child processes, this will
# break linkage for programs that expect to be linked to a different
# libpython instance with the same name!
# WARNING: In macOS, DYLD_LIBRARY_PATH will be unset by the system for
# processes covered by System Integrity Protection.
# #
# Runs an executable by first preparing PATH so that the selected Python # Runs an executable by first preparing PATH so that the selected Python
# version's `bin' directory is at the front. # version's `bin' directory is at the front.
@ -18,9 +28,16 @@ set -e
# Provide pyenv completions # Provide pyenv completions
if [ "$1" = "--complete" ]; then if [ "$1" = "--complete" ]; then
echo --environment
exec pyenv-shims --short exec pyenv-shims --short
fi fi
unset MODIFY_ENV
if [ "$1" = "-N" ] || [ "$1" = "--environment" ]; then
MODIFY_ENV=true
shift
fi
PYENV_VERSION="$(pyenv-version-name -f)" PYENV_VERSION="$(pyenv-version-name -f)"
PYENV_COMMAND="$1" PYENV_COMMAND="$1"
@ -54,4 +71,27 @@ if [ "${PYENV_BIN_PATH#${PYENV_ROOT}}" != "${PYENV_BIN_PATH}" ]; then
# Only add to $PATH for non-system version. # Only add to $PATH for non-system version.
export PATH="${PYENV_BIN_PATH}:${PATH}" export PATH="${PYENV_BIN_PATH}:${PATH}"
fi fi
if [ -n "$MODIFY_ENV" ]; then
# Check if multiple Python versions are selected
VERSIONS=$(pyenv-prefix)
if [[ "$VERSIONS" == *:* ]]; then
VERSION="${VERSIONS%%:*}"
echo "pyenv: Warning: multiple Python versions are selected." \
"Setting environment variables for the first one, (${VERSION#$PYENV_ROOT})" >&2
else
VERSION="$VERSIONS"
fi
# Assign the correct version of PYTHONHOME
export PYTHONHOME="$VERSION"
case "$(uname -s)" in
Darwin)
export DYLD_LIBRARY_PATH="${PYTHONHOME}/lib${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}"
;;
*)
export LD_LIBRARY_PATH="${PYTHONHOME}/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
;;
esac
fi
exec "$PYENV_COMMAND_PATH" "$@" exec "$PYENV_COMMAND_PATH" "$@"

View File

@ -189,8 +189,76 @@ function help_() {
} >&2 } >&2
} }
# True when tips/install should keep the portable default root form.
function pyenv_root_is_default() {
[[ ${PYENV_ROOT} == "${HOME}/.pyenv" ]]
}
# Escape a value for inclusion inside double quotes in a POSIX shell script.
function escape_for_double_quoted_posix() {
local s="$1"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
s="${s//\`/\\\`}"
printf '%s' "$s"
}
# Escape a value for inclusion inside double quotes in a fish script.
function escape_for_double_quoted_fish() {
local s="$1"
s="${s//\\/\\\\}"
s="${s//\"/\\\"}"
s="${s//\$/\\\$}"
printf '%s' "$s"
}
# Escape a value for inclusion inside single quotes in a PowerShell script.
function escape_for_single_quoted_pwsh() {
local s="$1"
# Bash 3.2 (macOS / CI docker): avoid \' in ${//} replacement —
# it becomes a literal backslash. Double single-quotes via a var instead.
local q="'"
s="${s//${q}/${q}${q}}"
printf '%s' "$s"
}
# Emit the PYENV_ROOT assignment line for tips/--install (posix|fish|pwsh).
# Portable default keeps $HOME / $Env:HOME; custom roots are quoted per target shell.
function print_pyenv_root_assignment() {
case "$1" in
posix )
if pyenv_root_is_default; then
echo 'export PYENV_ROOT="$HOME/.pyenv"'
else
printf 'export PYENV_ROOT="%s"\n' "$(escape_for_double_quoted_posix "${PYENV_ROOT}")"
fi
;;
fish )
if pyenv_root_is_default; then
# Keep master's expandable $HOME form (fish expands unquoted $HOME).
echo 'set -Ux PYENV_ROOT $HOME/.pyenv'
else
printf 'set -Ux PYENV_ROOT "%s"\n' "$(escape_for_double_quoted_fish "${PYENV_ROOT}")"
fi
;;
pwsh )
if pyenv_root_is_default; then
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"'
else
# Single-quoted PowerShell literal: no $ / backtick expansion.
printf "\$Env:PYENV_ROOT='%s'\n" "$(escape_for_single_quoted_pwsh "${PYENV_ROOT}")"
fi
;;
* )
echo "pyenv: internal error: unknown shell family for PYENV_ROOT assignment: $1" >&2
return 1
;;
esac
}
function print_posix_shell_setup() { function print_posix_shell_setup() {
echo 'export PYENV_ROOT="$HOME/.pyenv"' print_pyenv_root_assignment posix
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"'
echo 'eval "$(pyenv init - '$shell')"' echo 'eval "$(pyenv init - '$shell')"'
} }
@ -200,7 +268,7 @@ function print_fish_shell_setup() {
} }
function print_fish_user_path_setup() { function print_fish_user_path_setup() {
echo 'set -Ux PYENV_ROOT $HOME/.pyenv' print_pyenv_root_assignment fish
echo 'if functions -q fish_add_path' echo 'if functions -q fish_add_path'
echo ' test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin' echo ' test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin'
echo 'else' echo 'else'
@ -209,7 +277,7 @@ function print_fish_user_path_setup() {
} }
function print_pwsh_shell_setup() { function print_pwsh_shell_setup() {
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"' print_pyenv_root_assignment pwsh
echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {' echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {'
echo ' $Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }' echo ' $Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }'
echo 'iex ((pyenv init -) -join "`n")' echo 'iex ((pyenv init -) -join "`n")'
@ -473,12 +541,12 @@ function pyenv {
} }
if ( ("${commands[*]}" -split ' ') -contains \$command ) { if ( ("${commands[*]}" -split ' ') -contains \$command ) {
\$shell_cmds = (& (get-command -commandtype application pyenv) sh-\$command \$args) \$shell_cmds = (& (get-command -commandtype application pyenv -totalcount 1) sh-\$command \$args)
if ( \$shell_cmds.Count -gt 0 ) { if ( \$shell_cmds.Count -gt 0 ) {
iex (\$shell_cmds -join "\`n") iex (\$shell_cmds -join "\`n")
} }
} else { } else {
& (get-command -commandtype application pyenv) \$command \$args & (get-command -commandtype application pyenv -totalcount 1) \$command \$args
} }
} }
EOS EOS

View File

@ -80,10 +80,8 @@ fi
unset tested_for_other_write_errors unset tested_for_other_write_errors
# The prototype shim file is a script that re-execs itself, passing # The prototype shim file is a script that re-execs itself, passing
# its filename and any arguments to `pyenv exec`. This file is # its filename and any arguments to `pyenv exec`. This file is copied
# hard-linked for every executable and then removed. The linking # for every executable and then removed. It also serves as a lock.
# technique is fast, uses less disk space than unique files, and also
# serves as a locking mechanism.
create_prototype_shim() { create_prototype_shim() {
cat > "$PROTOTYPE_SHIM_PATH" <<SH cat > "$PROTOTYPE_SHIM_PATH" <<SH
#!/usr/bin/env bash #!/usr/bin/env bash
@ -100,18 +98,30 @@ fi
exec "$(command -v pyenv)" exec "\$program" "\$@" exec "$(command -v pyenv)" exec "\$program" "\$@"
SH SH
chmod +x "$PROTOTYPE_SHIM_PATH" chmod +x "$PROTOTYPE_SHIM_PATH"
local LC_ALL=C
IFS= read -r -d '' PROTOTYPE_SHIM_CONTENTS < "$PROTOTYPE_SHIM_PATH" || true
PROTOTYPE_SHIM_READ_SIZE=$((${#PROTOTYPE_SHIM_CONTENTS} + 1))
} }
# If the contents of the prototype shim file differ from the contents # Install a shim when it is first registered, replacing an existing copy
# of the first shim in the shims directory, assume pyenv has been # if it was overwritten. Hooks can then customize it without a later
# upgraded and the existing shims need to be removed. # registration overwriting their changes.
remove_outdated_shims() { install_shims() {
local shim local shim file shim_contents
for shim in "$SHIM_PATH"/*; do # Count bytes consistently across Bash versions, including multibyte paths.
if ! diff "$PROTOTYPE_SHIM_PATH" "$shim" >/dev/null 2>&1; then local LC_ALL=C
rm -f "$SHIM_PATH"/* for shim; do
file="${SHIM_PATH}/${shim}"
if [[ -f "$file" || ( -L "$file" && ! -e "$file" ) ]]; then
shim_contents=
# Read with a builtin to avoid a subprocess per shim. A successful
# read means a NUL or extra character was found. Limit the read in
# case a large file was accidentally written over a shim.
if IFS= read -r -d '' -n "$PROTOTYPE_SHIM_READ_SIZE" shim_contents 2>/dev/null < "$file" || [[ $shim_contents != "$PROTOTYPE_SHIM_CONTENTS" ]]; then
rm -f "$file"
fi
fi fi
break [ -e "$file" ] || cp "$PROTOTYPE_SHIM_PATH" "$file"
done done
} }
@ -132,7 +142,10 @@ if ((${BASH_VERSINFO[0]} > 3)); then
# Registers the name of a shim to be generated. # Registers the name of a shim to be generated.
register_shim() { register_shim() {
registered_shims["$1"]=1 if [[ ! ${registered_shims["$1"]} ]]; then
install_shims "$1"
registered_shims["$1"]=1
fi
} }
# Install all shims registered via `make_shims` or `register_shim` directly. # Install all shims registered via `make_shims` or `register_shim` directly.
@ -162,7 +175,10 @@ else # Same for bash < 4.
registered_shims=" " registered_shims=" "
register_shim() { register_shim() {
registered_shims="${registered_shims}${1} " if [[ "$registered_shims" != *" ${1} "* ]]; then
install_shims "$1"
registered_shims="${registered_shims}${1} "
fi
} }
install_registered_shims() { install_registered_shims() {
@ -188,7 +204,6 @@ shopt -s nullglob
# Create the prototype shim, then register shims for all known # Create the prototype shim, then register shims for all known
# executables. # executables.
create_prototype_shim create_prototype_shim
remove_outdated_shims
# shellcheck disable=SC2046 # shellcheck disable=SC2046
make_shims $(pyenv-versions --executables) make_shims $(pyenv-versions --executables)

1
plugins/.gitignore vendored
View File

@ -3,4 +3,5 @@
!/version-ext-compat !/version-ext-compat
!/python-build !/python-build
!/pyenv-binary !/pyenv-binary
!/pyenv-link
/python-build/test/build /python-build/test/build

View File

@ -14,8 +14,30 @@ architecture and a compatible libc) and have the recorded system libraries. It
is not portable across, say, glibc and musl, or to an older glibc; the platform is not portable across, say, glibc and musl, or to an older glibc; the platform
and dependency metadata exist to catch that. and dependency metadata exist to catch that.
Installing a binary package requires `tar` with xz support (typically provided
by the `xz` package).
## Commands ## Commands
### `pyenv binary install <version>`
Installs a matching published package from pyenv.github.io under `<version>`.
The command selects by OS, architecture and distribution; on macOS, an archive
built on an older major release can also be used. Available packages and their
definition checksums are recorded in `share/pyenv-binary/versions`. Add an entry
there when publishing a new package. The definition checks its system-library
requirements when an `ldconfig` cache is available; otherwise, it warns and
proceeds.
```sh
pyenv binary install 3.14.7
```
A definition with the selected package entry's name in a plugin's
`share/python-build` directory overrides the published definition. The normal
Python-Build search order applies, including `PYTHON_BUILD_DEFINITIONS`.
Local definitions are installed without downloading the stock definition.
### `pyenv binary package [-v|--verbose] <version>[:<entry>] --archive-base-url <url>` ### `pyenv binary package [-v|--verbose] <version>[:<entry>] --archive-base-url <url>`
Installs `<version>` from source under a separate name, packages that install Installs `<version>` from source under a separate name, packages that install
@ -29,7 +51,7 @@ Pass `-v` to show build progress from `pyenv install`.
```sh ```sh
pyenv binary package 3.12.7 \ pyenv binary package 3.12.7 \
--archive-base-url https://example.com/binaries --archive-base-url https://example.com/binaries
# On Debian 12 x86_64, writes 3.12.7-debian-12-x86_64.tar.gz, # On Debian 12 x86_64, writes 3.12.7-debian-12-x86_64.tar.xz,
# its .meta file and a `3.12.7-debian-12-x86_64' definition. # its .meta file and a `3.12.7-debian-12-x86_64' definition.
pyenv binary package 3.12.7:company-python \ pyenv binary package 3.12.7:company-python \
@ -52,12 +74,13 @@ pyenv binary package-name 3.12.7
# 3.12.7-debian-12-x86_64 # 3.12.7-debian-12-x86_64
``` ```
### `pyenv binary save <version> [<output-dir>] [--name <name>]` ### `pyenv binary save <version> [<output-dir>] [--name <name>] [--source-version <version>]`
Packs an installed version into `<version>-<platform>.tar.gz` (relative paths) Packs an installed version into `<version>-<platform>.tar.xz` (relative paths)
and writes `<version>-<platform>.meta` describing the build platform (OS, arch, and writes `<version>-<platform>.meta` describing the build platform (OS, arch,
distro and libc version) and the system libraries the build links against. Use distro and libc version) and the system libraries the build links against. Use
`--name` to set a different base name for both files. `--name` to set a different base name for both files. `--source-version` records
the source version when the installed version has a different name.
```sh ```sh
pyenv binary save 3.12.7 ./dist pyenv binary save 3.12.7 ./dist
@ -78,17 +101,18 @@ needs are present.
```sh ```sh
pyenv binary generate-installer ./dist/3.12.7-linux-x86_64.meta \ pyenv binary generate-installer ./dist/3.12.7-linux-x86_64.meta \
--archive-url https://example.com/3.12.7-linux-x86_64.tar.gz \ --archive-url https://example.com/3.12.7-linux-x86_64.tar.xz \
-o "$(pyenv root)/plugins/python-build/share/python-build/3.12.7-linux-x86_64" -o "$(pyenv root)/plugins/python-build/share/python-build/3.12.7-linux-x86_64"
pyenv install 3.12.7-linux-x86_64 pyenv install 3.12.7-linux-x86_64
``` ```
### `pyenv binary relocate <prefix>` ### `pyenv binary relocate <prefix> [<build-prefix>]`
Rewrites the rpaths of a Python tree unpacked into `<prefix>` so the interpreter Rewrites the rpaths of a Python tree unpacked into `<prefix>` so the interpreter
and its extension modules load the bundled libraries from there rather than from and its extension modules load the bundled libraries from there rather than from
the path the archive was built at. Uses `patchelf`. The generated definition the path the archive was built at. Linux and FreeBSD use `patchelf`; macOS
calls this; you rarely run it by hand. requires the original `<build-prefix>`. The generated definition calls this;
you rarely run it by hand.
Relocation is implemented for Linux; macOS is not wired up yet. Relocation is implemented for Linux, FreeBSD and macOS.

View File

@ -0,0 +1,130 @@
#!/usr/bin/env bash
#
# Summary: Install a published binary package
#
# Usage: pyenv binary install <version>
#
# Selects a compatible package from pyenv.github.io and installs it under
# <version>. Ordinary `pyenv install' is unchanged.
#
set -e
[ -n "$PYENV_DEBUG" ] && set -x
if [ "$1" = "--complete" ]; then
exit
fi
if [ "$#" -ne 1 ]; then
pyenv-help --usage binary-install >&2
exit 1
fi
case "$1" in
*/* | .. | . | *[[:cntrl:]]* )
echo "pyenv-binary: invalid version name \`$1'" >&2
exit 1
;;
esac
requested="$1"
os="$(uname -s)"
arch="$(uname -m)"
case "$os" in
Linux )
if [ -r /etc/os-release ]; then
distro="$(. /etc/os-release && printf '%s %s' "${ID:-}" "${VERSION_ID:-}")"
elif type -p lsb_release >/dev/null; then
distro="$(lsb_release -si) $(lsb_release -sr)"
fi
distro="$(printf '%s' "$distro" | tr '[:upper:]' '[:lower:]')"
;;
Darwin )
distro="macos $(sw_vers -productVersion)"
;;
esac
tmpdir="$(mktemp -d)"
trap 'rm -rf "$tmpdir"' EXIT
base_url="https://pyenv.github.io/pythons/binaries"
manifest_dir="$(dirname "${BASH_SOURCE[0]}")/../share/pyenv-binary/versions"
case "$requested" in
*.*.* ) manifests=( "$manifest_dir/${requested%.*}" ) ;;
*.* ) manifests=( "$manifest_dir/$requested" ) ;;
* ) manifests=( "$manifest_dir/$requested".* ) ;;
esac
matches="$tmpdir/matches"
: > "$matches"
for manifest in "${manifests[@]}"; do
[ -f "$manifest" ] || continue
while IFS=$'\t' read -r source_version name target_os target_arch target_distro sha256; do
case "$source_version" in
"$requested" | "$requested".* ) ;;
* ) continue ;;
esac
[[ "$source_version" =~ ^[0-9]+(\.[0-9]+){1,2}$ ]] || continue
[ "$target_os" = "$os" ] && [ "$target_arch" = "$arch" ] || continue
case "$name" in
"" | . | .. | *[!A-Za-z0-9._-]* ) continue ;;
esac
case "$os" in
Linux ) [ "$(printf '%s' "$target_distro" | tr '[:upper:]' '[:lower:]')" = "$distro" ] || continue ;;
Darwin )
target_version="${target_distro#macos }"
[ "$target_version" != "$target_distro" ] || continue
host_version="${distro#macos }"
[[ "$target_version" =~ ^[0-9]+(\.[0-9]+){1,2}$ ]] || continue
[[ "$host_version" =~ ^[0-9]+(\.[0-9]+){1,2}$ ]] || continue
IFS=. read -r target_major target_minor target_patch <<< "$target_version"
IFS=. read -r host_major host_minor host_patch <<< "$host_version"
target_patch="${target_patch:-0}"
host_patch="${host_patch:-0}"
[ "$host_major" -ge "$target_major" ] || continue
if [ "$host_major" -eq "$target_major" ]; then
[ "$host_minor" -ge "$target_minor" ] || continue
if [ "$host_minor" -eq "$target_minor" ]; then
[ "$host_patch" -ge "$target_patch" ] || continue
fi
fi
;;
* ) continue ;;
esac
printf '%s\t%s\t%s\n' "$source_version" "$name" "$sha256" >> "$matches"
done < "$manifest"
done
selection="$(sort -t. -k1,1nr -k2,2nr -k3,3nr "$matches" | head -n1)"
IFS=$'\t' read -r version entry expected_sha <<< "$selection"
if [ -z "$entry" ]; then
echo "pyenv-binary: no binary available for $requested on $os/$arch" >&2
exit 1
fi
definitions="$(pyenv-install --list --bare)" || definitions=""
if printf '%s\n' "$definitions" | grep -qxF -- "$entry"; then
pyenv-install "$entry:$version"
exit
fi
if ! [[ "$expected_sha" =~ ^[0-9a-fA-F]{64}$ ]]; then
echo "pyenv-binary: invalid checksum for $entry" >&2
exit 1
fi
expected_sha="$(printf '%s' "$expected_sha" | tr '[:upper:]' '[:lower:]')"
curl -fsSL -o "$tmpdir/$entry" "$base_url/$entry"
if command -v sha256sum >/dev/null 2>&1; then
actual_sha="$(sha256sum "$tmpdir/$entry")"; actual_sha="${actual_sha%% *}"
elif command -v shasum >/dev/null 2>&1; then
actual_sha="$(shasum -a 256 "$tmpdir/$entry")"; actual_sha="${actual_sha%% *}"
elif command -v openssl >/dev/null 2>&1; then
actual_sha="$(openssl dgst -sha256 "$tmpdir/$entry")"; actual_sha="${actual_sha##* }"
else
echo "pyenv-binary: need sha256sum, shasum or openssl to verify $entry" >&2
exit 1
fi
if [ "$actual_sha" != "$expected_sha" ]; then
echo "pyenv-binary: checksum mismatch for $entry" >&2
exit 1
fi
pyenv-install "$tmpdir/$entry:$version"

View File

@ -7,7 +7,7 @@
# Installs <version> from source under a separate entry name, saves it as a # Installs <version> from source under a separate entry name, saves it as a
# binary package, then emits a python-build definition for that package. # binary package, then emits a python-build definition for that package.
# The archive, metadata and definition are written to the current directory # The archive, metadata and definition are written to the current directory
# as <entry>.tar.gz, <entry>.meta and <entry>. # as <entry>.tar.xz, <entry>.meta and <entry>.
# #
# <version> A version `pyenv install' knows how to build. # <version> A version `pyenv install' knows how to build.
# <entry> The optional name to build under and install the # <entry> The optional name to build under and install the
@ -16,7 +16,7 @@
# -v,--verbose Show build progress from `pyenv install'. # -v,--verbose Show build progress from `pyenv install'.
# --archive-base-url <url> # --archive-base-url <url>
# Where the archive will be hosted; the definition # Where the archive will be hosted; the definition
# downloads it from <url>/<entry>.tar.gz. # downloads it from <url>/<entry>.tar.xz.
# #
set -e set -e
[ -n "$PYENV_DEBUG" ] && set -x [ -n "$PYENV_DEBUG" ] && set -x
@ -77,7 +77,9 @@ esac
# `pyenv install' puts a `<version>:<alias>' build under versions/<alias>. # `pyenv install' puts a `<version>:<alias>' build under versions/<alias>.
pyenv-install ${verbose:+--verbose} "$spec" pyenv-install ${verbose:+--verbose} "$spec"
pyenv-binary-save "$entry" "$PWD" --name "$entry" source_version="$(pyenv-latest -f -k "${spec%%:*}")"
source_version="${source_version##*/}"
pyenv-binary-save "$entry" "$PWD" --name "$entry" --source-version "$source_version"
pyenv-binary-generate-installer "${entry}.meta" \ pyenv-binary-generate-installer "${entry}.meta" \
--archive-url "${archive_base_url%/}/${entry}.tar.gz" -o "$entry" --archive-url "${archive_base_url%/}/${entry}.tar.xz" -o "$entry"

View File

@ -100,6 +100,22 @@ if [ "$(uname -s)" = "Darwin" ]; then
while IFS= read -r so; do while IFS= read -r so; do
relocate_macho "$so" '@loader_path/../..' relocate_macho "$so" '@loader_path/../..'
done < <(find "$prefix" -type f -path '*/lib/python*/lib-dynload/*.so') done < <(find "$prefix" -type f -path '*/lib/python*/lib-dynload/*.so')
# CPython records its installation prefix in generated scripts and build
# metadata. Bytecode can also retain source filenames from the build tree.
build_prefix_pattern="$(printf '%s\n' "$build_prefix" | sed 's/[][\\.^$*|]/\\&/g')"
prefix_replacement="$(printf '%s\n' "$prefix" | sed 's/[\\&|]/\\&/g')"
while IFS= read -r file; do
if LC_ALL=C grep -IqF "$build_prefix" "$file"; then
sed -i.bak "s|${build_prefix_pattern}|${prefix_replacement}|g" "$file"
rm -f "${file}.bak"
fi
done < <(find "$prefix" -type f ! -name '*.pyc' ! -name '*.pyo')
while IFS= read -r file; do
if LC_ALL=C grep -aqF "$build_prefix" "$file"; then
rm -f "$file"
fi
done < <(find "$prefix" -type f \( -name '*.pyc' -o -name '*.pyo' \))
exit exit
fi fi

View File

@ -2,9 +2,9 @@
# #
# Summary: Save an installed Python version as a relocatable archive # Summary: Save an installed Python version as a relocatable archive
# #
# Usage: pyenv binary save <version> [<output-dir>] [--name <name>] # Usage: pyenv binary save <version> [<output-dir>] [--name <name>] [--source-version <version>]
# #
# Packs an installed version into a relocatable .tar.gz (relative paths) and # Packs an installed version into a relocatable .tar.xz (relative paths) and
# writes a metadata file listing the build platform and the system libraries # writes a metadata file listing the build platform and the system libraries
# it links against, so an installer can check compatibility before unpacking. # it links against, so an installer can check compatibility before unpacking.
# #
@ -12,6 +12,7 @@
# <output-dir> Where to write the archive and metadata (default: `.'). # <output-dir> Where to write the archive and metadata (default: `.').
# --name <name> Use <name> as the archive and metadata base name instead of # --name <name> Use <name> as the archive and metadata base name instead of
# <version>-<platform>. # <version>-<platform>.
# --source-version <version> Record the version used to build a renamed install.
# #
set -e set -e
[ -n "$PYENV_DEBUG" ] && set -x [ -n "$PYENV_DEBUG" ] && set -x
@ -19,18 +20,23 @@ set -e
# Provide pyenv completions # Provide pyenv completions
if [ "$1" = "--complete" ]; then if [ "$1" = "--complete" ]; then
echo --name echo --name
echo --source-version
exec pyenv-versions --bare exec pyenv-versions --bare
fi fi
version="" version=""
output_dir="" output_dir=""
package_name="" package_name=""
source_version=""
while [ $# -gt 0 ]; do while [ $# -gt 0 ]; do
case "$1" in case "$1" in
--name ) --name )
[ $# -ge 2 ] && [ -n "$2" ] || { echo "pyenv-binary: --name needs a value" >&2; exit 1; } [ $# -ge 2 ] && [ -n "$2" ] || { echo "pyenv-binary: --name needs a value" >&2; exit 1; }
package_name="$2"; shift 2 ;; package_name="$2"; shift 2 ;;
--source-version )
[ $# -ge 2 ] && [ -n "$2" ] && [ "${2#-}" = "$2" ] || { echo "pyenv-binary: --source-version needs a value" >&2; exit 1; }
source_version="$2"; shift 2 ;;
-* ) -* )
echo "pyenv-binary: unknown option \`$1'" >&2; exit 1 ;; echo "pyenv-binary: unknown option \`$1'" >&2; exit 1 ;;
* ) * )
@ -49,7 +55,7 @@ done
output_dir="${output_dir:-$PWD}" output_dir="${output_dir:-$PWD}"
if [ -z "$version" ]; then if [ -z "$version" ]; then
echo "Usage: pyenv binary save <version> [<output-dir>] [--name <name>]" >&2 echo "Usage: pyenv binary save <version> [<output-dir>] [--name <name>] [--source-version <version>]" >&2
exit 1 exit 1
fi fi
@ -69,6 +75,14 @@ case "$package_name" in
;; ;;
esac esac
source_version="${source_version:-$version}"
case "$source_version" in
*/* | .. | . | *[[:cntrl:]]* )
echo "pyenv-binary: invalid source version \`${source_version}'" >&2
exit 1
;;
esac
prefix="${PYENV_ROOT}/versions/${version}" prefix="${PYENV_ROOT}/versions/${version}"
if [ ! -d "${prefix}/bin" ]; then if [ ! -d "${prefix}/bin" ]; then
echo "pyenv-binary: version \`${version}' is not installed" >&2 echo "pyenv-binary: version \`${version}' is not installed" >&2
@ -134,14 +148,15 @@ system_deps() {
mkdir -p "$output_dir" mkdir -p "$output_dir"
package_name="${package_name:-${version}-${platform}}" package_name="${package_name:-${version}-${platform}}"
archive="${package_name}.tar.gz" archive="${package_name}.tar.xz"
metadata="${package_name}.meta" metadata="${package_name}.meta"
tar -C "$(dirname "$prefix")" -czf "${output_dir}/${archive}" "$(basename "$prefix")" tar -C "$(dirname "$prefix")" -cJf "${output_dir}/${archive}" "$(basename "$prefix")"
{ {
echo "# pyenv-binary metadata" echo "# pyenv-binary metadata"
echo "version=${version}" echo "version=${version}"
echo "source_version=${source_version}"
echo "os=${os}" echo "os=${os}"
echo "arch=${arch}" echo "arch=${arch}"
echo "platform=${platform}" echo "platform=${platform}"

View File

@ -0,0 +1,3 @@
source_version entry os arch distro sha256
3.14.7 3.14.7-macos-15-arm64 Darwin arm64 macos 15.7.9 8a8ff86b520c3b5da00b49e04a5345b7a28f2f9e8da5a9ae43b8ac309e8f3e55
3.14.7 3.14.7-ubuntu-24.04-x86_64 Linux x86_64 ubuntu 24.04 e63dbcb981ec9ba83a2bc9b4d8b369620cec4aa45394559d719c5606ee9ff718

View File

@ -0,0 +1,203 @@
#!/usr/bin/env bats
load test_helper
host_distro() {
if [ -r /etc/os-release ]; then
. /etc/os-release
printf '%s %s' "$ID" "$VERSION_ID" | tr '[:upper:]' '[:lower:]'
else
printf '%s %s' "$(lsb_release -si)" "$(lsb_release -sr)" | tr '[:upper:]' '[:lower:]'
fi
}
use_manifest() {
local plugin="${BATS_TEST_TMPDIR}/plugin"
mkdir -p "$plugin/libexec" "$plugin/share/pyenv-binary/versions"
cp "${BATS_TEST_DIRNAME}/../libexec/pyenv-binary-install" "$plugin/libexec/"
PATH="$plugin/libexec:$PATH"
printf 'source_version\tentry\tos\tarch\tdistro\tsha256\n' > "$plugin/share/pyenv-binary/versions/3.14"
definition_sha="4c4ed1afbfdaa1e4c3bf7bbb82d730cecb7e384da91eea4f3cc093fd545524d6"
}
stub_downloads() {
create_stub curl <<'STUB'
output=""
while [ "$#" -gt 0 ]; do
case "$1" in
-o ) output="$2"; shift ;;
http* ) url="$1" ;;
esac
shift
done
case "$url" in
*/3.14.7-ubuntu-24.04-x86_64 | */3.14.7-macos-15-arm64 | */3.14.10-ubuntu-24.04-x86_64 ) printf definition > "$output" ;;
* ) exit 1 ;;
esac
STUB
}
@test "rejects a modified published definition" {
create_stub lsb_release 'case "$1" in -si) echo Ubuntu;; -sr) echo 24.04;; esac'
use_manifest
printf '3.14.7\t3.14.7-ubuntu-24.04-x86_64\tLinux\tx86_64\t%s\t%064d\n' \
"$(host_distro)" 0 >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
stub_downloads
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub pyenv-install '[ "$1" = --list ] && exit; echo installed'
run pyenv-binary-install 3.14.7
assert_failure
[[ "$output" == *'checksum mismatch'* ]]
}
@test "completion does not offer source-only versions" {
create_stub pyenv-install 'echo 3.14.7'
run pyenv-binary-install --complete
assert_success ""
}
@test "a plugin definition overrides a published binary without its checksum" {
create_stub lsb_release 'case "$1" in -si) echo Ubuntu;; -sr) echo 24.04;; esac'
use_manifest
export TMPDIR="$BATS_TEST_TMPDIR/temp"
mkdir -p "$TMPDIR"
local entry="3.14.7-ubuntu-24.04-x86_64"
printf '3.14.7\t%s\tLinux\tx86_64\t%s\t%s\n' "$entry" \
"$(host_distro)" "" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub curl 'touch "$BATS_TEST_TMPDIR/downloaded"; exit 1'
PATH="${BATS_TEST_DIRNAME}/../../python-build/bin:$PATH"
mkdir -p "$PYENV_ROOT/plugins/first/share/python-build" "$PYENV_ROOT/plugins/second/share/python-build"
printf '%s\n' 'mkdir -p "$PREFIX_PATH"; echo first > "$PREFIX_PATH/marker"' \
> "$PYENV_ROOT/plugins/first/share/python-build/$entry"
echo 'exit 1' > "$PYENV_ROOT/plugins/second/share/python-build/$entry"
run pyenv-binary-install 3.14
assert_success ""
assert_equal first "$(cat "$PYENV_ROOT/versions/3.14.7/marker")"
[ ! -e "$BATS_TEST_TMPDIR/downloaded" ]
assert_equal "" "$(find "$TMPDIR" -mindepth 1 -maxdepth 1 -type d)"
}
@test "an explicit definition path takes precedence over a plugin definition" {
create_stub lsb_release 'case "$1" in -si) echo Ubuntu;; -sr) echo 24.04;; esac'
use_manifest
local entry="3.14.7-ubuntu-24.04-x86_64"
printf '3.14.7\t%s\tLinux\tx86_64\t%s\t%s\n' "$entry" \
"$(host_distro)" "$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub curl 'touch "$BATS_TEST_TMPDIR/downloaded"; exit 1'
PATH="${BATS_TEST_DIRNAME}/../../python-build/bin:$PATH"
export PYTHON_BUILD_DEFINITIONS="$BATS_TEST_TMPDIR/custom definitions"
mkdir -p "$PYTHON_BUILD_DEFINITIONS" "$PYENV_ROOT/plugins/custom/share/python-build"
printf '%s\n' 'mkdir -p "$PREFIX_PATH"; echo custom > "$PREFIX_PATH/marker"' \
> "$PYTHON_BUILD_DEFINITIONS/$entry"
echo 'exit 1' > "$PYENV_ROOT/plugins/custom/share/python-build/$entry"
run pyenv-binary-install 3.14.7
assert_success ""
assert_equal custom "$(cat "$PYENV_ROOT/versions/3.14.7/marker")"
[ ! -e "$BATS_TEST_TMPDIR/downloaded" ]
}
@test "rejects an invalid published checksum when definition lookup fails" {
create_stub lsb_release 'case "$1" in -si) echo Ubuntu;; -sr) echo 24.04;; esac'
use_manifest
printf '3.14.7\t3.14.7-ubuntu-24.04-x86_64\tLinux\tx86_64\t%s\tinvalid\n' \
"$(host_distro)" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub pyenv-install 'exit 1'
create_stub curl 'touch "$BATS_TEST_TMPDIR/downloaded"; exit 1'
run pyenv-binary-install 3.14.7
assert_failure "pyenv-binary: invalid checksum for 3.14.7-ubuntu-24.04-x86_64"
[ ! -e "$BATS_TEST_TMPDIR/downloaded" ]
}
@test "installs a matching published binary with an uppercase checksum" {
create_stub lsb_release 'case "$1" in -si) echo Ubuntu;; -sr) echo 24.04;; esac'
use_manifest
local uppercase_sha="$(printf '%s' "$definition_sha" | tr '[:lower:]' '[:upper:]')"
printf '3.14.7\t3.14.7-macos-15-arm64\tDarwin\tarm64\tmacos 15.7.9\t%s\n' \
"$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
printf '3.14.7\t3.14.7-ubuntu-24.04-x86_64\tLinux\tx86_64\t%s\t%s\n' \
"$(host_distro | tr '[:lower:]' '[:upper:]')" "$uppercase_sha" \
>> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
stub_downloads
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub pyenv-install <<'STUB'
[ "$1" = --list ] && exit
definition="${1%:*}"
printf '%s:%s\n' "${definition##*/}" "${1##*:}"
cat "$definition"
STUB
run pyenv-binary-install 3.14
assert_success "3.14.7-ubuntu-24.04-x86_64:3.14.7
definition"
}
@test "a version prefix selects the latest published binary" {
create_stub lsb_release 'case "$1" in -si) echo Ubuntu;; -sr) echo 24.04;; esac'
use_manifest
printf '3.14.10\t3.14.10-ubuntu-24.04-x86_64\tLinux\tx86_64\t%s\t%s\n' \
"$(host_distro)" "$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
printf '3.14.7\t3.14.7-ubuntu-24.04-x86_64\tLinux\tx86_64\t%s\t%s\n' \
"$(host_distro)" "$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
stub_downloads
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
create_stub pyenv-install '[ "$1" = --list ] && exit; echo "${1##*:}"'
run pyenv-binary-install 3.14
assert_success "3.14.10"
}
@test "fails when no published binary matches the host" {
use_manifest
printf '3.14.7\t3.14.7-macos-15-arm64\tDarwin\tarm64\tmacos 15.7.9\t%s\n' \
"$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
run pyenv-binary-install 3.14.7
assert_failure "pyenv-binary: no binary available for 3.14.7 on Linux/x86_64"
}
@test "does not select a package for another Linux release" {
create_stub lsb_release 'case "$1" in -si) echo Ubuntu;; -sr) echo 22.04;; esac'
use_manifest
local other_release="ubuntu 24.04"
[ "$(host_distro)" = "$other_release" ] && other_release="ubuntu 22.04"
printf '3.14.7\t3.14.7-ubuntu-24.04-x86_64\tLinux\tx86_64\t%s\t%s\n' \
"$other_release" "$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
create_stub uname 'case "$1" in -s) echo Linux;; -m) echo x86_64;; esac'
run pyenv-binary-install 3.14.7
assert_failure "pyenv-binary: no binary available for 3.14.7 on Linux/x86_64"
}
@test "uses a macOS binary built on an older release" {
use_manifest
printf '3.14.7\t3.14.7-macos-15-arm64\tDarwin\tarm64\tmacos 15.7.9\t%s\n' \
"$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
stub_downloads
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
create_stub sw_vers 'echo 26.6.2'
create_stub pyenv-install '[ "$1" = --list ] && exit; echo "${1##*:}"'
run pyenv-binary-install 3.14.7
assert_success "3.14.7"
}
@test "rejects a macOS binary built on a newer patch release" {
use_manifest
printf '3.14.7\t3.14.7-macos-15-arm64\tDarwin\tarm64\tmacos 15.7.9\t%s\n' \
"$definition_sha" >> "$BATS_TEST_TMPDIR/plugin/share/pyenv-binary/versions/3.14"
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
create_stub sw_vers 'echo 15.7.8'
create_stub pyenv-install '[ "$1" = --list ] && exit; echo installed'
run pyenv-binary-install 3.14.7
assert_failure "pyenv-binary: no binary available for 3.14.7 on Darwin/arm64"
}

View File

@ -66,10 +66,24 @@ pyenv-install --list --bare
run pyenv-binary-package 3.12.7 --archive-base-url http://example.com/binaries run pyenv-binary-package 3.12.7 --archive-base-url http://example.com/binaries
assert_success assert_success
assert [ -d "${PYENV_ROOT}/versions/3.12.7-debian-12-x86_64" ] assert [ -d "${PYENV_ROOT}/versions/3.12.7-debian-12-x86_64" ]
assert [ -f "${BATS_TEST_TMPDIR}/3.12.7-debian-12-x86_64.tar.gz" ] assert [ -f "${BATS_TEST_TMPDIR}/3.12.7-debian-12-x86_64.tar.xz" ]
assert [ -f "${BATS_TEST_TMPDIR}/3.12.7-debian-12-x86_64.meta" ] assert [ -f "${BATS_TEST_TMPDIR}/3.12.7-debian-12-x86_64.meta" ]
run grep '^source_version=' "${BATS_TEST_TMPDIR}/3.12.7-debian-12-x86_64.meta"
assert_success "source_version=3.12.7"
run grep '^ARCHIVE_URL=' "${BATS_TEST_TMPDIR}/3.12.7-debian-12-x86_64" run grep '^ARCHIVE_URL=' "${BATS_TEST_TMPDIR}/3.12.7-debian-12-x86_64"
assert_success "ARCHIVE_URL=http://example.com/binaries/3.12.7-debian-12-x86_64.tar.gz" assert_success "ARCHIVE_URL=http://example.com/binaries/3.12.7-debian-12-x86_64.tar.xz"
}
@test "records the definition name when packaging from a file" {
stub_build_environment
cd "${BATS_TEST_TMPDIR}"
printf 'install_package "foo"\n' > custom-python
run pyenv-binary-package "${BATS_TEST_TMPDIR}/custom-python:custom-build" \
--archive-base-url http://example.com/binaries
assert_success
run grep '^source_version=' custom-build.meta
assert_success "source_version=custom-python"
} }
@test "rejects an entry name containing a slash" { @test "rejects an entry name containing a slash" {
@ -84,6 +98,7 @@ pyenv-install --list --bare
@test "packages on macOS" { @test "packages on macOS" {
create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac' create_stub uname 'case "$1" in -s) echo Darwin;; -m) echo arm64;; esac'
create_stub pyenv-latest 'echo 3.12.7'
create_stub pyenv-install 'echo install' create_stub pyenv-install 'echo install'
create_stub pyenv-binary-save 'echo save' create_stub pyenv-binary-save 'echo save'
create_stub pyenv-binary-generate-installer 'echo generate-installer' create_stub pyenv-binary-generate-installer 'echo generate-installer'
@ -102,10 +117,10 @@ generate-installer"
--archive-base-url http://example.com/binaries --archive-base-url http://example.com/binaries
assert_success assert_success
assert [ -d "${PYENV_ROOT}/versions/3.12.7-test" ] assert [ -d "${PYENV_ROOT}/versions/3.12.7-test" ]
assert [ -f "${BATS_TEST_TMPDIR}/3.12.7-test.tar.gz" ] assert [ -f "${BATS_TEST_TMPDIR}/3.12.7-test.tar.xz" ]
assert [ -f "${BATS_TEST_TMPDIR}/3.12.7-test.meta" ] assert [ -f "${BATS_TEST_TMPDIR}/3.12.7-test.meta" ]
run grep '^ARCHIVE_URL=' "${BATS_TEST_TMPDIR}/3.12.7-test" run grep '^ARCHIVE_URL=' "${BATS_TEST_TMPDIR}/3.12.7-test"
assert_success "ARCHIVE_URL=http://example.com/binaries/3.12.7-test.tar.gz" assert_success "ARCHIVE_URL=http://example.com/binaries/3.12.7-test.tar.xz"
} }
@test "correctly joins archive base url with a trailing slash" { @test "correctly joins archive base url with a trailing slash" {
@ -127,5 +142,5 @@ done
run pyenv-binary-package 3.12.7:3.12.7-test \ run pyenv-binary-package 3.12.7:3.12.7-test \
--archive-base-url http://example.com/binaries/ --archive-base-url http://example.com/binaries/
assert_success assert_success
assert_line "pyenv-binary-generate-installer --archive-url http://example.com/binaries/3.12.7-test.tar.gz" assert_line "pyenv-binary-generate-installer --archive-url http://example.com/binaries/3.12.7-test.tar.xz"
} }

View File

@ -23,11 +23,25 @@ create_interpreter() {
} }
create_macos_tree() { create_macos_tree() {
local prefix="${BATS_TEST_TMPDIR}/prefix" local prefix="${BATS_TEST_TMPDIR}/prefix&target"
local lib="${prefix}/lib/python3.12" local lib="${prefix}/lib/python3.12"
mkdir -p "${prefix}/bin" "${lib}/lib-dynload" "${lib}/site-packages/numpy" local old="/build prefix/3.12.7"
mkdir -p \
"${prefix}/bin" \
"${prefix}/lib/pkgconfig" \
"${lib}/__pycache__" \
"${lib}/lib-dynload" \
"${lib}/site-packages/numpy"
printf '#!/bin/sh\n' > "${prefix}/bin/python3.12" printf '#!/bin/sh\n' > "${prefix}/bin/python3.12"
chmod +x "${prefix}/bin/python3.12" chmod +x "${prefix}/bin/python3.12"
printf '#!%s/bin/python3.12\n' "$old" > "${prefix}/bin/pip3"
chmod +x "${prefix}/bin/pip3"
printf 'prefix=%s\n' "$old" > "${prefix}/lib/pkgconfig/python-3.12.pc"
printf 'prefix=/build prefix/3x12x7\n' > "${prefix}/lib/pkgconfig/unrelated.pc"
printf 'prefix = "%s"\n' "$old" > "${lib}/_sysconfigdata.py"
printf '\0bytecode:%s/module.py\n' "$old" > "${lib}/__pycache__/module.cpython-312.pyc"
printf '\0bytecode:%s/legacy.py\n' "$old" > "${lib}/legacy.pyo"
printf '\0sourceless bytecode\n' > "${lib}/sourceless.pyc"
touch "${prefix}/lib/libpython3.12.dylib" touch "${prefix}/lib/libpython3.12.dylib"
touch "${lib}/lib-dynload/_ssl.cpython-312-darwin.so" touch "${lib}/lib-dynload/_ssl.cpython-312-darwin.so"
touch "${lib}/site-packages/numpy/_multiarray.so" touch "${lib}/site-packages/numpy/_multiarray.so"
@ -45,6 +59,9 @@ case "$1" in
-L ) -L )
echo "${file}:" echo "${file}:"
case "$file" in case "$file" in
*/bin/pip3 )
exit 1
;;
*/bin/python3.12 ) */bin/python3.12 )
if [ -n "$OTOOL_RELOCATED" ]; then if [ -n "$OTOOL_RELOCATED" ]; then
echo " @rpath/libpython3.12.dylib (compatibility version 3.12.0, current version 3.12.0)" echo " @rpath/libpython3.12.dylib (compatibility version 3.12.0, current version 3.12.0)"
@ -179,7 +196,7 @@ STUB
} }
@test "relocates macOS load commands without changing unrelated entries" { @test "relocates macOS load commands without changing unrelated entries" {
local prefix="${BATS_TEST_TMPDIR}/prefix" local prefix="${BATS_TEST_TMPDIR}/prefix&target"
local old="/build prefix/3.12.7" local old="/build prefix/3.12.7"
local lib="${prefix}/lib/python3.12" local lib="${prefix}/lib/python3.12"
create_macos_tree create_macos_tree
@ -197,10 +214,21 @@ STUB
EOF EOF
run grep -F "${lib}/site-packages/numpy/_multiarray.so" "${BATS_TEST_TMPDIR}/otool.log" run grep -F "${lib}/site-packages/numpy/_multiarray.so" "${BATS_TEST_TMPDIR}/otool.log"
assert_failure assert_failure
run head -n 1 "${prefix}/bin/pip3"
assert_output "#!${prefix}/bin/python3.12"
run cat "${prefix}/lib/pkgconfig/python-3.12.pc"
assert_output "prefix=${prefix}"
run cat "${prefix}/lib/pkgconfig/unrelated.pc"
assert_output "prefix=/build prefix/3x12x7"
run cat "${lib}/_sysconfigdata.py"
assert_output "prefix = \"${prefix}\""
assert [ ! -e "${lib}/__pycache__/module.cpython-312.pyc" ]
assert [ ! -e "${lib}/legacy.pyo" ]
assert [ -e "${lib}/sourceless.pyc" ]
} }
@test "skips already relocated macOS load commands" { @test "skips already relocated macOS load commands" {
local prefix="${BATS_TEST_TMPDIR}/prefix" local prefix="${BATS_TEST_TMPDIR}/prefix&target"
create_macos_tree create_macos_tree
stub_macos_tools stub_macos_tools
export OTOOL_RELOCATED=1 export OTOOL_RELOCATED=1
@ -211,7 +239,7 @@ EOF
} }
@test "fails when install_name_tool cannot modify a selected file" { @test "fails when install_name_tool cannot modify a selected file" {
local prefix="${BATS_TEST_TMPDIR}/prefix" local prefix="${BATS_TEST_TMPDIR}/prefix&target"
create_macos_tree create_macos_tree
stub_macos_tools stub_macos_tools
create_path_executable install_name_tool 'exit 1' create_path_executable install_name_tool 'exit 1'

View File

@ -12,7 +12,7 @@ platform() {
@test "fails with no version given" { @test "fails with no version given" {
run pyenv-binary-save run pyenv-binary-save
assert_failure "Usage: pyenv binary save <version> [<output-dir>] [--name <name>]" assert_failure "Usage: pyenv binary save <version> [<output-dir>] [--name <name>] [--source-version <version>]"
} }
@test "fails for a version that is not installed" { @test "fails for a version that is not installed" {
@ -33,13 +33,13 @@ platform() {
@test "packages an installed version" { @test "packages an installed version" {
create_version "3.12.7" create_version "3.12.7"
local out="${BATS_TEST_TMPDIR}/dist" local out="${BATS_TEST_TMPDIR}/dist"
local archive="${out}/3.12.7-$(platform).tar.gz" local archive="${out}/3.12.7-$(platform).tar.xz"
run pyenv-binary-save "3.12.7" "$out" run pyenv-binary-save "3.12.7" "$out"
assert_success "Saved 3.12.7-$(platform).tar.gz and 3.12.7-$(platform).meta to $out" assert_success "Saved 3.12.7-$(platform).tar.xz and 3.12.7-$(platform).meta to $out"
assert [ -f "$archive" ] assert [ -f "$archive" ]
assert [ -f "${out}/3.12.7-$(platform).meta" ] assert [ -f "${out}/3.12.7-$(platform).meta" ]
run tar -tzf "$archive" run tar -tJf "$archive"
assert_success assert_success
assert_line 0 "3.12.7/" assert_line 0 "3.12.7/"
} }
@ -49,10 +49,32 @@ platform() {
local out="${BATS_TEST_TMPDIR}/dist" local out="${BATS_TEST_TMPDIR}/dist"
run pyenv-binary-save "3.12.7" "$out" --name "custom" run pyenv-binary-save "3.12.7" "$out" --name "custom"
assert_success "Saved custom.tar.gz and custom.meta to $out" assert_success "Saved custom.tar.xz and custom.meta to $out"
assert [ -f "${out}/custom.tar.gz" ] assert [ -f "${out}/custom.tar.xz" ]
run grep '^archive=' "${out}/custom.meta" run grep '^archive=' "${out}/custom.meta"
assert_success "archive=custom.tar.gz" assert_success "archive=custom.tar.xz"
}
@test "records the source version for a renamed build" {
create_version "3.12.7-ubuntu-24.04-x86_64"
local out="${BATS_TEST_TMPDIR}/dist"
run pyenv-binary-save "3.12.7-ubuntu-24.04-x86_64" "$out" \
--name "3.12.7-ubuntu-24.04-x86_64" --source-version "3.12.7"
assert_success
run grep '^source_version=' "${out}/3.12.7-ubuntu-24.04-x86_64.meta"
assert_success "source_version=3.12.7"
}
@test "rejects an option as the source version" {
run pyenv-binary-save "3.12.7" --source-version --name custom
assert_failure "pyenv-binary: --source-version needs a value"
}
@test "rejects control characters in the default source version" {
run pyenv-binary-save $'3.12.7\nsource_version=other'
assert_failure
[[ "$output" == "pyenv-binary: invalid source version"* ]]
} }
@test "fails when --name has no value" { @test "fails when --name has no value" {
@ -76,7 +98,7 @@ platform() {
assert_success assert_success
assert_line "version=3.12.7" assert_line "version=3.12.7"
assert_line "platform=$(platform)" assert_line "platform=$(platform)"
assert_line "archive=3.12.7-$(platform).tar.gz" assert_line "archive=3.12.7-$(platform).tar.xz"
} }
@test "records the original installation prefix" { @test "records the original installation prefix" {
@ -94,7 +116,7 @@ platform() {
PATH="$(path_without readelf)" run pyenv-binary-save "3.12.7" "${BATS_TEST_TMPDIR}/dist" PATH="$(path_without readelf)" run pyenv-binary-save "3.12.7" "${BATS_TEST_TMPDIR}/dist"
assert_failure "pyenv-binary: need readelf to inspect shared libraries" assert_failure "pyenv-binary: need readelf to inspect shared libraries"
assert [ ! -e "${BATS_TEST_TMPDIR}/dist/3.12.7-$(platform).tar.gz" ] assert [ ! -e "${BATS_TEST_TMPDIR}/dist/3.12.7-$(platform).tar.xz" ]
} }
@test "records only direct libraries resolved outside the prefix" { @test "records only direct libraries resolved outside the prefix" {

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 yfprojects
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,33 @@
# pyenv-link
A [pyenv](https://github.com/pyenv/pyenv) plugin for linking Python installations and virtual environments into your pyenv root.
This plugin recommends the [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv/) plugin.
## Usage
Make an arbitrary virtualenv available through pyenv. This automatically guesses a fitting name from the prompt, the directory name or the location of the venv.
```console
$ pyenv link version .venv
Linked new version named myproject
```
You can also specify a name to use for the venv.
```console
$ pyenv link version .venv myname
Linked new version named myname
```
The same command can give a platform-specific binary installation a shorter name:
```console
$ pyenv link version "$(pyenv root)/versions/3.13.14-linux-x86_64" 3.13.14
Linked new version named 3.13.14
```
Now you can make pyenv activate/use the venv automatically:
```console
$ pyenv local myproject
```

View File

@ -0,0 +1,34 @@
#!/usr/bin/env bash
#
# Summary: Link a Python environment as a pyenv version
#
# Usage: pyenv link version [--dry] [--quiet] <path> [<name>]
#
# Link a virtual python environment to pyenvs version directory
# so that the venv can be used like one created with *pyenv-virtualenv*.
#
# <path> should be a path to a Python installation or virtual environment.
set -e
[ -n "$PYENV_DEBUG" ] && set -x
# Provide pyenv completions
case "$1" in
--complete)
if [ -z "$2" ]; then
echo version
else
shift 2
pyenv-link-version --complete "$@"
fi
;;
version)
shift
pyenv-link-version "$@"
exit $?
;;
*)
pyenv-help --usage link >&2
exit 1
;;
esac

View File

@ -0,0 +1,150 @@
#!/usr/bin/env bash
#
# Summary: Link a Python environment as a pyenv version
#
# Usage: pyenv link version [--dry] [--quiet] <path> [<name>]
#
# Link a virtual python environment to pyenvs version directory
# so that the venv can be used like one created with *pyenv-virtualenv*.
#
# <path> should be a path to a Python installation or virtual environment.
# <name> should be string used as a version name it may not be present
# in the pyenv version directory yet.
# If not specified a matching name is guessed from pyvenv.cfg
# or directory name of the venv.
set -e
[ -n "$PYENV_DEBUG" ] && set -x
# functions
if ! {
enable -f "${BASH_SOURCE%/*}"/../../../libexec/pyenv-realpath.dylib realpath ||
type realpath # realpath available?
} >/dev/null 2>&1; then
# realpath requires GNU coreutils to be installed. That's why its bundled with pyenv
echo realpath not available >&2
# work-around when realpath is unavailable
realpath() {
(cd "$1" && pwd)
}
fi
guess_name() {
local venv_dir=$1
local name
# guess venv name from pyvenv.cfg
local pyvenv_cfg_path=$venv_dir/pyvenv.cfg
if [ -f "$pyvenv_cfg_path" ]; then
# if `prompt` key wasn't found the var remains empty
name=$(cut -b 1-1024 "$pyvenv_cfg_path" | sed -n '/^ *prompt *= */s///p')
case "$name" in
\"*\" | \'*\')
name=${name:1:${#name}-2}
;;
esac
fi
# guess venv name from name of venv directory
local venv_dir_name=${venv_dir##*/}
if [ -z "$name" ]; then
case "$venv_dir_name" in
venv | env | .venv | .env | ENV | VENV) ;;
*) name=$venv_dir_name ;;
esac
fi
# guess venv name from name of the parent directory of the venv directory
local venv_dir_parent=${venv_dir%/*}
local venv_dir_parent_name=${venv_dir_parent##*/}
if [ -z "$name" ]; then
name=$venv_dir_parent_name
fi
echo "$name"
}
# process args
POSARGS=()
# Provide pyenv completions
if [ "$1" = "--complete" ]; then
echo --dry
echo --quiet
exit
fi
for arg in "$@"; do
case $arg in
--dry)
dry=true # any value
;;
--quiet)
quiet=true # any value
;;
-*)
pyenv-help --usage link-version >&2
exit 1
;;
*)
POSARGS+=("$arg")
;;
esac
done
if [ ! ${#POSARGS[@]} -le 2 ] || [ ! ${#POSARGS[@]} -ge 1 ]; then
pyenv-help --usage link-version >&2
exit 1
fi
venv_dir=${POSARGS[0]%/}
venv_name=${POSARGS[1]}
# Check venv exists
if [ ! -d "$venv_dir" ]; then
echo "The virtual env you specified doesn't exist"
exit 2
fi
# make venv dir absolute
venv_dir=$(realpath "$venv_dir")
# determine venv name
if [ -z "$venv_name" ]; then
venv_name=$(guess_name "$venv_dir")
fi
case "$venv_name" in
"" | */* | . | .. | *:* | system | *[[:cntrl:]]* )
echo "pyenv-link: invalid version name \`${venv_name}'" >&2
exit 1
;;
esac
versions_dir="$PYENV_ROOT/versions"
pyenv_prefix_path="$versions_dir/$venv_name"
if [ -e "$pyenv_prefix_path" ] || [ -L "$pyenv_prefix_path" ]; then
echo Version "$venv_name" already exists >&2
exit 3
fi
case "$venv_dir" in
"$versions_dir"/*)
link_target=${venv_dir#"$versions_dir"/}
;;
*)
link_target=$venv_dir
;;
esac
# link to pyenv version directory
if [ -z "$dry" ]; then
mkdir -p "$versions_dir"
ln -s "$link_target" "$pyenv_prefix_path"
fi
# output
if [ -z "$quiet" ]; then
echo "Linked new version named $venv_name"
fi

View File

@ -0,0 +1,61 @@
#!/usr/bin/env bats
load test_helper
@test "link completions use the dispatcher" {
run pyenv completions link
assert_success
assert_output <<OUT
--help
version
OUT
run pyenv completions link version
assert_success
assert_output <<OUT
--help
--dry
--quiet
OUT
}
@test "link requires a version path" {
run pyenv-link version
assert_failure "Usage: pyenv link version [--dry] [--quiet] <path> [<name>]"
}
@test "links an installed binary under its plain version name" {
create_alt_executable_in_version "3.13.14-linux-x86_64" python 'echo linked-python'
run pyenv-link version "$PYENV_ROOT/versions/3.13.14-linux-x86_64" 3.13.14
assert_success "Linked new version named 3.13.14"
assert_equal "3.13.14-linux-x86_64" "$(readlink "$PYENV_ROOT/versions/3.13.14")"
PYENV_VERSION=3.13.14 run pyenv exec python
assert_success "linked-python"
}
@test "links external paths containing spaces into a fresh root" {
mkdir -p "$PYENV_TEST_DIR/external env/bin"
run pyenv-link version "$PYENV_TEST_DIR/external env" custom
assert_success "Linked new version named custom"
assert_equal "$PYENV_TEST_DIR/external env" "$(readlink "$PYENV_ROOT/versions/custom")"
}
@test "refuses a dangling destination link" {
mkdir -p "$PYENV_ROOT/versions" "$PYENV_TEST_DIR/source"
ln -s missing "$PYENV_ROOT/versions/dangling"
run pyenv-link version "$PYENV_TEST_DIR/source" dangling
assert_failure "Version dangling already exists"
assert_equal missing "$(readlink "$PYENV_ROOT/versions/dangling")"
}
@test "rejects invalid version names" {
mkdir -p "$PYENV_TEST_DIR/source"
for name in ../outside . .. 'foo/bar' 'foo:bar' system; do
run pyenv-link version "$PYENV_TEST_DIR/source" "$name"
assert_failure "pyenv-link: invalid version name \`$name'"
assert [ ! -e "$PYENV_ROOT/outside" ]
done
echo "prompt = '../outside'" > "$PYENV_TEST_DIR/source/pyvenv.cfg"
run pyenv-link version "$PYENV_TEST_DIR/source"
assert_failure "pyenv-link: invalid version name \`../outside'"
assert [ ! -e "$PYENV_ROOT/outside" ]
}

View File

@ -0,0 +1 @@
../../../test/test_helper.bash

View File

@ -54,8 +54,11 @@ Or, if you would like to install the latest development release:
## Usage ## Usage
Before you begin, you should ensure that your build environment has the proper On Ubuntu, Debian, and Mint, install the recommended build dependencies with:
system dependencies for compiling the wanted Python Version (see our [recommendations](https://github.com/pyenv/pyenv/wiki#suggested-build-environment)).
pyenv install-prerequisites
For other environments, see our [build environment recommendations](https://github.com/pyenv/pyenv/wiki#suggested-build-environment).
### Using `pyenv install` with pyenv ### Using `pyenv install` with pyenv
@ -361,4 +364,3 @@ git diff --name-only master \
- Filter out any which don't live where python-build keeps its build scripts - Filter out any which don't live where python-build keeps its build scripts
- Look only at the file name (i.e. the python version name) - Look only at the file name (i.e. the python version name)
- Run a new docker container for each, building that version - Run a new docker container for each, building that version

View File

@ -261,7 +261,7 @@ for i in "${!DEFINITIONS[@]}"; do
PYENV_BOOTSTRAP_VERSION="${PYENV_RPYTHON_VERSION}" PYENV_BOOTSTRAP_VERSION="${PYENV_RPYTHON_VERSION}"
else else
for version in $(pyenv-versions --bare | sort -r); do for version in $(pyenv-versions --bare | sort -r); do
if [[ "${version}" == "2.7"* ]]; then if [[ "${version}" =~ ^(2\.7|pypy2\.7) ]]; then
PYENV_BOOTSTRAP_VERSION="$version" PYENV_BOOTSTRAP_VERSION="$version"
break break
fi fi
@ -275,7 +275,7 @@ for i in "${!DEFINITIONS[@]}"; do
fi fi
done done
else else
echo "pyenv-install: $VERSION_NAME: PyPy requires Python 2.7 to build from source." >&2 echo "pyenv-install: $VERSION_NAME: PyPy requires Python 2.7 to build from source. You can specify the version to use by setting the PYENV_BOOTSTRAP_VERSION environment variable." >&2
exit 1 exit 1
fi fi
;; ;;

View File

@ -0,0 +1,64 @@
#!/usr/bin/env bash
#
# Summary: Install Python build prerequisites on Debian-based systems
#
# Usage: pyenv install-prerequisites [-a|--all]
#
# -a/--all Also install optional dependencies (for rarely used modules)
#
set -e
[ -n "$PYENV_DEBUG" ] && set -x
# Provide pyenv completions
if [ "$1" = "--complete" ]; then
echo --all
exit
fi
usage() {
pyenv-help install-prerequisites 2>/dev/null
[ -z "$1" ] || exit "$1"
}
all=
while (($#)); do
case "$1" in
-h|--help)
usage 0
;;
-a|--all)
all=1
;;
*)
usage 1 >&2
;;
esac
shift
done
if ! command -v apt-get >/dev/null; then
echo "pyenv: installing build prerequisites is not supported on this system" >&2
exit 1
fi
prerequisites=(
make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev
libsqlite3-dev curl git llvm libncurses5-dev libncursesw5-dev xz-utils
tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev libzstd-dev
)
optional=(
libgdbm-dev
)
if [ "$(id -u)" -eq 0 ]; then
apt_get=(apt-get)
elif command -v sudo >/dev/null; then
apt_get=(sudo apt-get)
else
echo "pyenv: sudo is required to install build prerequisites" >&2
exit 1
fi
"${apt_get[@]}" update -q
"${apt_get[@]}" install -yq "${prerequisites[@]}" ${all:+"${optional[@]}"}

View File

@ -14,7 +14,7 @@
# -g/--debug Build a debug version # -g/--debug Build a debug version
# #
PYTHON_BUILD_VERSION="2.8.5" PYTHON_BUILD_VERSION="2.8.7"
OLDIFS="$IFS" OLDIFS="$IFS"
@ -425,6 +425,18 @@ http_head_aria2c() {
aria2c --dry-run --no-conf=true ${ARIA2_OPTS} "$1" >&4 2>&1 aria2c --dry-run --no-conf=true ${ARIA2_OPTS} "$1" >&4 2>&1
} }
# Shows interactive output of a program
# while also logging it.
# Usage:
# command <switches forcing interactive output to non-terminal> 2>&1 | interactive_output; rc=${PIPESTATUS[0]}
interactive_output() {
if [ -n "$VERBOSE" ]; then
cat >> "$LOG_PATH"
else
tee -a "$LOG_PATH" >&3
fi
}
http_get_aria2c() { http_get_aria2c() {
# aria2c always treats -o argument as a relative path # aria2c always treats -o argument as a relative path
local out dir_out; local out dir_out;
@ -447,7 +459,26 @@ http_get_aria2c() {
dir_out="$HOME" dir_out="$HOME"
fi fi
if aria2c --allow-overwrite=true --no-conf=true -d "${dir_out}" -o "${out}" ${ARIA2_OPTS} "$1" >&4; then local aria2c_progress=
# aria2c prints status to stdout rather than stderr.
# As a result, when stdout is redirected, it becomes line-buffered,
# and status messages (which are divided by CRs) are not seen
# until a summary message with some LFs is printed.
# So we have to print summaries often as a crutch.
# But need to make the interval reasonable because each summary is
# several lines long which, made too often, becomes obnoxious.
[ -t 3 ] && aria2c_progress="--summary-interval=5"
local cmd
cmd=(aria2c --allow-overwrite=true --no-conf=true -d "${dir_out}" -o "${out}" ${aria2c_progress} ${ARIA2_OPTS} "$1")
if [ -t 3 ]; then
"${cmd[@]}" 2>&1 | interactive_output
ret=${PIPESTATUS[0]}
else
"${cmd[@]}" >&4
ret=$?
fi
if [ "$ret" -eq 0 ]; then
[ -n "$2" ] || cat "${dir_out:-.}/${out}" [ -n "$2" ] || cat "${dir_out:-.}/${out}"
else else
false false
@ -471,7 +502,21 @@ http_get_curl() {
local curl_is_snap; local curl_is_snap;
if [[ $(command -v curl) == "/snap/"* ]]; then curl_is_snap=1; fi if [[ $(command -v curl) == "/snap/"* ]]; then curl_is_snap=1; fi
if [[ -n $2 && -n $curl_is_snap ]]; then out="$HOME/$(basename "$2")"; else out="$2"; fi if [[ -n $2 && -n $curl_is_snap ]]; then out="$HOME/$(basename "$2")"; else out="$2"; fi
curl -q -o "${out:--}" -sSLf ${CURL_OPTS} "$1" || return $? local curl_progress=
if [ -t 3 ]; then
curl_progress="--no-silent"
fi
local cmd
cmd=(curl -q -o "${out:--}" -sSLf ${CURL_OPTS} ${curl_progress} "$1")
if [ -t 3 ]; then
exec 5>&1
"${cmd[@]}" 3>&1 1>&5 2>&3 3>&- | interactive_output
ret=${PIPESTATUS[0]}
exec 5>&-
[ "$ret" -eq 0 ] || return "$ret"
else
"${cmd[@]}" || return $?
fi
if [[ -n $out && -n $curl_is_snap ]]; then mv "$out" "$2"; fi if [[ -n $out && -n $curl_is_snap ]]; then mv "$out" "$2"; fi
} }
@ -480,7 +525,21 @@ http_head_wget() {
} }
http_get_wget() { http_get_wget() {
wget -nv ${WGET_OPTS} -O "${2:--}" "$1" local wget_progress="-nv"
if [ -t 3 ]; then
wget_progress="-nv --show-progress --progress=bar:force:noscroll"
fi
local cmd
cmd=(wget ${WGET_OPTS} ${wget_progress} -O "${2:--}" "$1")
if [ -t 3 ]; then
exec 5>&1
"${cmd[@]}" 3>&1 1>&5 2>&3 3>&- | interactive_output
ret=${PIPESTATUS[0]}
exec 5>&-
return "$ret"
else
"${cmd[@]}"
fi
} }
fetch_tarball() { fetch_tarball() {
@ -873,6 +932,7 @@ build_package_standard_build() {
if [ "$package_var_name" = "PYTHON" ]; then if [ "$package_var_name" = "PYTHON" ]; then
if can_use_homebrew; then if can_use_homebrew; then
configured_with_openssl || use_homebrew_openssl || true
use_custom_tcltk || use_homebrew_tcltk || true use_custom_tcltk || use_homebrew_tcltk || true
use_homebrew_readline || true use_homebrew_readline || true
use_homebrew_ncurses || true use_homebrew_ncurses || true
@ -885,6 +945,7 @@ build_package_standard_build() {
fi fi
fi fi
if can_use_macports; then if can_use_macports; then
configured_with_openssl || use_macports_openssl || true
use_custom_tcltk || true use_custom_tcltk || true
use_macports_readline || true use_macports_readline || true
use_macports_ncurses || true use_macports_ncurses || true
@ -996,27 +1057,29 @@ build_package_jython_builder() {
( cd "dist" && build_package_jython ) ( cd "dist" && build_package_jython )
} }
build_package_pyston2_2() { build_package_pyston() {
# currently supported version 2.2 and 2.3
build_package_copy build_package_copy
mkdir -p "${PREFIX_PATH}/bin" "${PREFIX_PATH}/lib" # Pyston tarballs provide an executable with a version-specific naming scheme
local bin # and `pyston` and `pyston3` symlinks to it.
shopt -s nullglob make_python_symlinks pyston
for bin in "bin/"*; do
if [ -f "${bin}" ] && [ -x "${bin}" ] && [ ! -L "${bin}" ]; then
case "${bin##*/}" in
"pyston"* )
( cd "${PREFIX_PATH}/bin" && ln -fs "${bin##*/}" "python" )
;;
esac
fi
done
shopt -u nullglob
} }
build_package_pyston() { # Add missing `python', `pythonX' and `pythonX.Y' symlinks as per PEP 394.
# currently supported version 2.3.1v2 and higher make_python_symlinks() {
build_package_copy local seeder_basename version_suffix real_interpreter
local -a interpreter_names
seeder_basename="${1:?}"; shift
(($#)) && interpreter_names=("$@") || interpreter_names=(python)
local real_interpreter
real_interpreter=$(resolve_link "${PREFIX_PATH}/bin/$seeder_basename" || echo $seeder_basename)
# Use syntax accepted in both Py2 and Py3. Even though current Py2 holdouts (e.g. PyPy) support e.g. print()
version_suffix=$("${PREFIX_PATH}/bin/$seeder_basename" -c 'import sys; sys.stdout.write("%d.%d\n" % sys.version_info[:2])')
for interpreter_name in "${interpreter_names[@]}"; do
for name in "$interpreter_name" "$interpreter_name${version_suffix%.*}" "$interpreter_name${version_suffix}"; do
[[ -e "${PREFIX_PATH}/bin/$name" ]] || ln -fs "${real_interpreter}" "${PREFIX_PATH}/bin/$name"
done
done
} }
build_package_ironpython() { build_package_ironpython() {
@ -1112,30 +1175,38 @@ pyston_architecture() {
# Note: not used by graalpy >= 23.3.0 anymore # Note: not used by graalpy >= 23.3.0 anymore
build_package_graalpython() { build_package_graalpython() {
build_package_copy build_package_copy
ln -fs "${PREFIX_PATH}/bin/graalpython" "${PREFIX_PATH}/bin/python" make_python_symlinks graalpython
} }
build_package_pypy() { build_package_pypy() {
build_package_copy build_package_copy
mkdir -p "${PREFIX_PATH}/bin" "${PREFIX_PATH}/lib"
local bin local bin
shopt -s nullglob shopt -s nullglob
for bin in "bin/"*; do for bin in "bin/libpypy"*; do
if [ -f "${bin}" ] && [ -x "${bin}" ] && [ ! -L "${bin}" ]; then if [[ -f "${bin}" && -x "${bin}" && ! -L "${bin}" ]]; then
case "${bin##*/}" in ln -fs "../bin/${bin##*/}" "${PREFIX_PATH}/lib/${bin##*/}"
"libpypy"* ) fi
( cd "${PREFIX_PATH}/lib" && ln -fs "../bin/${bin##*/}" "${bin##*/}" ) done
;;
"pypy"* ) # PyPy source builds may create only a pypy* executable with a version-sepecific name
( cd "${PREFIX_PATH}/bin" && ln -fs "${bin##*/}" "python" ) local seeder= seeder_candidate
;; for seeder_candidate in "${PREFIX_PATH}/bin/"pypy*; do
esac if [[ -f $seeder_candidate && -x $seeder_candidate ]]; then
seeder="${seeder_candidate##*/}"
break
fi fi
done done
shopt -u nullglob shopt -u nullglob
[[ -n $seeder ]] || {
echo "python-build: Cannot find a valid PyPy executable in \`${PREFIX_PATH}/bin'" >&4
exit 1
}
make_python_symlinks "$seeder" pypy python
} }
build_package_pypy_builder() { build_package_pypy_builder() {
use_homebrew_openssl || use_macports_openssl || true
if [ -f "rpython/bin/rpython" ]; then # pypy 2.x if [ -f "rpython/bin/rpython" ]; then # pypy 2.x
if [ -z "${PYPY_OPTS}" ]; then if [ -z "${PYPY_OPTS}" ]; then
local PYPY_OPTS="--opt=jit --batch --make-jobs=$(num_cpu_cores)" local PYPY_OPTS="--opt=jit --batch --make-jobs=$(num_cpu_cores)"
@ -1201,6 +1272,7 @@ anaconda_architecture() {
"aarch64" ) echo "Linux-aarch64" ;; "aarch64" ) echo "Linux-aarch64" ;;
"i386" | "i486" | "i586" | "i686" | "i786" ) echo "Linux-x86" ;; "i386" | "i486" | "i586" | "i686" | "i786" ) echo "Linux-x86" ;;
"ppc64le" ) echo "Linux-ppc64le" ;; "ppc64le" ) echo "Linux-ppc64le" ;;
"riscv64" ) echo "Linux-riscv64" ;;
"x86_64" ) echo "Linux-x86_64" ;; "x86_64" ) echo "Linux-x86_64" ;;
* ) return 1 ;; * ) return 1 ;;
esac esac
@ -1258,7 +1330,7 @@ cleanup_builtin_patches() {
fix_directory_permissions() { fix_directory_permissions() {
# Ensure installed directories are not world-writable # Ensure installed directories are not world-writable
find "$PREFIX_PATH" -type d \( -perm -020 -o -perm -002 \) -exec chmod go-w {} \; find "$PREFIX_PATH" -type d \( -perm -020 -o -perm -002 \) -exec chmod go-w {} \+
} }
require_java7() { require_java7() {
@ -1705,8 +1777,17 @@ build_package_mac_readline() {
build_package_standard "$@" build_package_standard "$@"
} }
configured_with_openssl() {
local arg
for arg in ${CONFIGURE_OPTS} ${PYTHON_CONFIGURE_OPTS} "${PYTHON_CONFIGURE_OPTS_ARRAY[@]}"; do
[[ "$arg" =~ ^--with-openssl(=|$) ]] && return 0
done
return 1
}
has_broken_mac_openssl() { has_broken_mac_openssl() {
is_mac || return 1 is_mac || return 1
configured_with_openssl && return 1
local openssl_version="$(/usr/bin/openssl version 2>/dev/null || true)" local openssl_version="$(/usr/bin/openssl version 2>/dev/null || true)"
if [[ $openssl_version = "OpenSSL 0.9.8"?* || $openssl_version = "LibreSSL"* ]]; then if [[ $openssl_version = "OpenSSL 0.9.8"?* || $openssl_version = "LibreSSL"* ]]; then
if can_use_homebrew; then if can_use_homebrew; then
@ -2757,7 +2838,8 @@ else
BUILD_PATH="$PYTHON_BUILD_BUILD_PATH" BUILD_PATH="$PYTHON_BUILD_BUILD_PATH"
fi fi
exec 4<> "$LOG_PATH" # open the log file at fd 4 # Append mode needed to be able to `tee` to it at the same time
exec 4>> "$LOG_PATH"
if [ -n "$VERBOSE" ]; then if [ -n "$VERBOSE" ]; then
tail -f "$LOG_PATH" & tail -f "$LOG_PATH" &
TAIL_PID=$! TAIL_PID=$!

View File

@ -89,6 +89,9 @@ def py_version(version):
# transition points: # transition points:
# https://github.com/conda-forge/miniforge/blame/main/Miniforge3/construct.yaml # https://github.com/conda-forge/miniforge/blame/main/Miniforge3/construct.yaml
# look for "- python <version>" in non-pypy branch and which tag the commit is first in # look for "- python <version>" in non-pypy branch and which tag the commit is first in
if version_tuple_ >= (26,5,3):
# https://github.com/conda-forge/miniforge/commit/8ae029d5f17e34e93fec2d9bfe708ba9175adf08
return "314"
if version_tuple_ >= (26,1): if version_tuple_ >= (26,1):
# https://github.com/conda-forge/miniforge/commit/0016367731e52c67234d6d0e7e6a24c6bf7673e4 # https://github.com/conda-forge/miniforge/commit/0016367731e52c67234d6d0e7e6a24c6bf7673e4
return "313" return "313"

View File

@ -0,0 +1,221 @@
#!/usr/bin/env python3
"""Rudimentary script to add PyPY releases automagically.
Requires requests-html.
Checks the PyPy download archives for new versions,
then writes a build script for any which do not exist locally,
saving it to plugins/python-build/share/python-build.
Written and tested in *CPython* 3.9.6. PyPy3 compatibility is not
guaranteed, but it should work.
"""
from pathlib import Path
import argparse
import logging
import re
import sys
from requests_html import HTMLSession
# https://downloads.python.org/pypy/versions.json doesn't contain
# checksums, so using checksums.html instead.
# More convenient than calculating them from downloads.
PYPY_REPO = "https://downloads.python.org/pypy/"
PYPY_CHECKSUMS = "https://pypy.org/checksums.html"
here = Path(__file__).resolve()
OUT_DIR: Path = here.parent.parent / "share" / "python-build"
EXCLUDED_RELEASES = [] # none for now
# Note: Remember to escape/unescape curly braces when editing the bash script
SCRIPT_BIN = """
VERSION='{version_pypy}'
PYVER='{version_python}'
# https://www.pypy.org/checksums.html
aarch64_hash={checksum_aarch64}
linux32_hash={checksum_linux32}
linux64_hash={checksum_linux64}
osarm64_hash={checksum_osarm64}
osx64_hash={checksum_osx64}
### end of manual settings - following lines same for every download
function err_no_binary {{
local archmsg="${{1}}"
local ver="pypy${{PYVER}}-v${{VERSION}}-src"
local url="https://downloads.python.org/pypy/${{ver}}.tar.{file_ext}"
{{ echo
colorize 1 "ERROR"
echo ": The binary distribution of PyPy is not available for ${{archmsg}}."
echo "try '${{url}}' to build from source."
echo
}} >&2
exit 1
}}
function pypy_pkg_data {{
# pypy architecture tag
local ARCH="${{1}}"
# defaults
local cmd='install_package' # use {file_ext}
local pkg="${{ARCH}}" # assume matches
local ext='tar.{file_ext}'
local hash='' # undefined
# select the hash, fix pkg if not match ARCH
case "${{ARCH}}" in
'linux-aarch64' )
hash="${{aarch64_hash}}"
pkg='aarch64'
;;
'linux' )
hash="${{linux32_hash}}"
pkg='linux32'
;;
'linux64' )
hash="${{linux64_hash}}"
;;
'osarm64' )
hash="${{osarm64_hash}}"
pkg='macos_arm64'
;;
'osx64' )
if require_osx_version "10.15"; then
hash="${{osx64_hash}}"
pkg='macos_x86_64'
else
err_no_binary "${{ARCH}}, OS X < 10.15"
fi
;;
* )
err_no_binary "${{ARCH}}"
;;
esac
local basever="pypy${{PYVER}}-v${{VERSION}}"
local baseurl="https://downloads.python.org/pypy/${{basever}}"
# result - command, package dir, url+hash
echo "${{cmd}}" "${{basever}}-${{pkg}}" "${{baseurl}}-${{pkg}}.${{ext}}#${{hash}}"
}}
# determine command, package directory, url+hash
declare -a pd="$(pypy_pkg_data "$(pypy_architecture 2>/dev/null || true)")"
# install
${{pd[0]}} "${{pd[1]}}" "${{pd[2]}}" 'pypy' "verify_py${{PYVER//./}}" '{ensurepip}'
""".lstrip()
SCRIPT_SRC = """
VERSION='{version_pypy}'
PYVER='{version_python}'
# https://www.pypy.org/checksums.html
hash={checksum_src}
### end of manual settings - following lines same for every download
ver="pypy${{PYVER}}-v${{VERSION}}-src"
url="https://downloads.python.org/pypy/${{ver}}.tar.{file_ext}"
prefer_openssl11
install_package "openssl-1.1.1f" "https://www.openssl.org/source/openssl-1.1.1f.tar.gz#186c6bfe6ecfba7a5b48c47f8a1673d0f3b0e5ba2e25602dd23b629975da3f35" mac_openssl --if has_broken_mac_openssl
install_package "${{ver}}" "${{url}}#${{hash}}" 'pypy_builder' "verify_py${{PYVER//./}}" '{ensurepip}'
""".lstrip()
args = None
logger = logging.getLogger(__name__)
def main() -> bool:
html_session = HTMLSession()
response = html_session.get(PYPY_CHECKSUMS)
page = response.html
checksum_blocks = page.find("pre.literal-block")
for csum_block in checksum_blocks:
python_version, pypy_version = parse_pypy_ver(csum_block.text)
py_it = f"pypy{python_version}-{pypy_version}"
if py_it not in EXCLUDED_RELEASES:
vbin_path = OUT_DIR.joinpath(py_it)
vsrc_path = OUT_DIR.joinpath(py_it+"-src")
kwargs = None
for ps in ((vbin_path, SCRIPT_BIN), (vsrc_path, SCRIPT_SRC)):
if not ps[0].is_file():
kwargs = kwargs or parse_checksums_ext(csum_block.text)
code = ps[1].format(
version_pypy=pypy_version,
version_python=python_version,
ensurepip="ensurepip" if not python_version == "2.7" else "ensurepip_lt21",
**kwargs # which are:
# checksum_aarch64
# checksum_linux32
# checksum_linux64
# checksum_osarm64
# checksum_osx64
# checksum_src
# file_ext
)
if not args.dry_run:
with open(file=ps[0], mode="w", encoding="utf-8") as f:
f.write(code)
f.close()
else:
print(f"---- DRY RUN SCRIPT FOR {ps[0]} ----")
print(code)
def parse_pypy_ver(csum_block:str) -> tuple[str,str]:
"""Gets the PyPy name from the checksum block."""
match = re.findall(r"pypy([0-9]\.[0-9]+)\-v([0-9]\.[0-9]\.[0-9]+)", csum_block)
match = set(match)
if len(match) == 1:
return match.pop()
return ""
def parse_checksums_ext(csum_block:str) -> dict:
"""Gets the checksums and ext for each platform (excluding win64) from the checksum block."""
chksm_ex = {
r"aarch64": "",
r"linux32": "",
r"linux64": "",
r"macos_arm64": "",
r"macos_x86_64": "",
r"src": "",
}
ext = set()
for ex in chksm_ex:
match = re.findall(r"([a-z0-9]+) pypy[0-9]\.[0-9]+\-v[0-9]\.[0-9]\.[0-9]+-"+ex+r".tar.(gz|bz2)", csum_block)
chksm_ex[ex] = match[0][0]
ext.add(match[0][1])
# if both gz and bz2, prefer bz2
ext = ext.pop() if len(ext) == 1 else "bz2"
return {
"checksum_aarch64": chksm_ex["aarch64"],
"checksum_linux32": chksm_ex["linux32"],
"checksum_linux64": chksm_ex["linux64"],
"checksum_osarm64": chksm_ex["macos_arm64"],
"checksum_osx64": chksm_ex["macos_x86_64"],
"checksum_src": chksm_ex["src"],
"file_ext": ext
}
if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"-d", "--dry-run", action="store_true",
help="Do not write scripts, just report them to stdout",
)
args = parser.parse_args()
#sys.excepthook seems to have no effect in Github Actions
try:
sys.exit(main())
except Exception:
logging.exception("Unhandled exception occurred")
sys.exit(2)

View File

@ -0,0 +1,27 @@
# source this in Bash
# cd to git repo of CPython
_python_build_dir=$(cd "${BASH_SOURCE%/*}/.."; pwd -P)
backport() {
[[ $# -lt 2 ]] && { echo "usage: $FUNCNAME <commit_hash> <CPython version>..." >&2; return 1; }
(set -euxo pipefail
sha="${1:?}"
shift
for b; do
git checkout "Branch_v$b" || git checkout -b "Branch_v$b" "v$b"
git cherry-pick "$sha"
git format-patch -1
patch_dir="$_python_build_dir/share/python-build/$b/Python-$b"
shopt -s nullglob
pp=("$patch_dir"/*.patch)
patch_offset=${#pp[@]}
shopt -u nullglob
unset pp
mkdir -p "$patch_dir"
for f in *.patch; do
mv "$f" "$patch_dir/$(printf '%04d' $((${f::4}+patch_offset)))${f:4}"
done
done)
}

View File

@ -0,0 +1,9 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-3.6.5" "https://github.com/openssl/openssl/releases/download/openssl-3.6.5/openssl-3.6.5.tar.gz#a2157c2830efdec3788939b00c9b0638306d3f0bbb76dc4832ee503bb397df98" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.10.22" "https://www.python.org/ftp/python/3.10.22/Python-3.10.22.tar.xz#c61fe9b1a1a7ec2a0b0388e664187c378a5325a89e3606d220abf5bdfccb2543" standard verify_py310 copy_python_gdb ensurepip
else
install_package "Python-3.10.22" "https://www.python.org/ftp/python/3.10.22/Python-3.10.22.tgz#9448b34d16f8e3db0964ac3ed9fb283197747543c2c021f283ffd2c8b7287357" standard verify_py310 copy_python_gdb ensurepip
fi

View File

@ -0,0 +1,11 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL_RPATH=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.6.5" "https://github.com/openssl/openssl/releases/download/openssl-3.6.5/openssl-3.6.5.tar.gz#a2157c2830efdec3788939b00c9b0638306d3f0bbb76dc4832ee503bb397df98" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.11.17" "https://www.python.org/ftp/python/3.11.17/Python-3.11.17.tar.xz#bfb74ad39efae27cda510f134ab408e00f9992c56851cfc0b1cdb5646da11599" standard verify_py311 copy_python_gdb ensurepip
else
install_package "Python-3.11.17" "https://www.python.org/ftp/python/3.11.17/Python-3.11.17.tgz#53cdee63ac4bf12387b7b33a53d3b1f8f4941cad73807a7b4fe91bb001ef004a" standard verify_py311 copy_python_gdb ensurepip
fi

View File

@ -0,0 +1,11 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL_RPATH=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.6.5" "https://github.com/openssl/openssl/releases/download/openssl-3.6.5/openssl-3.6.5.tar.gz#a2157c2830efdec3788939b00c9b0638306d3f0bbb76dc4832ee503bb397df98" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.12.15" "https://www.python.org/ftp/python/3.12.15/Python-3.12.15.tar.xz#c2c4321961fab0fb999d66e0cecf521c2ab3994c7992873ea99e306c1094fd5a" standard verify_py312 copy_python_gdb ensurepip
else
install_package "Python-3.12.15" "https://www.python.org/ftp/python/3.12.15/Python-3.12.15.tgz#de1a241a519e0a3374fea98988d0b52c886743f9d953f23be8269cc7b59c5fab" standard verify_py312 copy_python_gdb ensurepip
fi

View File

@ -0,0 +1,2 @@
export PYTHON_BUILD_FREE_THREADING=1
source "${BASH_SOURCE[0]%t}"

View File

@ -0,0 +1,11 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL_RPATH=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.6.5" "https://github.com/openssl/openssl/releases/download/openssl-3.6.5/openssl-3.6.5.tar.gz#a2157c2830efdec3788939b00c9b0638306d3f0bbb76dc4832ee503bb397df98" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.13.16" "https://www.python.org/ftp/python/3.13.16/Python-3.13.16.tar.xz#f4b1bfb3c79b5bb11b8d228a12504163b4c0dab4d679828d8f5f26b6cb6ab35d" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.16" "https://www.python.org/ftp/python/3.13.16/Python-3.13.16.tgz#cfac63bddf956deafb1172ca131ae5dcaafd6f95056086e233fca205593ed427" standard verify_py313 copy_python_gdb ensurepip
fi

View File

@ -0,0 +1,2 @@
export PYTHON_BUILD_FREE_THREADING=1
source "${BASH_SOURCE[0]%t}"

View File

@ -0,0 +1,11 @@
prefer_openssl3_to_4
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL_RPATH=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-4.0.3" "https://github.com/openssl/openssl/releases/download/openssl-4.0.3/openssl-4.0.3.tar.gz#325b5c806167c13b40b1ffeadfe0248197c00eccc4cf123ec1e28d2d2fd216d9" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "https://ftpmirror.gnu.org/readline/readline-8.3.tar.gz#fe5383204467828cd495ee8d1d3c037a7eba1389c22bc6a041f627976f9061cc" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.14.8" "https://www.python.org/ftp/python/3.14.8/Python-3.14.8.tar.xz#c2215904f02b175596dc49351585104f4bc20341e1c47378b26a2c274360ce73" standard verify_py314 copy_python_gdb ensurepip
else
install_package "Python-3.14.8" "https://www.python.org/ftp/python/3.14.8/Python-3.14.8.tgz#a65b20a728f169f4e66ae143f40b1bd3d33c38d770251663f627c9767b79b210" standard verify_py314 copy_python_gdb ensurepip
fi

View File

@ -0,0 +1,2 @@
export PYTHON_BUILD_FREE_THREADING=1
source "${BASH_SOURCE[0]%t}"

View File

@ -18,6 +18,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE. # SOFTWARE.
VERSION='25.3.4.1' VERSION='25.3.4.1'
RELEASE_TAG='graal-25.3.4'
colorize 1 "GraalPy 23.1 and later installed by python-build use the faster Oracle GraalVM distribution" && echo colorize 1 "GraalPy 23.1 and later installed by python-build use the faster Oracle GraalVM distribution" && echo
colorize 1 "Oracle GraalVM uses the GFTC license, which is free for development and production use, see https://medium.com/graalvm/161527df3d76" && echo colorize 1 "Oracle GraalVM uses the GFTC license, which is free for development and production use, see https://medium.com/graalvm/161527df3d76" && echo
@ -46,4 +47,4 @@ case "$graalpy_arch" in
;; ;;
esac esac
install_package "graalpy3.13-${VERSION}" "https://github.com/oracle/graalpython/releases/download/graal-${VERSION}/graalpy3.13-${VERSION}-${graalpy_arch}.tar.gz#${checksum}" "copy" ensurepip install_package "graalpy3.13-${VERSION}" "https://github.com/oracle/graalpython/releases/download/${RELEASE_TAG}/graalpy3.13-${VERSION}-${graalpy_arch}.tar.gz#${checksum}" "copy" ensurepip

View File

@ -0,0 +1,50 @@
# Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
VERSION='25.4.4'
RELEASE_TAG='graal-25.4.4'
colorize 1 "GraalPy 23.1 and later installed by python-build use the faster Oracle GraalVM distribution" && echo
colorize 1 "Oracle GraalVM uses the GFTC license, which is free for development and production use, see https://medium.com/graalvm/161527df3d76" && echo
colorize 1 "The GraalVM Community Edition variant of GraalPy is also available, under the name graalpy3.13-community-${VERSION}" && echo
graalpy_arch="$(graalpy_architecture 2>/dev/null || true)"
case "$graalpy_arch" in
"linux-amd64" )
checksum="8b72e6e513d06976e5c8e051228d69d541fde76d05d5f907eaef4bb31db83af4"
;;
"linux-aarch64" )
checksum="1323dc064583efd1d6b696d3a9f9e4b1ff8facd0f7cc2b69fe0a0bf7ef06ea1a"
;;
"macos-aarch64" )
checksum="aacd819b5c3b6889b6a6275d8009ec1e8e3fe27cf7b77265710a1c9ea931bedd"
;;
* )
{ echo
colorize 1 "ERROR"
echo ": No binary distribution of GraalPy is available for $(uname -sm)."
echo
} >&2
exit 1
;;
esac
install_package "graalpy3.13-${VERSION}" "https://github.com/oracle/graalpython/releases/download/${RELEASE_TAG}/graalpy3.13-${VERSION}-${graalpy_arch}.tar.gz#${checksum}" "copy" ensurepip

View File

@ -18,6 +18,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE. # SOFTWARE.
VERSION='25.3.4.1' VERSION='25.3.4.1'
RELEASE_TAG='graal-25.3.4'
graalpy_arch="$(graalpy_architecture 2>/dev/null || true)" graalpy_arch="$(graalpy_architecture 2>/dev/null || true)"
@ -41,4 +42,4 @@ case "$graalpy_arch" in
;; ;;
esac esac
install_package "graalpy3.13-community-${VERSION}" "https://github.com/oracle/graalpython/releases/download/graal-${VERSION}/graalpy3.13-community-${VERSION}-${graalpy_arch}.tar.gz#${checksum}" "copy" ensurepip install_package "graalpy3.13-community-${VERSION}" "https://github.com/oracle/graalpython/releases/download/${RELEASE_TAG}/graalpy3.13-community-${VERSION}-${graalpy_arch}.tar.gz#${checksum}" "copy" ensurepip

View File

@ -0,0 +1,45 @@
# Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal in
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
VERSION='25.4.4'
RELEASE_TAG='graal-25.4.4'
graalpy_arch="$(graalpy_architecture 2>/dev/null || true)"
case "$graalpy_arch" in
"linux-amd64" )
checksum="a038c8fa650f3bd17046f3cb8609b271e07b0e21fdb8527f10726beee442b93d"
;;
"linux-aarch64" )
checksum="5d0fab1a2f541b387dbf3fbf6b123a5836a0bc99937076f34aeb29282ee246c1"
;;
"macos-aarch64" )
checksum="dce08327e8ccb48423cc50f72a5137d4ff8c9da8ff7319525a69e2e68ac637cd"
;;
* )
{ echo
colorize 1 "ERROR"
echo ": No binary distribution of GraalPy is available for $(uname -sm)."
echo
} >&2
exit 1
;;
esac
install_package "graalpy3.13-community-${VERSION}" "https://github.com/oracle/graalpython/releases/download/${RELEASE_TAG}/graalpy3.13-community-${VERSION}-${graalpy_arch}.tar.gz#${checksum}" "copy" ensurepip

View File

@ -0,0 +1,20 @@
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniconda3-py310_26.7.1-0-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.7.1-0-Linux-aarch64.sh#caf3e9652f32f40d8755c22678c315f6305c04f68c47ff3e76e625d26f17f59b" "miniconda" verify_py310
;;
"Linux-x86_64" )
install_script "Miniconda3-py310_26.7.1-0-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.7.1-0-Linux-x86_64.sh#acc1cda57155ecacb854b49bb5875eadb6500d1ea70176f44e8b7a321f59d620" "miniconda" verify_py310
;;
"MacOSX-arm64" )
install_script "Miniconda3-py310_26.7.1-0-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.7.1-0-MacOSX-arm64.sh#07b3e50a23a39db29c8dde820a4ab662532086a5da849a466f582f180115bce9" "miniconda" verify_py310
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,20 @@
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniconda3-py310_26.7.1-1-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.7.1-1-Linux-aarch64.sh#1a77b0376464ab4a35df7ec033ee86875b9a932d29d985ce5bc2e4a16790e153" "miniconda" verify_py310
;;
"Linux-x86_64" )
install_script "Miniconda3-py310_26.7.1-1-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.7.1-1-Linux-x86_64.sh#fb1af4c45e6e73fe193c2398b4346b1e45522f729cdfccfdb18f6c765954dbd9" "miniconda" verify_py310
;;
"MacOSX-arm64" )
install_script "Miniconda3-py310_26.7.1-1-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py310_26.7.1-1-MacOSX-arm64.sh#56c8b663e389605596fef71797367f30fa60ddc3022630c1bca309a09e833661" "miniconda" verify_py310
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,20 @@
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniconda3-py311_26.7.1-0-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.7.1-0-Linux-aarch64.sh#f20e0a792cea183252f832f2ba68b05f34ddb2f728d97c64a2adf04ebaaca62d" "miniconda" verify_py311
;;
"Linux-x86_64" )
install_script "Miniconda3-py311_26.7.1-0-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.7.1-0-Linux-x86_64.sh#b5e7fa2d712bfc4b2d1d300e3ebbd9064491420efdb520753ab4e2e10f09ed75" "miniconda" verify_py311
;;
"MacOSX-arm64" )
install_script "Miniconda3-py311_26.7.1-0-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.7.1-0-MacOSX-arm64.sh#6415f748347a56c7b4a60271aad7bb85b8365f00aae69eacc2cd1612cd8955ac" "miniconda" verify_py311
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,20 @@
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniconda3-py311_26.7.1-1-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.7.1-1-Linux-aarch64.sh#3dec21b8c8612be0fdff92938c010752eb2ee46d413b74cac68d4c9547270937" "miniconda" verify_py311
;;
"Linux-x86_64" )
install_script "Miniconda3-py311_26.7.1-1-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.7.1-1-Linux-x86_64.sh#a6f98e6e19d5b7897ae887cd6af931eb863459f86ffd1a09cc370124cab0993e" "miniconda" verify_py311
;;
"MacOSX-arm64" )
install_script "Miniconda3-py311_26.7.1-1-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py311_26.7.1-1-MacOSX-arm64.sh#da6322bf9a213536df5ce630da2a249b9fb6d433f439b84be07003a790be6be6" "miniconda" verify_py311
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,20 @@
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniconda3-py312_26.7.1-0-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.7.1-0-Linux-aarch64.sh#391edcfaef0e70b7047834a86e48f5686eb0fe1e7612a086ca73e0084ffea45f" "miniconda" verify_py312
;;
"Linux-x86_64" )
install_script "Miniconda3-py312_26.7.1-0-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.7.1-0-Linux-x86_64.sh#3d33f72fcb35134ab68a7775021a0ee6d22b8a4dd9139d9c9798792e933ee132" "miniconda" verify_py312
;;
"MacOSX-arm64" )
install_script "Miniconda3-py312_26.7.1-0-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.7.1-0-MacOSX-arm64.sh#1d9cb2f5c6ea2ce48711ba42f62c2b9e14094a8ef9781c98981bb9b9d9813862" "miniconda" verify_py312
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,20 @@
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniconda3-py312_26.7.1-1-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.7.1-1-Linux-aarch64.sh#f6d64a1565e713429683720f59dd6661f5131c2f959a4830438eb1969cde23f7" "miniconda" verify_py312
;;
"Linux-x86_64" )
install_script "Miniconda3-py312_26.7.1-1-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.7.1-1-Linux-x86_64.sh#b27f60ab63e77eeab50a5417c989120f767e863df32400190d4c7262369f8695" "miniconda" verify_py312
;;
"MacOSX-arm64" )
install_script "Miniconda3-py312_26.7.1-1-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py312_26.7.1-1-MacOSX-arm64.sh#fc46408196d7383fcb03e1235b6891a5983fa3e0f56877eec7b27950130e7605" "miniconda" verify_py312
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,20 @@
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniconda3-py313_26.7.1-0-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.7.1-0-Linux-aarch64.sh#e556d9805217d9798fa5fca0e190905c218025b552cee1fc2526dc55e498744d" "miniconda" verify_py313
;;
"Linux-x86_64" )
install_script "Miniconda3-py313_26.7.1-0-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.7.1-0-Linux-x86_64.sh#3ad92b3b7fc3c82d6b649f76c688c89ae70b3eb267cc6bee8e657084a0ee3748" "miniconda" verify_py313
;;
"MacOSX-arm64" )
install_script "Miniconda3-py313_26.7.1-0-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.7.1-0-MacOSX-arm64.sh#1dfed26e3e7fe750a5626734cf9b4edb0ca0a55f3e9e395dba3ef8daeb79ecb5" "miniconda" verify_py313
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,20 @@
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniconda3-py313_26.7.1-1-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.7.1-1-Linux-aarch64.sh#669e8f11248e97473ff058d97eb02b6c8e67f6c853e230f7a88cce95303c9fce" "miniconda" verify_py313
;;
"Linux-x86_64" )
install_script "Miniconda3-py313_26.7.1-1-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.7.1-1-Linux-x86_64.sh#c26cbbd996d5ada0bec054b49a37fab690e2f91125701e458df6cca73da9482b" "miniconda" verify_py313
;;
"MacOSX-arm64" )
install_script "Miniconda3-py313_26.7.1-1-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py313_26.7.1-1-MacOSX-arm64.sh#689068fd5c3aaeb0137aad1202dd1743d4d8b62cf3b4b487e53787ef8a04feae" "miniconda" verify_py313
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,20 @@
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniconda3-py314_26.7.1-0-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py314_26.7.1-0-Linux-aarch64.sh#f1f9342b74c24e320f927f1d315784fa9f8ea3124aab9ead2f188ee9771f4430" "miniconda" verify_py314
;;
"Linux-x86_64" )
install_script "Miniconda3-py314_26.7.1-0-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py314_26.7.1-0-Linux-x86_64.sh#f87bfab5ccdcb80894518f868c80cc321ac1ebc7d18d07792d59895bbc30b313" "miniconda" verify_py314
;;
"MacOSX-arm64" )
install_script "Miniconda3-py314_26.7.1-0-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py314_26.7.1-0-MacOSX-arm64.sh#933860616eff59f858f94ee086be1a645b8d1710cf449a078d22de14e8755468" "miniconda" verify_py314
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,20 @@
export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniconda3-py314_26.7.1-1-Linux-aarch64" "https://repo.anaconda.com/miniconda/Miniconda3-py314_26.7.1-1-Linux-aarch64.sh#e31545afd7462d3c9c33b154c7a101c5acb5e01b69380b6994651aead6942893" "miniconda" verify_py314
;;
"Linux-x86_64" )
install_script "Miniconda3-py314_26.7.1-1-Linux-x86_64" "https://repo.anaconda.com/miniconda/Miniconda3-py314_26.7.1-1-Linux-x86_64.sh#e8b25b92b262499141c5bd57a98d3c008024185fa951494b9cd9b6d94e72338b" "miniconda" verify_py314
;;
"MacOSX-arm64" )
install_script "Miniconda3-py314_26.7.1-1-MacOSX-arm64" "https://repo.anaconda.com/miniconda/Miniconda3-py314_26.7.1-1-MacOSX-arm64.sh#9bdf85d31ea3b4b85ef26b2762d68e2d849fdd38b608fb5272127acef802ff75" "miniconda" verify_py314
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniconda is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,25 @@
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniforge3-26.5.3-0-Linux-aarch64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.5.3-0/Miniforge3-26.5.3-0-Linux-aarch64.sh#0391e42075a7632e9665d6e728387ee6b905f6c3e704d3513e1c1133d0d69b89" "miniconda" verify_py314
;;
"Linux-ppc64le" )
install_script "Miniforge3-26.5.3-0-Linux-ppc64le.sh" "https://github.com/conda-forge/miniforge/releases/download/26.5.3-0/Miniforge3-26.5.3-0-Linux-ppc64le.sh#a77ac9485c7ae7287b2c8eaa38caf44d661509eb0134643f10a7e816ce414ac2" "miniconda" verify_py314
;;
"Linux-x86_64" )
install_script "Miniforge3-26.5.3-0-Linux-x86_64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.5.3-0/Miniforge3-26.5.3-0-Linux-x86_64.sh#14db468222ad564658656f769506056209b6dc375f5e7dfd31eb5ebbf08fa529" "miniconda" verify_py314
;;
"MacOSX-arm64" )
install_script "Miniforge3-26.5.3-0-MacOSX-arm64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.5.3-0/Miniforge3-26.5.3-0-MacOSX-arm64.sh#0d765919d3ccfd1f89147aa1cf8133bfc55b3a3c13f5bacdcc091c33132fddd2" "miniconda" verify_py314
;;
"MacOSX-x86_64" )
install_script "Miniforge3-26.5.3-0-MacOSX-x86_64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.5.3-0/Miniforge3-26.5.3-0-MacOSX-x86_64.sh#0266a7bfeb12165286133145717bef0d88070f1b76710beb6a62fec4e88371a1" "miniconda" verify_py314
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniforge is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,28 @@
case "$(anaconda_architecture 2>/dev/null || true)" in
"Linux-aarch64" )
install_script "Miniforge3-26.7.2-0-Linux-aarch64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.7.2-0/Miniforge3-26.7.2-0-Linux-aarch64.sh#89b786c8d2c8b0fda7553914c1314ae4ddaa094503802f279377b19ac4463cb2" "miniconda" verify_py314
;;
"Linux-ppc64le" )
install_script "Miniforge3-26.7.2-0-Linux-ppc64le.sh" "https://github.com/conda-forge/miniforge/releases/download/26.7.2-0/Miniforge3-26.7.2-0-Linux-ppc64le.sh#466e6af6766fe3d9aea18a7a6431d480f3a64995d53e8cbd438ca5a064b2c945" "miniconda" verify_py314
;;
"Linux-riscv64" )
install_script "Miniforge3-26.7.2-0-Linux-riscv64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.7.2-0/Miniforge3-26.7.2-0-Linux-riscv64.sh#a82efd1197849cd6755c080bd883ed376eda09080f52bfe9051912afdd05c281" "miniconda" verify_py314
;;
"Linux-x86_64" )
install_script "Miniforge3-26.7.2-0-Linux-x86_64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.7.2-0/Miniforge3-26.7.2-0-Linux-x86_64.sh#281b0ac7d550802efc81af633225a5e6116d29ae72f3ab4eae7168c3931a4c05" "miniconda" verify_py314
;;
"MacOSX-arm64" )
install_script "Miniforge3-26.7.2-0-MacOSX-arm64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.7.2-0/Miniforge3-26.7.2-0-MacOSX-arm64.sh#d70bfa2e97afcda96927c9b9ca0e2316cb7750e4ce651c94388267cbe9588711" "miniconda" verify_py314
;;
"MacOSX-x86_64" )
install_script "Miniforge3-26.7.2-0-MacOSX-x86_64.sh" "https://github.com/conda-forge/miniforge/releases/download/26.7.2-0/Miniforge3-26.7.2-0-MacOSX-x86_64.sh#b00e7798658f92721a3ae2f6b9832695ffc6baf07758894d726268055359f6c5" "miniconda" verify_py314
;;
* )
{ echo
colorize 1 "ERROR"
echo ": The binary distribution of Miniforge is not available for $(anaconda_architecture 2>/dev/null || true)."
echo
} >&2
exit 1
;;
esac

View File

@ -0,0 +1,109 @@
From 639cdfe83c371bcc87969cb6db926bc360135ac9 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 1baa145e3ed..b67faee87a8 100755
--- a/configure
+++ b/configure
@@ -11709,7 +11709,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11719,7 +11719,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -11762,6 +11762,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 3e6c07c2793..c431bf42398 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3680,7 +3680,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3690,7 +3690,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3712,6 +3712,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 6fa96938bf9512e0205b279801a181ff2666df34 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 2e7e0b7e0a7..04e72587bbf 100755
--- a/configure
+++ b/configure
@@ -11940,7 +11940,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11950,7 +11950,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -11993,6 +11993,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 0c069141478..96bcd704a07 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3702,7 +3702,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3712,7 +3712,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3734,6 +3734,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 3cf76ece0608dbb12ff03e7c8d406e7b7db2b267 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From a57787f02b8748622e4d6ca503bfda5eea2952ec Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From e7a4c51e2b860939fd571d9062ae48d65a8ef6ce Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From dec047356c85880ccde9ceb08aec873150ebb6ce Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From aa13fa0dccef42fe23311544960cfda52169e89f Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 169cf06dbfe83862835225eb170e199d7060f5c0 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 72b6601d648c31b0f970859d820c7cfa6d731ac8 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From e2eacb52f1825425539ae8d777a35ae62ea003ad Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 2c0df425ef4e26366251172e040a9d6cfb1f9471 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 5e98482b7f8a32b769426b279742504aa45ba9a7 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From bc7cf075bc9476e358303855ca4a7c88f2103108 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index a7d2975f1f5..c0b730f2746 100755
--- a/configure
+++ b/configure
@@ -11951,7 +11951,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11961,7 +11961,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12004,6 +12004,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 5aa91cbad35..9eae56f1d31 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3707,7 +3707,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3717,7 +3717,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3739,6 +3739,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 95ca265cab510ac5ccf8da44b45234e1d51dcfd7 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From cf8eba395ddf888ce7d9e5e4a257209841aff6a4 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,27 @@
From 3fec519d6b326918f39ceb142ef762042ce8365f Mon Sep 17 00:00:00 2001
From: Ivan Pozdeev <vano@mail.mipt.ru>
Date: Fri, 26 Dec 2025 13:39:21 +0300
Subject: [PATCH] Recognize an argument to -j in MAKEFLAGS
---
setup.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/setup.py b/setup.py
index ad8fb81b218..5666deaf67b 100644
--- a/setup.py
+++ b/setup.py
@@ -307,8 +307,8 @@ def __init__(self, dist):
self.failed_on_import = []
self.missing = []
self.disabled_configure = []
- if '-j' in os.environ.get('MAKEFLAGS', ''):
- self.parallel = True
+ if (m:=re.search(r'(?:^|\s)(?:-j|--jobs)(?:\s+|=)?(\d*)',os.environ.get('MAKEFLAGS', ''))) is not None:
+ self.parallel = int(m.group(1)) if m.group(1) else True
def add(self, ext):
self.extensions.append(ext)
--
2.36.1.windows.1

View File

@ -0,0 +1,109 @@
From cf8eba395ddf888ce7d9e5e4a257209841aff6a4 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 43ec16e5e7b527cff1c9e47699248f04afe8cf37 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 0cc86f9ed76..3c3eb939642 100755
--- a/configure
+++ b/configure
@@ -11951,7 +11951,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11961,7 +11961,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12004,6 +12004,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 547255ff31e..13d44972ea8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3707,7 +3707,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3717,7 +3717,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3739,6 +3739,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 654bafbe923d5a8f7ef7c3dee3f4bc9e4fef0139 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 19f1bd59ba8..5e3f216954e 100755
--- a/configure
+++ b/configure
@@ -11951,7 +11951,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11961,7 +11961,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12004,6 +12004,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 763fc697be7..c06f1a567c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3707,7 +3707,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3717,7 +3717,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3739,6 +3739,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From fb4d6093b2b2e557711a747bae5c16742abf49bc Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 19f1bd59ba8..5e3f216954e 100755
--- a/configure
+++ b/configure
@@ -11951,7 +11951,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11961,7 +11961,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12004,6 +12004,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 763fc697be7..c06f1a567c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3707,7 +3707,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3717,7 +3717,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3739,6 +3739,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From d3864984569660dccaa498b92d8fdabe9d291882 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 19f1bd59ba8..5e3f216954e 100755
--- a/configure
+++ b/configure
@@ -11951,7 +11951,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11961,7 +11961,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12004,6 +12004,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 763fc697be7..c06f1a567c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3707,7 +3707,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3717,7 +3717,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3739,6 +3739,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From c3f875f9d55c7e2040dac25a8afcdd048d87b50b Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index bad619963ad..bb7f6bb1c00 100755
--- a/configure
+++ b/configure
@@ -11951,7 +11951,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11961,7 +11961,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12004,6 +12004,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index cc69015b102..e2ab2faed28 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3707,7 +3707,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3717,7 +3717,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3739,6 +3739,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From b1d96618e86c6135eba1556ca096ba1ab69b6973 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index bad619963ad..bb7f6bb1c00 100755
--- a/configure
+++ b/configure
@@ -11951,7 +11951,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11961,7 +11961,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12004,6 +12004,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index cc69015b102..e2ab2faed28 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3707,7 +3707,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3717,7 +3717,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3739,6 +3739,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From c6b863db3ae5e6e142d5ea24ac72a3cbc9c68ac9 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.10] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 4b71c4e00f8..bfe3e819fff 100755
--- a/configure
+++ b/configure
@@ -11952,7 +11952,7 @@ fi
# checks for library functions
for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -11962,7 +11962,7 @@ for ac_func in alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -12005,6 +12005,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ac3be3850a9..0b88132edfb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3708,7 +3708,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
- clock confstr close_range copy_file_range ctermid dup3 execv explicit_bzero \
+ clock confstr close_range copy_file_range ctermid execv explicit_bzero \
explicit_memset faccessat fchmod fchmodat fchown fchownat \
fdwalk fexecve fdopendir fork fpathconf fstatat ftime ftruncate futimesat \
futimens futimes gai_strerror getentropy \
@@ -3718,7 +3718,7 @@ AC_CHECK_FUNCS(alarm accept4 setitimer getitimer bind_textdomain_codeset chown \
if_nameindex \
initgroups kill killpg lchown lockf linkat lstat lutimes mmap \
memrchr mbrtowc mkdirat mkfifo \
- madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause pipe2 plock poll \
+ madvise mkfifoat mknod mknodat mktime mremap nice openat pathconf pause plock poll \
posix_fallocate posix_fadvise posix_spawn posix_spawnp pread preadv preadv2 \
pthread_condattr_setclock pthread_init pthread_kill pwrite pwritev pwritev2 \
readlink readlinkat readv realpath renameat \
@@ -3740,6 +3740,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 7ebb74cb3b6b0b163d3bd07ea2ef21e5446c505b Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 784f8d30609..bc7c194e866 100755
--- a/configure
+++ b/configure
@@ -14966,7 +14966,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -14976,7 +14976,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15019,6 +15019,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index ab5e1de6fab..f70d17f4cdb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4543,7 +4543,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4553,7 +4553,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4575,6 +4575,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 23afa3cb08eb7a95c5549e46c6275af3bbf0bc93 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 9567ac3a62c..65ed2916e09 100755
--- a/configure
+++ b/configure
@@ -15158,7 +15158,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15168,7 +15168,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15211,6 +15211,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 90008bcae17..0816d477558 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4582,7 +4582,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4592,7 +4592,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4614,6 +4614,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 531b50ba6658c58f015de4f4f8aef8d3ef03ca0d Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index a1ad0ae2510..76a3eec37be 100755
--- a/configure
+++ b/configure
@@ -15209,7 +15209,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15219,7 +15219,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15262,6 +15262,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 7b4000fa9c3..44167040f3e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4594,7 +4594,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4604,7 +4604,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4626,6 +4626,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 5699cd1a15ba3f0474ad61aaeb94ad1ad2dfc833 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index a1ad0ae2510..76a3eec37be 100755
--- a/configure
+++ b/configure
@@ -15209,7 +15209,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15219,7 +15219,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15262,6 +15262,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 7b4000fa9c3..44167040f3e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4594,7 +4594,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4604,7 +4604,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4626,6 +4626,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From b8b17a685e1e4beac5a00540dde764213200a724 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index a1ad0ae2510..76a3eec37be 100755
--- a/configure
+++ b/configure
@@ -15209,7 +15209,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15219,7 +15219,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15262,6 +15262,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 7b4000fa9c3..44167040f3e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4594,7 +4594,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4604,7 +4604,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4626,6 +4626,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 2fa150b3f0bce148cda2d2acf10973941580e9c8 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index a1ad0ae2510..76a3eec37be 100755
--- a/configure
+++ b/configure
@@ -15209,7 +15209,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15219,7 +15219,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15262,6 +15262,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 7b4000fa9c3..44167040f3e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4594,7 +4594,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4604,7 +4604,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4626,6 +4626,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From c721b82ced0789df0643b87327440bea4fa8062c Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index a1ad0ae2510..76a3eec37be 100755
--- a/configure
+++ b/configure
@@ -15209,7 +15209,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15219,7 +15219,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15262,6 +15262,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 7b4000fa9c3..44167040f3e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4594,7 +4594,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4604,7 +4604,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4626,6 +4626,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 3f03fe05c04c7dbd8ff3206c7f56d41638c90681 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 5ffa02dcb5b..1b90ed0d119 100755
--- a/configure
+++ b/configure
@@ -15209,7 +15209,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15219,7 +15219,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15262,6 +15262,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index bfc99cc4268..08c7df52a7a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4594,7 +4594,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4604,7 +4604,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4626,6 +4626,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 29e98f7040994fa86bf63845b00ab9a4d80f5931 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index a1ad0ae2510..76a3eec37be 100755
--- a/configure
+++ b/configure
@@ -15209,7 +15209,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15219,7 +15219,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15262,6 +15262,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 7b4000fa9c3..44167040f3e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4594,7 +4594,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4604,7 +4604,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4626,6 +4626,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,27 @@
From 3fec519d6b326918f39ceb142ef762042ce8365f Mon Sep 17 00:00:00 2001
From: Ivan Pozdeev <vano@mail.mipt.ru>
Date: Fri, 26 Dec 2025 13:39:21 +0300
Subject: [PATCH] Recognize an argument to -j in MAKEFLAGS
---
setup.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/setup.py b/setup.py
index ad8fb81b218..5666deaf67b 100644
--- a/setup.py
+++ b/setup.py
@@ -307,8 +307,8 @@ def __init__(self, dist):
self.failed_on_import = []
self.missing = []
self.disabled_configure = []
- if '-j' in os.environ.get('MAKEFLAGS', ''):
- self.parallel = True
+ if (m:=re.search(r'(?:^|\s)(?:-j|--jobs)(?:\s+|=)?(\d*)',os.environ.get('MAKEFLAGS', ''))) is not None:
+ self.parallel = int(m.group(1)) if m.group(1) else True
def add(self, ext):
self.extensions.append(ext)
--
2.36.1.windows.1

View File

@ -0,0 +1,64 @@
From cc13eabc7ce08accf49656e258ba500f74a1dae8 Mon Sep 17 00:00:00 2001
From: Ronald Oussoren <ronaldoussoren@mac.com>
Date: Thu, 28 Dec 2023 09:42:05 +0100
Subject: [PATCH] gh-110459: Make sure --with-openssl-rpath works on macOS
(#113441)
* gh-110459: Make sure --with-openssl-rpath works on macOS
On macOS the `-rpath` linker flag is spelled differently
than on on platforms.
---
.../macOS/2023-12-23-22-41-07.gh-issue-110459.NaMBJy.rst | 2 ++
configure | 7 ++++++-
configure.ac | 7 ++++++-
3 files changed, 14 insertions(+), 2 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2023-12-23-22-41-07.gh-issue-110459.NaMBJy.rst
diff --git a/Misc/NEWS.d/next/macOS/2023-12-23-22-41-07.gh-issue-110459.NaMBJy.rst b/Misc/NEWS.d/next/macOS/2023-12-23-22-41-07.gh-issue-110459.NaMBJy.rst
new file mode 100644
index 00000000000..44ffd857785
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2023-12-23-22-41-07.gh-issue-110459.NaMBJy.rst
@@ -0,0 +1,2 @@
+Running ``configure ... --with-openssl-rpath=X/Y/Z`` no longer fails to detect
+OpenSSL on macOS.
diff --git a/configure b/configure
index 7e50abc29d0..6d65d3abc18 100755
--- a/configure
+++ b/configure
@@ -27478,7 +27478,12 @@ then :
else $as_nop
- rpath_arg="-Wl,-rpath="
+ if test "$ac_sys_system" = "Darwin"
+ then
+ rpath_arg="-Wl,-rpath,"
+ else
+ rpath_arg="-Wl,-rpath="
+ fi
fi
diff --git a/configure.ac b/configure.ac
index e064848af9e..bfdabc4474e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6808,7 +6808,12 @@ AX_CHECK_OPENSSL([have_openssl=yes],[have_openssl=no])
AS_VAR_IF([GNULD], [yes], [
rpath_arg="-Wl,--enable-new-dtags,-rpath="
], [
- rpath_arg="-Wl,-rpath="
+ if test "$ac_sys_system" = "Darwin"
+ then
+ rpath_arg="-Wl,-rpath,"
+ else
+ rpath_arg="-Wl,-rpath="
+ fi
])
AC_MSG_CHECKING([for --with-openssl-rpath])
--
2.46.2.windows.1

View File

@ -0,0 +1,109 @@
From 29e98f7040994fa86bf63845b00ab9a4d80f5931 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index a1ad0ae2510..76a3eec37be 100755
--- a/configure
+++ b/configure
@@ -15209,7 +15209,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15219,7 +15219,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15262,6 +15262,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index 7b4000fa9c3..44167040f3e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4594,7 +4594,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4604,7 +4604,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4626,6 +4626,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From d1ea67d806c3f9370a0217902fd06f93dfbd58ae Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 9e76287725b..7bb2018d9b9 100755
--- a/configure
+++ b/configure
@@ -15160,7 +15160,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15170,7 +15170,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15213,6 +15213,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index c62a565eb68..8b618d89fb6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4582,7 +4582,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4592,7 +4592,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4614,6 +4614,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From a6a677bd661d3e1230d376787dc365519746d051 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index 9e76287725b..7bb2018d9b9 100755
--- a/configure
+++ b/configure
@@ -15160,7 +15160,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15170,7 +15170,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15213,6 +15213,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index c62a565eb68..8b618d89fb6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4582,7 +4582,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4592,7 +4592,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4614,6 +4614,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,117 @@
From 9b4547ee5f8d1d3d00fb0383a1c5e65cc1aa1b86 Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 ++
configure | 31 ++++++++++++-------
configure.ac | 11 +++++--
3 files changed, 31 insertions(+), 14 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index a66a081a76b..0f0a4a4cf30 100755
--- a/configure
+++ b/configure
@@ -16517,12 +16517,6 @@ if test "x$ac_cv_func_dup" = xyes
then :
printf "%s\n" "#define HAVE_DUP 1" >>confdefs.h
-fi
-ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
-if test "x$ac_cv_func_dup3" = xyes
-then :
- printf "%s\n" "#define HAVE_DUP3 1" >>confdefs.h
-
fi
ac_fn_c_check_func "$LINENO" "execv" "ac_cv_func_execv"
if test "x$ac_cv_func_execv" = xyes
@@ -16991,12 +16985,6 @@ if test "x$ac_cv_func_pipe" = xyes
then :
printf "%s\n" "#define HAVE_PIPE 1" >>confdefs.h
-fi
-ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
-if test "x$ac_cv_func_pipe2" = xyes
-then :
- printf "%s\n" "#define HAVE_PIPE2 1" >>confdefs.h
-
fi
ac_fn_c_check_func "$LINENO" "plock" "ac_cv_func_plock"
if test "x$ac_cv_func_plock" = xyes
@@ -17571,6 +17559,25 @@ fi
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC options needed to detect all undeclared functions" >&5
printf %s "checking for $CC options needed to detect all undeclared functions... " >&6; }
if test ${ac_cv_c_undeclared_builtin_options+y}
diff --git a/configure.ac b/configure.ac
index 1c25abd65a0..d8f7b64ea60 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4582,7 +4582,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4592,7 +4592,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4614,6 +4614,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 3164590efaab7b21c093b50e78c3d332494b037c Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index af4a5bbfdfa..e929659dc62 100755
--- a/configure
+++ b/configure
@@ -15198,7 +15198,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15208,7 +15208,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15251,6 +15251,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index e1cbb7c7fbe..d3a1cd1be6b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4586,7 +4586,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4596,7 +4596,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4618,6 +4618,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

View File

@ -0,0 +1,109 @@
From 4cb7a6c0d9769517ecc8714da0c6668dec76639f Mon Sep 17 00:00:00 2001
From: Ned Deily <nad@python.org>
Date: Wed, 5 Aug 2026 10:30:17 +0300
Subject: [PATCH] (downstream) [3.11] gh-153711: Avoid use of dup3 and pipe2
calls introduced in macOS 27 (#155211)
---
...-08-05-02-02-33.gh-issue-153711.pO9fFb.rst | 3 +++
configure | 23 +++++++++++++++++--
configure.ac | 11 +++++++--
3 files changed, 33 insertions(+), 4 deletions(-)
create mode 100644 Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
diff --git a/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
new file mode 100644
index 00000000000..90804c179a4
--- /dev/null
+++ b/Misc/NEWS.d/next/macOS/2026-08-05-02-02-33.gh-issue-153711.pO9fFb.rst
@@ -0,0 +1,3 @@
+On macOS, do not attempt to use the :manpage:`dup3(2)` and
+:manpage:`pipe2(2)` system calls introduced in
+macOS 27 to prevent problems when running on older systems.
diff --git a/configure b/configure
index af4a5bbfdfa..e929659dc62 100755
--- a/configure
+++ b/configure
@@ -15198,7 +15198,7 @@ fi
# checks for library functions
for ac_func in \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -15208,7 +15208,7 @@ for ac_func in \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -15251,6 +15251,25 @@ done
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ ac_fn_c_check_func "$LINENO" "dup3" "ac_cv_func_dup3"
+if test "x$ac_cv_func_dup3" = xyes
+then :
+ printf '%s\n' "#define HAVE_DUP3 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "pipe2" "ac_cv_func_pipe2"
+if test "x$ac_cv_func_pipe2" = xyes
+then :
+ printf '%s\n' "#define HAVE_PIPE2 1" >>confdefs.h
+
+fi
+
+fi
+
ac_fn_c_check_decl "$LINENO" "dirfd" "ac_cv_have_decl_dirfd" "#include <sys/types.h>
#include <dirent.h>
"
diff --git a/configure.ac b/configure.ac
index e1cbb7c7fbe..d3a1cd1be6b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4586,7 +4586,7 @@ fi
# checks for library functions
AC_CHECK_FUNCS([ \
accept4 alarm bind_textdomain_codeset chmod chown clock close_range confstr \
- copy_file_range ctermid dup dup3 execv explicit_bzero explicit_memset \
+ copy_file_range ctermid dup execv explicit_bzero explicit_memset \
faccessat fchmod fchmodat fchown fchownat fdopendir fdwalk fexecve \
fork fork1 fpathconf fstatat ftime ftruncate futimens futimes futimesat \
gai_strerror getegid getentropy geteuid getgid getgrgid getgrgid_r \
@@ -4596,7 +4596,7 @@ AC_CHECK_FUNCS([ \
getspnam getuid getwd if_nameindex initgroups kill killpg lchown linkat \
lockf lstat lutimes madvise mbrtowc memrchr mkdirat mkfifo mkfifoat \
mknod mknodat mktime mmap mremap nice openat opendir pathconf pause pipe \
- pipe2 plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
+ plock poll posix_fadvise posix_fallocate posix_spawn posix_spawnp \
pread preadv preadv2 pthread_condattr_setclock pthread_init pthread_kill \
pwrite pwritev pwritev2 readlink readlinkat readv realpath renameat \
rtpSpawn sched_get_priority_max sched_rr_get_interval sched_setaffinity \
@@ -4618,6 +4618,13 @@ if test "$MACHDEP" != linux; then
AC_CHECK_FUNCS(lchmod)
fi
+# macOS introduced dup3 and pipe2 in macOS 27, late in the
+# lifetime of this version of Python. Rather than adding weaklinking
+# support for them, just continue to ignore them.
+if test "$ac_sys_system" != "Darwin"; then
+ AC_CHECK_FUNCS([dup3 pipe2])
+fi
+
AC_CHECK_DECL(dirfd,
AC_DEFINE(HAVE_DIRFD, 1,
Define if you have the 'dirfd' function or macro.), ,
--
2.55.0.windows.3

Some files were not shown because too many files have changed in this diff Show More