Compare commits

..

No commits in common. "master" and "v2.4.23" have entirely different histories.

343 changed files with 1057 additions and 8424 deletions

1
.github/CODEOWNERS vendored
View File

@ -1 +0,0 @@
* @pyenv/pyenv-core-maintainers @pyenv/pyenv-core-committers

26
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,26 @@
Too many issues will kill our team's development velocity, drastically.
Make sure you have checked all steps below.
### Prerequisite
* [ ] Make sure your problem is not listed in [the common build problems](https://github.com/pyenv/pyenv/wiki/Common-build-problems).
* [ ] Make sure no duplicated issue has already been reported in [the pyenv issues](https://github.com/pyenv/pyenv/issues). You should look for closed issues, too.
* [ ] Make sure you are not asking us to help solving your specific issue.
* GitHub issues is opened mainly for development purposes. If you want to ask someone to help solving your problem, go to some community site like [Gitter](https://gitter.im/yyuu/pyenv), [StackOverflow](https://stackoverflow.com/questions/tagged/pyenv), etc.
* [ ] Make sure your problem is not derived from packaging (e.g. [Homebrew](https://brew.sh)).
* Please refer to the package documentation for the installation issues, etc.
* [ ] Make sure your problem is not derived from plugins.
* This repository is maintaining `pyenv` and the default `python-build` plugin only. Please refrain from reporting issues of other plugins here.
### Description
- [ ] Platform information (e.g. Ubuntu Linux 16.04):
- [ ] OS architecture (e.g. amd64):
- [ ] pyenv version:
- [ ] Python version:
- [ ] C Compiler information (e.g. gcc 7.3):
- [ ] Please attach the debug trace of the failing command as a gist:
* Run `env PYENV_DEBUG=1 <faulty command> 2>&1 | tee trace.log` and attach `trace.log`. E.g. if you have a problem with installing Python, run `env PYENV_DEBUG=1 pyenv install -v <version> 2>&1 | tee trace.log` (note the `-v` option to `pyenv install`).
- [ ] If you have a problem with installing Python, please also attach `config.log` from the build directory
* The build directory is reported after the "BUILD FAILED" message and is usually under `/tmp`.
- [ ] If the build succeeds but the problem is still with the build process (e.g. the resulting Python is missing a feature), please attach
* the debug trace from reinstalling the faulty version with `env PYENV_DEBUG=1 pyenv install -f -k -v <version> 2>&1 | tee trace.log`
* `config.log` from the build directory. When using `pyenv install` with `-k` as per above, the build directory will be under `$PYENV_ROOT/sources`.

View File

@ -1,54 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
### Prerequisites
* [ ] Make sure your problem is not listed in [the common build problems](https://github.com/pyenv/pyenv/wiki/Common-build-problems).
* [ ] Make sure no duplicated issue has already been reported in [the pyenv issues](https://github.com/pyenv/pyenv/issues?q=is%3Aissue). For build errors, a reported issue typically mentions a key error message. This key error message is often not in the 10 last build log lines reported to the console but is rather earlier in the build log -- typically, it's the first error message encountered in the log.
* [ ] Make sure you are reporting a problem in Pyenv and not seeking consultation with Pyenv usage.
* GitHub issues are intended mainly for Pyenv development purposes. If you are seeking help with Pyenv usage, check [Pyenv documentation](https://github.com/pyenv/pyenv?tab=readme-ov-file#simple-python-version-management-pyenv), go to a user community site like [Gitter](https://gitter.im/yyuu/pyenv), [StackOverflow](https://stackoverflow.com/questions/tagged/pyenv), etc, or to [Discussions](https://github.com/orgs/pyenv/discussions).
* [ ] Make sure your problem is not derived from packaging (e.g. [Homebrew](https://brew.sh)).
* Please refer to the package documentation for the installation issues, etc.
* [ ] Make sure your problem is not derived from plugins.
* This repository is maintaining `pyenv` and the default `python-build` plugin only. Please refrain from reporting issues of other plugins here.
### Describe the bug
A clear and concise description of what the bug is.
Do specify what the expected behaviour is if that's not obvious from the bug's nature.
#### Reproduction steps
Listing the commands to run in a new console session and their output is usually sufficient.
Please use a Markdown code block (three backticks on a line by themselves before and after the text) to denote a console output excerpt.
Usually not needed for build errors (since the arguments can already be seen in the debug trace) unless you are using an unusual invocation (e.g. setting environment variables that affect the build).
#### Diagnostic details
- [ ] Platform information (e.g. Ubuntu Linux 24.04):
- [ ] OS architecture (e.g. amd64):
- [ ] pyenv version:
- [ ] Python version:
- [ ] C Compiler information (e.g. gcc 7.3):
- [ ] Please attach the debug trace of the failing command as a [gist](https://gist.github.com/):
* Run `env PYENV_DEBUG=1 <faulty command> 2>&1 | tee trace.log` and attach `trace.log`. E.g. if you have a problem with installing Python, run `env PYENV_DEBUG=1 pyenv install -v <version> 2>&1 | tee trace.log` (note the `-v` option to `pyenv install`).
- [ ] If you have a problem with installing Python, please also attach `config.log` from the build directory
* The build directory is reported after the "BUILD FAILED" message and is usually under `/tmp`.
- [ ] If the build succeeds but the problem is still with the build process (e.g. the resulting Python is missing a feature), please attach
* the debug trace from reinstalling the faulty version with `env PYENV_DEBUG=1 pyenv install -f -k -v <version> 2>&1 | tee trace.log`
* `config.log` from the build directory. When using `pyenv install` with `-k` as per above, the build directory will be under `$PYENV_ROOT/sources`.
- [ ] If the problem happens in another Pyenv invocation, turn on debug logging by setting `PYENV_DEBUG=1`, e.g. `env PYENV_DEBUG=1 pyenv local 3.6.4`, and attach the resulting trace as a gist
- [ ] If the problem happens outside of a Pyenv invocation, get the debug trace like this:
```
export PYENV_DEBUG=1
# for Bash
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
# for Zsh
export PS4='+(%x:%I): %N(%i): '
set -x
<reproduce the problem>
set +x
```

View File

@ -1,24 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Describe the intended use case**
* What your general environment is if it's relevant to the feature request and is not a generic console with a typical Pyenv installation (CI, server with a custom setup, cloud environment, IDE)
* What you are trying to achieve
* What specifically you are doing for that regarding Pyenv
* Where you are stuck
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
[ ] In particular, did you consider [writing a plugin](https://github.com/pyenv/pyenv/blob/master/README.md#pyenv-plugins)? Note that if your plugin has general applicability, you can publish it in the 3rd-party plugin catalog on the Pyenv Wiki as per the link above.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -1,45 +0,0 @@
name: Add versions
on:
workflow_dispatch: {}
schedule:
# Every N hours
- cron: '0 */8 * * *'
permissions:
contents: write
pull-requests: write
jobs:
add_cpython:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3
cache: 'pip'
cache-dependency-path: plugins/python-build/scripts/requirements.txt
- run: pip install -r plugins/python-build/scripts/requirements.txt
- name: check for a release
run: |
python plugins/python-build/scripts/add_cpython.py --verbose >added_versions.lst && rc=$? || rc=$?
echo "rc=$rc" >> $GITHUB_ENV
- name: set PR properties
shell: python
run: |
import os
import sys
versions=[l.rstrip() for l in open("added_versions.lst")]
with open(os.environ['GITHUB_ENV'],'a') as f:
f.write(f'branch_name=auto_add_version/{"_".join(versions)}\n')
f.write(f'pr_name=Add {", ".join(versions)}\n')
os.remove("added_versions.lst")
- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
if: env.rc == 0
with:
branch: ${{ env.branch_name }}
title: ${{ env.pr_name }}

View File

@ -10,16 +10,21 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
python-version: python-version:
- "3.9"
- "3.10" - "3.10"
- "3.11" - "3.11"
- "3.12" - "3.12"
- "3.13" - "3.13"
- "3.14" runs-on: macos-14
runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
# Normally, we would use the superbly maintained...
# - uses: actions/setup-python@v2
# with:
# python-version: ${{ matrix.python-version }}
# ... but in the repo, we want to test pyenv builds on macOS
- run: | - run: |
brew install openssl readline sqlite3 xz tcl-tk@8 libb2 zstd brew install openssl readline sqlite3 xz zlib
# https://github.com/pyenv/pyenv#installation # https://github.com/pyenv/pyenv#installation
- run: pwd - run: pwd
- env: - env:

View File

@ -5,10 +5,8 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs: outputs:
versions: ${{steps.modified-versions.outputs.versions}} versions: ${{steps.modified-versions.outputs.versions}}
versions_cpython_only: ${{steps.modified-versions.outputs.versions_cpython_only}}
versions_macos_build_exclude: ${{steps.modified-versions.outputs.versions_macos_build_exclude}}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- run: git fetch origin "$GITHUB_BASE_REF" - run: git fetch origin "$GITHUB_BASE_REF"
- shell: bash - shell: bash
run: > run: >
@ -21,53 +19,9 @@ jobs:
echo "versions<<$EOF" >> $GITHUB_ENV; echo "versions<<$EOF" >> $GITHUB_ENV;
echo "$versions" >> $GITHUB_ENV; echo "$versions" >> $GITHUB_ENV;
echo "$EOF" >> $GITHUB_ENV; echo "$EOF" >> $GITHUB_ENV;
versions_cpython_only=$(grep -Ee '^[[:digit:]]' <<<"$versions")
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64);
echo "versions_cpython_only<<$EOF" >> $GITHUB_ENV;
echo "$versions_cpython_only" >> $GITHUB_ENV;
echo "$EOF" >> $GITHUB_ENV;
- run: pip install packaging
- name: Build exclusions JSON
shell: python
run: |
import os
import json
import random
import re
import subprocess
import packaging.version
result=[]
for line in os.environ['versions'].splitlines():
if m:=re.match(r'([^-]+)-(\d+\.\d+)-(\d+\.\d+.\d+)', line):
name, version = m.group(1), packaging.version.Version(m.group(3))
# Miniconda dropped MacOS x64 support
if (name == 'miniconda3' and version >= packaging.version.Version('25.9.1')):
result.append({'os':'macos-15-intel','python-version':line})
if m:=re.match(r'([^-]+)-(\d+\.\d+)', line):
name, version = m.group(1), packaging.version.Version(m.group(2))
# Anaconda dropped MacOS x64 support
if name == 'anaconda3' and version >= packaging.version.Version('2025.12'):
result.append({'os':'macos-15-intel','python-version':line})
EOF = str(random.getrandbits(15*8))
with open(os.environ['GITHUB_ENV'],'w') as f:
f.write(f"versions_macos_build_exclude_json<<{EOF}\n")
json.dump(result, f)
f.write(f'\n{EOF}\n')
- id: modified-versions - id: modified-versions
run: | run: |
echo "versions=`echo "${{ env.versions }}" | jq -R . | jq -sc .`" >> $GITHUB_OUTPUT echo "versions=`echo "${{ env.versions }}" | jq -R . | jq -sc .`" >> $GITHUB_OUTPUT
echo "versions_cpython_only=`echo "${{ env.versions_cpython_only }}" | jq -R . | jq -sc .`" >> $GITHUB_OUTPUT
echo 'versions_macos_build_exclude=${{ env.versions_macos_build_exclude_json }}' >> $GITHUB_OUTPUT
macos_build: macos_build:
needs: discover_modified_scripts needs: discover_modified_scripts
if: needs.discover_modified_scripts.outputs.versions != '[""]' if: needs.discover_modified_scripts.outputs.versions != '[""]'
@ -75,11 +29,10 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}} python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
os: ["macos-14", "macos-15", "macos-15-intel"] os: ["macos-13", "macos-14"]
exclude: ${{fromJson(needs.discover_modified_scripts.outputs.versions_macos_build_exclude)}}
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- run: | - run: |
#envvars #envvars
export PYENV_ROOT="$GITHUB_WORKSPACE" export PYENV_ROOT="$GITHUB_WORKSPACE"
@ -95,8 +48,7 @@ jobs:
fi fi
- run: | - run: |
#build #build
pyenv --debug install ${{ matrix.python-version }} && rc=$? || rc=$? pyenv --debug install ${{ matrix.python-version }}
if [[ $rc -ne 0 ]]; then echo config.log:; cat $TMPDIR/python-build*/*/config.log; false; fi
pyenv global ${{ matrix.python-version }} pyenv global ${{ matrix.python-version }}
# Micropython doesn't support --version # Micropython doesn't support --version
- run: | - run: |
@ -130,18 +82,17 @@ jobs:
pyenv global system pyenv global system
rm -f "$(pyenv root)"/shims/* rm -f "$(pyenv root)"/shims/*
macos_build_bundled_dependencies: macos_build_bundled_dependencies:
needs: discover_modified_scripts needs: discover_modified_scripts
if: needs.discover_modified_scripts.outputs.versions_cpython_only != '[""]' if: needs.discover_modified_scripts.outputs.versions != '[""]'
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions_cpython_only)}} python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
os: ["macos-14", "macos-15", "macos-15-intel"] os: ["macos-13", "macos-14"]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- run: | - run: |
#envvars #envvars
export PYENV_ROOT="$GITHUB_WORKSPACE" export PYENV_ROOT="$GITHUB_WORKSPACE"
@ -158,57 +109,7 @@ jobs:
fi fi
- run: | - run: |
#build #build
pyenv --debug install ${{ matrix.python-version }} && rc=$? || rc=$? pyenv --debug install ${{ matrix.python-version }}
if [[ $rc -ne 0 ]]; then echo config.log:; cat $TMPDIR/python-build*/*/config.log; false; fi
pyenv global ${{ matrix.python-version }}
- run: |
#print version
python --version
python -m pip --version
- env:
EXPECTED_PYTHON: ${{ matrix.python-version }}
run: |
#check
python -c '
import os, sys, os.path
correct_dir = os.path.join(
os.environ["PYENV_ROOT"],
"versions",
os.environ["EXPECTED_PYTHON"],
"bin")
assert os.path.dirname(sys.executable) == correct_dir'
ubuntu_build:
needs: discover_modified_scripts
if: needs.discover_modified_scripts.outputs.versions != '[""]'
strategy:
fail-fast: false
matrix:
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
os: ["ubuntu-22.04", "ubuntu-24.04"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- run: |
#envvars
export PYENV_ROOT="$GITHUB_WORKSPACE"
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
- run: |
#prerequisites
sudo apt-get update -q; sudo apt-get install -yq make build-essential \
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
export PYENV_BOOTSTRAP_VERSION=pypy2.7-7
echo "PYENV_BOOTSTRAP_VERSION=$PYENV_BOOTSTRAP_VERSION" >> $GITHUB_ENV
pyenv install $PYENV_BOOTSTRAP_VERSION
fi
- run: |
#build
pyenv --debug install ${{ matrix.python-version }} && rc=$? || rc=$?
if [[ $rc -ne 0 ]]; then echo config.log:; cat $TMPDIR/python-build*/*/config.log; false; fi
pyenv global ${{ matrix.python-version }} pyenv global ${{ matrix.python-version }}
# Micropython doesn't support --version # Micropython doesn't support --version
- run: | - run: |
@ -237,21 +138,80 @@ jobs:
"bin") "bin")
assert os.path.dirname(sys.executable) == correct_dir' assert os.path.dirname(sys.executable) == correct_dir'
fi fi
# bundled executables in some Anaconda releases cause the post-run step to break # bundled executables in some Anaconda releases cause the post-run step to hang in MacOS
- run: | - run: |
pyenv global system pyenv global system
rm -f "$(pyenv root)"/shims/* rm -f "$(pyenv root)"/shims/*
ubuntu_build_tar_gz:
ubuntu_build:
needs: discover_modified_scripts needs: discover_modified_scripts
if: needs.discover_modified_scripts.outputs.versions_cpython_only != '[""]' if: needs.discover_modified_scripts.outputs.versions != '[""]'
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions_cpython_only)}} python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
os: ["ubuntu-latest"] os: ["ubuntu-20.04", "ubuntu-22.04"]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
- run: |
#envvars
export PYENV_ROOT="$GITHUB_WORKSPACE"
echo "PYENV_ROOT=$PYENV_ROOT" >> $GITHUB_ENV
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
- run: |
#prerequisites
sudo apt-get update -q; sudo apt-get install -yq make build-essential \
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
export PYENV_BOOTSTRAP_VERSION=pypy2.7-7
echo "PYENV_BOOTSTRAP_VERSION=$PYENV_BOOTSTRAP_VERSION" >> $GITHUB_ENV
pyenv install $PYENV_BOOTSTRAP_VERSION
fi
- run: |
#build
pyenv install -v ${{ matrix.python-version }}
pyenv global ${{ matrix.python-version }}
# Micropython doesn't support --version
- run: |
#print version
if [[ "${{ matrix.python-version }}" == "micropython-"* ]]; then
python -c 'import sys; print(sys.version)'
else
python --version
python -m pip --version
fi
# Micropython doesn't support sys.executable, os.path, older versions even os
- env:
EXPECTED_PYTHON: ${{ matrix.python-version }}
run: |
#check
if [[ "${{ matrix.python-version }}" == "micropython-"* ]]; then
[[ $(pyenv which python) == "${{ env.PYENV_ROOT }}/versions/${{ matrix.python-version }}/bin/python" ]] || exit 1
python -c 'import sys; assert sys.implementation.name == "micropython"'
else
python -c 'if True:
import os, sys, os.path
correct_dir = os.path.join(
os.environ["PYENV_ROOT"],
"versions",
os.environ["EXPECTED_PYTHON"],
"bin")
assert os.path.dirname(sys.executable) == correct_dir'
fi
ubuntu_build_tar_gz:
needs: discover_modified_scripts
if: needs.discover_modified_scripts.outputs.versions != '[""]'
strategy:
fail-fast: false
matrix:
python-version: ${{fromJson(needs.discover_modified_scripts.outputs.versions)}}
os: ["ubuntu-20.04", "ubuntu-22.04"]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- run: | - run: |
#envvars #envvars
export PYENV_ROOT="$GITHUB_WORKSPACE" export PYENV_ROOT="$GITHUB_WORKSPACE"
@ -271,22 +231,32 @@ jobs:
fi fi
- run: | - run: |
#build #build
pyenv --debug install ${{ matrix.python-version }} && rc=$? || rc=$? pyenv install -v ${{ matrix.python-version }}
if [[ $rc -ne 0 ]]; then echo config.log:; cat $TMPDIR/python-build*/*/config.log; false; fi
pyenv global ${{ matrix.python-version }} pyenv global ${{ matrix.python-version }}
# Micropython doesn't support --version
- run: | - run: |
#print version #print version
python --version if [[ "${{ matrix.python-version }}" == "micropython-"* ]]; then
python -m pip --version python -c 'import sys; print(sys.version)'
else
python --version
python -m pip --version
fi
# Micropython doesn't support sys.executable, os.path, older versions even os
- env: - env:
EXPECTED_PYTHON: ${{ matrix.python-version }} EXPECTED_PYTHON: ${{ matrix.python-version }}
run: | run: |
#check #check
python -c ' if [[ "${{ matrix.python-version }}" == "micropython-"* ]]; then
import os, sys, os.path [[ $(pyenv which python) == "${{ env.PYENV_ROOT }}/versions/${{ matrix.python-version }}/bin/python" ]] || exit 1
correct_dir = os.path.join( python -c 'import sys; assert sys.implementation.name == "micropython"'
os.environ["PYENV_ROOT"], else
"versions", python -c 'if True:
os.environ["EXPECTED_PYTHON"], import os, sys, os.path
"bin") correct_dir = os.path.join(
assert os.path.dirname(sys.executable) == correct_dir' os.environ["PYENV_ROOT"],
"versions",
os.environ["EXPECTED_PYTHON"],
"bin")
assert os.path.dirname(sys.executable) == correct_dir'
fi

View File

@ -10,17 +10,29 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
os: os:
- ubuntu-24.04
- ubuntu-22.04 - ubuntu-22.04
- macos-15-intel - ubuntu-20.04
- macos-15
- macos-14 - macos-14
- macos-13
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
# Normally, we would use the superbly maintained...
# - uses: actions/setup-python@v2
# with:
# python-version: ${{ matrix.python-version }}
# ... but in the repo, we want to test pyenv builds on Ubuntu
# - run: |
# sudo apt-get install -y build-essential libssl-dev zlib1g-dev libbz2-dev \
# libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev libncursesw5-dev \
# xz-utils tk-dev libffi-dev liblzma-dev python-openssl git
# https://github.com/pyenv/pyenv#installation
- run: | - run: |
if test "$RUNNER_OS" == "macOS"; then if test "$RUNNER_OS" == "macOS"; then
brew install coreutils fish brew install coreutils fish
elif [[ $(lsb_release -sr | awk -F. '{print $1}') -ge 20 ]]; then
# Ubuntu 18 has fish 2 which lacks many features that facilitate testing
sudo apt install fish -yq
fi fi
- run: pwd - run: pwd
- env: - env:
@ -28,13 +40,8 @@ jobs:
run: | run: |
echo $PYENV_ROOT echo $PYENV_ROOT
echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH echo "$PYENV_ROOT/shims:$PYENV_ROOT/bin" >> $GITHUB_PATH
- name: Run test on the host - run: |
run: |
make test make test
- name: Run test with docker
if: ${{ ! contains(matrix.os, 'macos') }}
run: |
make test-docker
- env: - env:
PYENV_NATIVE_EXT: 1 PYENV_NATIVE_EXT: 1
run: | run: |

View File

@ -10,14 +10,19 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
python-version: python-version:
- "3.9"
- "3.10" - "3.10"
- "3.11" - "3.11"
- "3.12" - "3.12"
- "3.13" - "3.13"
- "3.14" runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v4
# Normally, we would use the superbly maintained...
# - uses: actions/setup-python@v2
# with:
# python-version: ${{ matrix.python-version }}
# ... but in the repo, we want to test pyenv builds on Ubuntu
- run: | - run: |
sudo apt-get update -q; sudo apt install -yq make build-essential libssl-dev zlib1g-dev \ sudo apt-get update -q; sudo apt install -yq make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev curl \ libbz2-dev libreadline-dev libsqlite3-dev curl \

3
.gitignore vendored
View File

@ -6,8 +6,7 @@
/libexec/*.dylib /libexec/*.dylib
/src/Makefile /src/Makefile
/src/*.o /src/*.o
/bats /bats/
/bats-*/
/default-packages /default-packages
.idea .idea
*.un~ *.un~

View File

@ -1,169 +1,5 @@
# Version History # Version History
## Release v2.6.18
* Fix an infinite loop if a shim is symlinked to and called from a different location with "system" version active by @native-api in https://github.com/pyenv/pyenv/pull/3375
* CI: Update and cleanup workflow scripts by @native-api in https://github.com/pyenv/pyenv/pull/3372
* Add PowerShell support by @fblanchetNaN in https://github.com/pyenv/pyenv/pull/2749
* rehash: support older BSD `mktemp` by @native-api in https://github.com/pyenv/pyenv/pull/3376
* rehash: report final lock acquisition error while silencing provisional ones; init: don't silence automatic rehash by @native-api in https://github.com/pyenv/pyenv/pull/3377
* pyenv launcher: introduce and export _PYENV_INSTALL_PREFIX by @rockandska in https://github.com/pyenv/pyenv/pull/3334
* README: Document how to change Python version in a shell spawned from a Python-based program (e.g. Jupyter) by @native-api in https://github.com/pyenv/pyenv/pull/3380
* Recognize an argument to -j in MAKEFLAGS when building extensions in 3.10-3.11 and latest 3.5-3.9 by @native-api in https://github.com/pyenv/pyenv/pull/3379
* CI: add a script to autogenerate CPython build scripts by @native-api in https://github.com/pyenv/pyenv/pull/3358
* Add miniconda3-25.11.1-1 by @binbjz in https://github.com/pyenv/pyenv/pull/3382
* CI: exclude unsupported MacOS-x64 for recent Miniconda versions by @binbjz in https://github.com/pyenv/pyenv/pull/3385
* Auto-accept TOS for miniconda3-25+ by @native-api in https://github.com/pyenv/pyenv/pull/3386
* Add anaconda-2025.12-1 by @native-api in https://github.com/pyenv/pyenv/pull/3387
* CI: automatically check for CPython releases and generate PRs by @native-api in https://github.com/pyenv/pyenv/pull/3388
## Release v2.6.17
* Add miniforge 25.9.1-0, 25.11.0-1 by @13steinj in https://github.com/pyenv/pyenv/pull/3371
* miniconda3-latest: auto accept TOS by @native-api in https://github.com/pyenv/pyenv/pull/3373
* Add CPython 3.15.0a3 by @edgarrmondragon in https://github.com/pyenv/pyenv/pull/3374
## Release v2.6.16
* rehash: Fix hanging for 60 seconds when shims directory is not writable due to Linux Landlock by @native-api in https://github.com/pyenv/pyenv/pull/3367
* Add Miniconda3-25.9.1-3 by @binbjz in https://github.com/pyenv/pyenv/pull/3368
* sh-rehash: Fix erroneously executing rather than printing a command by @native-api in https://github.com/pyenv/pyenv/pull/3369
* Add CPython 3.13.11, 3.14.2 by @cesarcoatl in https://github.com/pyenv/pyenv/pull/3370
## Release v2.6.15
* Add CPython 3.13.10 by @jsirois in https://github.com/pyenv/pyenv/pull/3364
## Release v2.6.14
* CI: Bump actions/checkout from 5 to 6 in the github-actions group by @dependabot[bot] in https://github.com/pyenv/pyenv/pull/3360
* Fix "ld: symbol(s) not found" for C system calls in some MacOS versions if XCode is for a newer major MacOS version by @native-api in https://github.com/pyenv/pyenv/pull/3362
* Add CPython 3.14.1 by @nedbat in https://github.com/pyenv/pyenv/pull/3363
## Release v2.6.13
* CI: Replace macos-13 with macos-15-intel by @edgarrmondragon in https://github.com/pyenv/pyenv/pull/3356
* Add Miniconda3-25.9.1-1 by @binbjz in https://github.com/pyenv/pyenv/pull/3357
* Add CPython 3.15.0a2 by @nedbat in https://github.com/pyenv/pyenv/pull/3359
## Release v2.6.12
* Add graalpy-25.0.1 by @msimacek in https://github.com/pyenv/pyenv/pull/3350
* Add CPython 3.9.25 by @nedbat in https://github.com/pyenv/pyenv/pull/3355
## Release v2.6.11
* Support building against Homebrew Tcl/Tk 9 by @native-api in https://github.com/pyenv/pyenv/pull/3343
* Add CPython 3.13.9 by @nedbat in https://github.com/pyenv/pyenv/pull/3346
* Add CPython 3.15.0a1 by @edgarrmondragon in https://github.com/pyenv/pyenv/pull/3347
## Release v2.6.10
* Add CPython 3.12.12, 3.11.14, 3.10.19, 3.9.24 by @nedbat in https://github.com/pyenv/pyenv/pull/3344
## Release v2.6.9
* CI: modified-scripts-build: fix CPython-specific jobs never firing by @tuzi3040 in https://github.com/pyenv/pyenv/pull/3338
* CI: modified-scripts-build: fix output variable for CPython-specific workflows by @native-api in https://github.com/pyenv/pyenv/pull/3340
* Add CPython 3.14.0 by @SnoopJ in https://github.com/pyenv/pyenv/pull/3339
* Add CPython 3.13.8 by @jsirois in https://github.com/pyenv/pyenv/pull/3341
## Release v2.6.8
* Use Zlib from XCode SDK in a way compatible with XCode 16 and CLT by @JarheadStever in https://github.com/pyenv/pyenv/pull/3301
* Add miniforge 25.3.0-1, 25.3.0-2, 25.3.0-3, 25.3.1-0, skip miniforge 25.3.0-0 by @native-api in https://github.com/pyenv/pyenv/pull/3306
* Fix Readline and OpenSSL detection for MacPorts without the corresponding package by @native-api in https://github.com/pyenv/pyenv/pull/3317
* Bump actions/checkout from 4 to 5 in the github-actions group by @dependabot[bot] in https://github.com/pyenv/pyenv/pull/3318
* Fix rehash hook for pipx/pipx.x/pipx.xx by @rockandska in https://github.com/pyenv/pyenv/pull/3320
* Add miniconda 25.7.0-2 by @native-api in https://github.com/pyenv/pyenv/pull/3323
* Support curl from a snap by @native-api in https://github.com/pyenv/pyenv/pull/3329
* CI: Bats test suite in docker by @rockandska in https://github.com/pyenv/pyenv/pull/3324
* Add GraalPy 25.0.0 by @msimacek in https://github.com/pyenv/pyenv/pull/3331
* Upgrade pip detetcion in pip-rehash to accept multiple variations by @rockandska in https://github.com/pyenv/pyenv/pull/3330
* Add CPython 3.14.0rc3 by @nedbat in https://github.com/pyenv/pyenv/pull/3333
* Use TCLTK_* and pkg-config for 3.11+ linking with Homebrew Tcl/Tk; add PYTHON_BUILD_TCLTK_FORMULA envvar by @native-api in https://github.com/pyenv/pyenv/pull/3327
## Release v2.6.7
* Skip Zlib from XCode for XCode 16+ by @native-api in https://github.com/pyenv/pyenv/pull/3298
* Don't fail the build if `xcodebuild` fails by @native-api in https://github.com/pyenv/pyenv/pull/3302
* Add CPython 3.14.0rc2 and 3.13.7 by @nedbat in https://github.com/pyenv/pyenv/pull/3303
## Release v2.6.6
* Add anaconda3-2025.06-0, anaconda3-2025.06-1, miniconda3-25.3.1-1, miniconda3-25.5.1-0, miniconda3-25.5.1-1 by @native-api in https://github.com/pyenv/pyenv/pull/3295
* Add CPython 3.13.6 by @cesarcoatl in https://github.com/pyenv/pyenv/pull/3297
## Release v2.6.5
* Bump OpenSSL to 3.5.1 in the latest releases and branch tips in CPython 3.12 - 3.15 by @edgarrmondragon in https://github.com/pyenv/pyenv/pull/3287
* Add Jython 2.7.4 by @cesarcoatl in https://github.com/pyenv/pyenv/pull/3290
* Add CPython 3.14.0rc1 by @nedbat in https://github.com/pyenv/pyenv/pull/3293
* Add GraalPy 24.2.2 by @msimacek in https://github.com/pyenv/pyenv/pull/3291
## Release v2.6.4
* Backport bpo_36106 to 3.5.10 and 3.6.15 by @native-api in https://github.com/pyenv/pyenv/pull/3280
* (regression) Use Zlib from XCode SDK in MacOS without Homebrew or Macports by @native-api in https://github.com/pyenv/pyenv/pull/3282
* Add PyPy v7.3.20 by @jsirois in https://github.com/pyenv/pyenv/pull/3284
* Add CPython 3.14.0b4 by @edgarrmondragon in https://github.com/pyenv/pyenv/pull/3285
## Release v2.6.3
* README: Re-promote "Python versions with extended support" to a section by @native-api in https://github.com/pyenv/pyenv/pull/3276
* Support linking to MacPorts ports installed from binary archives by @0916dhkim in https://github.com/pyenv/pyenv/pull/3272
* Add CPython 3.14.0b3 by @nedbat in https://github.com/pyenv/pyenv/pull/3278
## Release v2.6.2
* Add CPython 3.13.5 by @nedbat in https://github.com/pyenv/pyenv/pull/3269
## Release v2.6.1
* Add CPython 3.9.23, 3.10.18, 3.11.13, 3.12.11, 3.13.4 by @nedbat in https://github.com/pyenv/pyenv/pull/3266
## Release v2.6.0
* python-build: Support patch paths with spaces/special characters by @native-api in https://github.com/pyenv/pyenv/pull/3251
* Add CODEOWNERS file by @native-api in https://github.com/pyenv/pyenv/pull/3247
* README: make fish PATH add conditional on the directory existing by @BooleanCat in https://github.com/pyenv/pyenv/pull/2786
* Add --bare option to `pyenv version` by @jjwatt in https://github.com/pyenv/pyenv/pull/2783
* README: Add shell setup instructions for nushell by @jordanst3wart in https://github.com/pyenv/pyenv/pull/2916
* Add MacPorts support for python-build by @studnitskiy in https://github.com/pyenv/pyenv/pull/3186
* python-build: fix `has_broken_mac_readline` when Readline is explicitly configured by @fofoni in https://github.com/pyenv/pyenv/pull/3254
* Add CPython 3.14.0b2 by @nedbat in https://github.com/pyenv/pyenv/pull/3259
## Release v2.5.7
* Point 3.14-dev to `3.14` branch by @edgarrmondragon in https://github.com/pyenv/pyenv/pull/3246
## Release v2.5.6
* Add GraalPy 24.2.1 by @msimacek in https://github.com/pyenv/pyenv/pull/3238
* Fix get-pip URLs for 3.7, 3.8 and Pyston by @dmrlawson in https://github.com/pyenv/pyenv/pull/3242
* [CI] Cache `uname` and `sw_vers` output in Python-Build for easier mocking in tests by @native-api in https://github.com/pyenv/pyenv/pull/3244
* Add CPython 3.14.0b1 and 3.15-dev by @edgarrmondragon in https://github.com/pyenv/pyenv/pull/3245
## Release v2.5.5
* Add graalpy 24.2 by @msimacek in https://github.com/pyenv/pyenv/pull/3215
* Switch 3.9+ to OpenSSL 3 by @native-api in https://github.com/pyenv/pyenv/pull/3223
* Add miniforge3-24.11.3-1, miniforge3-24.11.3-2, miniforge3-25.1.1 by @native-api in https://github.com/pyenv/pyenv/pull/3224
* Add CPython 3.9.22, 3.10.17, 3.11.12, 3.12.10, 3.13.3, 3.14.0a7 by @native-api in https://github.com/pyenv/pyenv/pull/3233
## Release v2.5.4
* Add anaconda3-2025.1.1-2 by @binbjz in https://github.com/pyenv/pyenv/pull/3198
* Add PyPy v7.3.19 by @jsirois in https://github.com/pyenv/pyenv/pull/3205
* Add CPython 3.14.0a6 by @nedbat in https://github.com/pyenv/pyenv/pull/3213
## Release v2.5.3
* Add PyPy v7.3.18 by @dand-oss in https://github.com/pyenv/pyenv/pull/3184
* Add Miniconda3 25.1.1-0 by @binbjz in https://github.com/pyenv/pyenv/pull/3190
* Add miniforge3-25.1.1-0, miniforge3-24.11.3-0 by @native-api in https://github.com/pyenv/pyenv/pull/3191
* Add CPython 3.14.0a5 by @edgarrmondragon in https://github.com/pyenv/pyenv/pull/3194
* Add Miniconda3 25.1.1-1 by @binbjz in https://github.com/pyenv/pyenv/pull/3192
* Update hashes for Python 3.14.0a5 tarballs by @jsirois in https://github.com/pyenv/pyenv/pull/3196
* rehash: Do not execute conda-specific code if conda is not installed by @ChristianFredrikJohnsen in https://github.com/pyenv/pyenv/pull/3151
## Release v2.5.2
* Fix OpenSSL version parsing in python-build script by @threadflow in https://github.com/pyenv/pyenv/pull/3181
* Add GraalPy 24.1.2 by @msimacek in https://github.com/pyenv/pyenv/pull/3176
* Add CPython 3.12.9 and 3.13.2 by @edgarrmondragon in https://github.com/pyenv/pyenv/pull/3183
## Release v2.5.1
* CI: use Ubuntu 24.04; use ubuntu-latest for the ubuntu_build check by @native-api in https://github.com/pyenv/pyenv/pull/3144
* Fix: mistake in configuration hints in `pyenv init` and manpage by @ChristianFredrikJohnsen in https://github.com/pyenv/pyenv/pull/3145
* README: Add recommended curl arguments to suggested installer invocation by @JayBazuzi in https://github.com/pyenv/pyenv/pull/3155
* Add miniforge3-24.11.2-0, miniforge3-24.11.2-1 by @native-api in https://github.com/pyenv/pyenv/pull/3163
* Fix "Unsupported options" error building bundled OpenSSL <3.2.0 by @native-api in https://github.com/pyenv/pyenv/pull/3164
* Add CPython 3.14.0a4 by @nedbat in https://github.com/pyenv/pyenv/pull/3168
## Release v2.5.0
* `pyenv init -` performance improvements; recommend using `pyenv init - <shell>` by @ChristianFredrikJohnsen in https://github.com/pyenv/pyenv/pull/3136
* Add miniconda3-24.11.1-0 by @binbjz in https://github.com/pyenv/pyenv/pull/3138
* Add miniconda3-24.3.0-0 by @native-api in https://github.com/pyenv/pyenv/pull/3139
* CI: only run macos_build_bundled_dependencies and ubuntu_build_tar_gz for CPython by @native-api in https://github.com/pyenv/pyenv/pull/3141
* Add miniforge3 and mambaforge3 24.1.2-0, 24.3.0-0, 24.5.0-0, 24.7.1-0, 24.7.1-1, 24.7.1-2, 24.9.0-0, 24.9.2-0, 24.11.0-0, 24.11.0-1 by @native-api in https://github.com/pyenv/pyenv/pull/3142
* Skip broken miniforge3/mambaforge3 22.11.0-0, 22.11.0-1, 22.11.0-2 in the generation script by @native-api in https://github.com/pyenv/pyenv/pull/3143
## Release v2.4.23 ## Release v2.4.23
* README: explain using multiple versions by @Finkregh in https://github.com/pyenv/pyenv/pull/3126 * README: explain using multiple versions by @Finkregh in https://github.com/pyenv/pyenv/pull/3126
* Support PACKAGE_CPPFLAGS and PACKAGE_LDFLAGS by @native-api in https://github.com/pyenv/pyenv/pull/3130 * Support PACKAGE_CPPFLAGS and PACKAGE_LDFLAGS by @native-api in https://github.com/pyenv/pyenv/pull/3130

View File

@ -272,15 +272,8 @@ version of Python, or install a package that provides binaries.
Displays the currently active Python version, along with information on Displays the currently active Python version, along with information on
how it was set. how it was set.
Usage: pyenv version [--bare]
--bare show just the version name. An alias to `pyenv version-name'
$ pyenv version $ pyenv version
2.7.6 (set by /home/yyuu/.pyenv/version) 2.7.6 (set by /home/yyuu/.pyenv/version)
$ pyenv version --bare
2.7.6
## `pyenv versions` ## `pyenv versions`

View File

@ -13,6 +13,12 @@ General guidance
You can still add performance optimizations etc that take advantage of newer Bash features You can still add performance optimizations etc that take advantage of newer Bash features
as long as there is a fallback execution route for Bash 3. as long as there is a fallback execution route for Bash 3.
* Be extra careful when submitting logic specific for the Apple Silicon platform
As of this writing, Github Actions do not support it and only one team member has the necessary hardware.
So we may be unable to test your changes and may have to take your word for it.
Formatting PRs Formatting PRs
============== ==============

35
Dockerfile Normal file
View File

@ -0,0 +1,35 @@
FROM ubuntu:18.04
LABEL maintainer="Chris L. Barnes <chrislloydbarnes@gmail.com>"
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update -y \
&& apt-get install -y \
make \
build-essential \
libssl-dev \
zlib1g-dev \
libbz2-dev \
libreadline-dev \
libsqlite3-dev \
wget \
curl \
llvm \
libncurses5-dev \
libncursesw5-dev \
xz-utils \
tk-dev \
libffi-dev \
liblzma-dev \
python-openssl \
git \
&& rm -rf /var/lib/apt/lists/*
ENV PYENV_ROOT "/pyenv"
ENV PATH "$PYENV_ROOT/bin:$PATH"
COPY . /pyenv
RUN eval "$(pyenv init -)"

View File

@ -8,7 +8,7 @@ Release checklist:
Type the would-be tag name in the "Choose a tag" field and press "Generate release notes" Type the would-be tag name in the "Choose a tag" field and press "Generate release notes"
* The summary may need editing. E.g. rephrase entries, delete/merge entries that are too minor or irrelevant to the users (e.g. typo fixes, CI) * The summary may need editing. E.g. rephrase entries, delete/merge entries that are too minor or irrelevant to the users (e.g. typo fixes, CI)
* Update `CHANGELOG.md` with the new version number and the edited summary (only the changes section) * Update `CHANGELOG.md` with the new version number and the edited summary (only the changes section)
* Push the version number in `libexec/pyenv---version` and `plugins/python-build/bin/python-build` * Push the version number in `libexec/pyenv---version`
* Minor version is pushed if there are significant functional changes (not e.g. bugfixes/formula adaptations/supporting niche use cases). * Minor version is pushed if there are significant functional changes (not e.g. bugfixes/formula adaptations/supporting niche use cases).
* Major version is pushed if there are breaking changes * Major version is pushed if there are breaking changes
* Commit the changes locally into `master` * Commit the changes locally into `master`

View File

@ -1,86 +1,3 @@
TEST_BATS_VERSION = v1.10.0
TEST_BASH_VERSIONS = 3.2.57 4.1.17
TEST_UNIT_DOCKER_PREFIX = test-unit-docker
TEST_UNIT_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_UNIT_DOCKER_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_UNIT_DOCKER_PREFIX)))
TEST_PLUGIN_DOCKER_PREFIX = test-plugin-docker
TEST_PLUGIN_DOCKER_TARGETS = $(foreach bash,$(TEST_BASH_VERSIONS),$(addsuffix -$(bash),$(TEST_PLUGIN_DOCKER_PREFIX)) $(addsuffix -gnu-$(bash),$(TEST_PLUGIN_DOCKER_PREFIX)))
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)))
.PHONY:
test-docker: $(TEST_UNIT_DOCKER_PREFIX) $(TEST_PLUGIN_DOCKER_PREFIX)
# Run all unit test under bats docker
.PHONY: $(TEST_UNIT_DOCKER_PREFIX)
$(TEST_UNIT_DOCKER_PREFIX): $(TEST_UNIT_DOCKER_TARGETS)
# Run each unit test under bats docker
.PHONY: $(TEST_UNIT_DOCKER_TARGETS)
$(TEST_UNIT_DOCKER_TARGETS): DOCKER_IMAGE = $(TEST_BATS_IMAGE_PREFIX)
$(TEST_UNIT_DOCKER_TARGETS): GNU = $(if $(findstring -gnu-,$@),True,False)
$(TEST_UNIT_DOCKER_TARGETS): BASH = $(filter $(TEST_BASH_VERSIONS),$(subst -, ,$@))
$(TEST_UNIT_DOCKER_TARGETS): DOCKER_TAG = bash-$(BASH)-gnu-$(GNU)
$(TEST_UNIT_DOCKER_TARGETS): INTERACTIVE = $(if $(findstring true,$(CI)),,-ti)
$(TEST_UNIT_DOCKER_TARGETS): $(TEST_UNIT_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))" \
$${BATS_TEST_FILTER:+-e BATS_TEST_FILTER="$${BATS_TEST_FILTER}"} \
$${BATS_FILE_FILTER:+-e BATS_FILE_FILTER="$${BATS_FILE_FILTER}"} \
$${CI+-e CI="$${CI}"} \
$(INTERACTIVE) \
$(DOCKER_IMAGE):$(DOCKER_TAG) \
test/run
# Run all plugin test under bats docker
.PHONY: $(TEST_PLUGIN_DOCKER_PREFIX)
$(TEST_PLUGIN_DOCKER_PREFIX): $(TEST_PLUGIN_DOCKER_TARGETS)
# Run each plugin test under bats docker
.PHONY: $(TEST_PLUGIN_DOCKER_TARGETS)
$(TEST_PLUGIN_DOCKER_TARGETS): DOCKER_IMAGE = $(TEST_BATS_IMAGE_PREFIX)
$(TEST_PLUGIN_DOCKER_TARGETS): GNU = $(if $(findstring -gnu-,$@),True,False)
$(TEST_PLUGIN_DOCKER_TARGETS): BASH = $(filter $(TEST_BASH_VERSIONS),$(subst -, ,$@))
$(TEST_PLUGIN_DOCKER_TARGETS): DOCKER_TAG = bash-$(BASH)-gnu-$(GNU)
$(TEST_PLUGIN_DOCKER_TARGETS): INTERACTIVE = $(if $(findstring true,$(CI)),,-ti)
$(TEST_PLUGIN_DOCKER_TARGETS): $(TEST_PLUGIN_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 $${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} plugins/python-build/test/$${BATS_FILE_FILTER}
# Build all images needed for bats under docker
.PHONY: $(TEST_BATS_IMAGE_PREFIX)
$(TEST_BATS_IMAGE_PREFIX): $(TEST_BATS_IMAGE_TARGETS)
# Build each image needed for bats under docker
.PHONY: $(TEST_BATS_IMAGE_TARGETS)
$(TEST_BATS_IMAGE_TARGETS): DOCKER_IMAGE = $(TEST_BATS_IMAGE_PREFIX)
$(TEST_BATS_IMAGE_TARGETS): GNU = $(if $(findstring -gnu-,$@),True,False)
$(TEST_BATS_IMAGE_TARGETS): BASH = $(filter $(TEST_BASH_VERSIONS),$(subst -, ,$@))
$(TEST_BATS_IMAGE_TARGETS): DOCKER_TAG = bash-$(BASH)-gnu-$(GNU)
$(TEST_BATS_IMAGE_TARGETS):
$(info Building docker image '$(DOCKER_IMAGE):$(DOCKER_TAG)')
docker build \
--quiet \
-f "$(PWD)/test/Dockerfile" \
--build-arg GNU="$(GNU)" \
--build-arg BASH="$(BASH)" \
--build-arg BATS_VERSION="$(TEST_BATS_VERSION)" \
-t $(DOCKER_IMAGE):$(DOCKER_TAG) \
./
.PHONY: test test-build test-unit test-plugin .PHONY: test test-build test-unit test-plugin
# Do not pass in user flags to build tests. # Do not pass in user flags to build tests.
@ -93,7 +10,7 @@ test-unit: bats
PATH="./bats/bin:$$PATH" test/run PATH="./bats/bin:$$PATH" test/run
test-plugin: bats test-plugin: bats
cd plugins/python-build && $(PWD)/bats/bin/bats $${CI:+--tap} $${BATS_TEST_FILTER:+--filter "$${BATS_TEST_FILTER}"} test/$${BATS_FILE_FILTER} cd plugins/python-build && $(PWD)/bats/bin/bats $${CI:+--tap} test
PYTHON_BUILD_ROOT := $(CURDIR)/plugins/python-build PYTHON_BUILD_ROOT := $(CURDIR)/plugins/python-build
PYTHON_BUILD_OPTS ?= --verbose PYTHON_BUILD_OPTS ?= --verbose
@ -108,12 +25,5 @@ test-build:
[ -e $(PYTHON_BUILD_TEST_PREFIX)/bin/pip ] [ -e $(PYTHON_BUILD_TEST_PREFIX)/bin/pip ]
$(PYTHON_BUILD_TEST_PREFIX)/bin/pip -V $(PYTHON_BUILD_TEST_PREFIX)/bin/pip -V
.SECONDARY: bats-$(TEST_BATS_VERSION) bats:
bats-$(TEST_BATS_VERSION): git clone --depth 1 --branch v1.2.0 https://github.com/bats-core/bats-core.git bats
rm -rf bats
ln -sf bats-$(TEST_BATS_VERSION) bats
git clone --depth 1 --branch $(TEST_BATS_VERSION) https://github.com/bats-core/bats-core.git bats-$(TEST_BATS_VERSION)
.PHONY: bats
bats: bats-$(TEST_BATS_VERSION)
ln -sf bats-$(TEST_BATS_VERSION) bats

120
README.md
View File

@ -50,7 +50,6 @@ This project was forked from [rbenv](https://github.com/rbenv/rbenv) and
* **[Usage](#usage)** * **[Usage](#usage)**
* [Install additional Python versions](#install-additional-python-versions) * [Install additional Python versions](#install-additional-python-versions)
* [Prefix auto-resolution to the latest version](#prefix-auto-resolution-to-the-latest-version) * [Prefix auto-resolution to the latest version](#prefix-auto-resolution-to-the-latest-version)
* [Python versions with extended support](#python-versions-with-extended-support)
* [Switch between Python versions](#switch-between-python-versions) * [Switch between Python versions](#switch-between-python-versions)
* [Making multiple versions available](#making-multiple-versions-available) * [Making multiple versions available](#making-multiple-versions-available)
* [Uninstall Python versions](#uninstall-python-versions) * [Uninstall Python versions](#uninstall-python-versions)
@ -67,7 +66,6 @@ This project was forked from [rbenv](https://github.com/rbenv/rbenv) and
* [Locating Pyenv-provided Python Installations](#locating-pyenv-provided-python-installations) * [Locating Pyenv-provided Python Installations](#locating-pyenv-provided-python-installations)
* [Advanced Configuration](#advanced-configuration) * [Advanced Configuration](#advanced-configuration)
* [Using Pyenv without shims](#using-pyenv-without-shims) * [Using Pyenv without shims](#using-pyenv-without-shims)
* [Running nested shells from Python-based programs](#running-nested-shells-from-python-based-programs)
* [Environment variables](#environment-variables) * [Environment variables](#environment-variables)
* **[Development](#development)** * **[Development](#development)**
* [Contributing](#contributing) * [Contributing](#contributing)
@ -89,7 +87,7 @@ The Homebrew option from the [MacOS section below](#macos) would also work if yo
##### 1. Automatic installer (Recommended) ##### 1. Automatic installer (Recommended)
```bash ```bash
curl -fsSL https://pyenv.run | bash curl https://pyenv.run | bash
``` ```
For more details visit our other project: For more details visit our other project:
@ -193,27 +191,27 @@ See [Advanced configuration](#advanced-configuration) for details and more confi
```bash ```bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init - bash)"' >> ~/.bashrc echo 'eval "$(pyenv init -)"' >> ~/.bashrc
``` ```
2. Then, if you have `~/.profile`, `~/.bash_profile` or `~/.bash_login`, add the commands there as well. 3. Then, if you have `~/.profile`, `~/.bash_profile` or `~/.bash_login`, add the commands there as well.
If you have none of these, create a `~/.profile` and add the commands there. If you have none of these, create a `~/.profile` and add the commands there.
* to add to `~/.profile`: * to add to `~/.profile`:
``` bash ``` bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile
echo 'eval "$(pyenv init - bash)"' >> ~/.profile echo 'eval "$(pyenv init -)"' >> ~/.profile
``` ```
* to add to `~/.bash_profile`: * to add to `~/.bash_profile`:
```bash ```bash
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init - bash)"' >> ~/.bash_profile echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
``` ```
**Bash warning**: There are some systems where the `BASH_ENV` variable is configured **Bash warning**: There are some systems where the `BASH_ENV` variable is configured
to point to `.bashrc`. On such systems, you should almost certainly put the to point to `.bashrc`. On such systems, you should almost certainly put the
`eval "$(pyenv init - bash)"` line into `.bash_profile`, and **not** into `.bashrc`. Otherwise, you `eval "$(pyenv init -)"` line into `.bash_profile`, and **not** into `.bashrc`. Otherwise, you
may observe strange behaviour, such as `pyenv` getting into an infinite loop. may observe strange behaviour, such as `pyenv` getting into an infinite loop.
See [#264](https://github.com/pyenv/pyenv/issues/264) for details. See [#264](https://github.com/pyenv/pyenv/issues/264) for details.
@ -222,12 +220,11 @@ See [Advanced configuration](#advanced-configuration) for details and more confi
#### Zsh #### Zsh
<details> <details>
Add Pyenv startup commands to `~/.zshrc` by running the following in your terminal:
```zsh ```zsh
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init - zsh)"' >> ~/.zshrc echo 'eval "$(pyenv init -)"' >> ~/.zshrc
``` ```
If you wish to get Pyenv in noninteractive login shells as well, also add the commands to `~/.zprofile` or `~/.zlogin`. If you wish to get Pyenv in noninteractive login shells as well, also add the commands to `~/.zprofile` or `~/.zlogin`.
@ -238,53 +235,21 @@ See [Advanced configuration](#advanced-configuration) for details and more confi
<details> <details>
1. If you have Fish 3.2.0 or newer, execute this interactively: 1. If you have Fish 3.2.0 or newer, execute this interactively:
```fish ~~~ fish
set -Ux PYENV_ROOT $HOME/.pyenv set -Ux PYENV_ROOT $HOME/.pyenv
test -d $PYENV_ROOT/bin; and fish_add_path $PYENV_ROOT/bin fish_add_path $PYENV_ROOT/bin
``` ~~~
2. Otherwise, execute the snippet below: 2. Otherwise, execute the snippet below:
```fish ~~~ fish
set -Ux PYENV_ROOT $HOME/.pyenv set -Ux PYENV_ROOT $HOME/.pyenv
test -d $PYENV_ROOT/bin; and set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths set -U fish_user_paths $PYENV_ROOT/bin $fish_user_paths
``` ~~~
3. Now, add this to `~/.config/fish/config.fish`: 3. Now, add this to `~/.config/fish/config.fish`:
```fish ~~~ fish
pyenv init - fish | source pyenv init - | source
``` ~~~
</details>
#### Nushell
<details>
Add the following lines to your `config.nu` to add Pyenv and its shims to your `PATH`.
Shell integration (completions and subcommands changing the shell's state)
isn't currently supported.
~~~ nu
$env.PYENV_ROOT = "~/.pyenv" | path expand
if (( $"($env.PYENV_ROOT)/bin" | path type ) == "dir") {
$env.PATH = $env.PATH | prepend $"($env.PYENV_ROOT)/bin" }
$env.PATH = $env.PATH | prepend $"(pyenv root)/shims"
~~~
</details>
#### Microsoft PowerShell
<details>
Add the commands to `$profile.CurrentUserAllHosts` by running the following in your terminal:
~~~ pwsh
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"' >> $profile.CurrentUserAllHosts
echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {
$Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }' >> $profile.CurrentUserAllHosts
echo 'iex ((pyenv init -) -join "`n")' >> $profile.CurrentUserAllHosts
~~~
</details> </details>
### C. Restart your shell ### C. Restart your shell
@ -384,9 +349,8 @@ You can run [`pyenv latest -k <prefix>`](COMMANDS.md#pyenv-latest) to see how `p
See the [`pyenv latest` documentation](COMMANDS.md#pyenv-latest) for details. See the [`pyenv latest` documentation](COMMANDS.md#pyenv-latest) for details.
----
#### Python versions with extended support <details> <summary> Python versions with extended support </summary>
For the following Python releases, Pyenv applies user-provided patches that add support for some newer environments. For the following Python releases, Pyenv applies user-provided patches that add support for some newer environments.
Though we don't actively maintain those patches, since existing releases never change, Though we don't actively maintain those patches, since existing releases never change,
@ -692,25 +656,23 @@ for the environment variables that control Pyenv's behavior.
extra commands into your shell. Coming from RVM, some of you might be extra commands into your shell. Coming from RVM, some of you might be
opposed to this idea. Here's what `eval "$(pyenv init -)"` actually does: opposed to this idea. Here's what `eval "$(pyenv init -)"` actually does:
1. **Finds current shell.**
`pyenv init` figures out what shell you are using, as the exact commands of `eval "$(pyenv init -)"` vary depending on shell. Specifying which shell you are using (e.g. `eval "$(pyenv init - bash)"`) is preferred, because it reduces launch time significantly.
2. **Sets up the shims path.** This is what allows Pyenv to intercept 1. **Sets up the shims path.** This is what allows Pyenv to intercept
and redirect invocations of `python`, `pip` etc. transparently. and redirect invocations of `python`, `pip` etc. transparently.
It prepends `$(pyenv root)/shims` to your `$PATH`. It prepends `$(pyenv root)/shims` to your `$PATH`.
It also deletes any other instances of `$(pyenv root)/shims` on `PATH` It also deletes any other instances of `$(pyenv root)/shims` on `PATH`
which allows to invoke `eval "$(pyenv init -)"` multiple times without which allows to invoke `eval "$(pyenv init -)"` multiple times without
getting duplicate `PATH` entries. getting duplicate `PATH` entries.
3. **Installs autocompletion.** This is entirely optional but pretty 2. **Installs autocompletion.** This is entirely optional but pretty
useful. Sourcing `<pyenv installation prefix>/completions/pyenv.bash` will set that useful. Sourcing `$(pyenv root)/completions/pyenv.bash` will set that
up. There are also completions for Zsh, Fish and PowerShell. up. There are also completions for Zsh and Fish.
4. **Rehashes shims.** From time to time you'll need to rebuild your 3. **Rehashes shims.** From time to time you'll need to rebuild your
shim files. Doing this on init makes sure everything is up to shim files. Doing this on init makes sure everything is up to
date. You can always run `pyenv rehash` manually. date. You can always run `pyenv rehash` manually.
5. **Installs `pyenv` into the current shell as a shell function.** 4. **Installs `pyenv` into the current shell as a shell function.**
This bit is also optional, but allows This bit is also optional, but allows
pyenv and plugins to change variables in your current shell. pyenv and plugins to change variables in your current shell.
This is required for some commands like `pyenv shell` to work. This is required for some commands like `pyenv shell` to work.
@ -719,7 +681,7 @@ opposed to this idea. Here's what `eval "$(pyenv init -)"` actually does:
for some reason you need `pyenv` to be a real script rather than a for some reason you need `pyenv` to be a real script rather than a
shell function, you can safely skip it. shell function, you can safely skip it.
`eval "$(pyenv init --path)"` only does items 2 and 4. `eval "$(pyenv init --path)"` only does items 1 and 3.
To see exactly what happens under the hood for yourself, run `pyenv init -` To see exactly what happens under the hood for yourself, run `pyenv init -`
or `pyenv init --path`. or `pyenv init --path`.
@ -755,32 +717,6 @@ as currently configured.
`pyenv exec` works by prepending `$(pyenv root)/versions/<selected version>/bin` `pyenv exec` works by prepending `$(pyenv root)/versions/<selected version>/bin`
to `PATH` in the `<command>`'s environment, the same as what e.g. RVM does. to `PATH` in the `<command>`'s environment, the same as what e.g. RVM does.
### Running nested shells from Python-based programs
In addition to altering `PATH`, `pyenv exec` sets `PYENV_VERSION` in the
executed program's environment to ensure that it won't spontaneouly switch to
using a different Python version.
Some Python-based programs (e.g. Jupyter) can spawn nested shell sessions.
`pyenv version` in such a shell would dutily report that the current version was
set by an environment variable.
Depending on your use case, this version lock may be undesirable.
In this case, you need to change or unset the environment variable,
either directly or via `pyenv shell`.
To automate this, you can do so in your shell's interactive startup file,
detecting the nested shell session via some characteristic environment variable
that the spawning application sets.
E.g. in Jupyter's case (as of this writing), it's `JUPYTER_SERVER_ROOT`,
and the corresponding `~/.bashrc` line may look like this:
```bash
[[ -n $JUPYTER_SERVER_ROOT ]] && unset PYENV_VERSION
```
### Environment variables ### Environment variables

View File

@ -1,17 +0,0 @@
$scriptblock = {
param($wordToComplete, $commandAst, $cursorPosition)
$words = $commandAst.ToString()
if ( $wordToComplete ) {
$matches = (($words[0..$cursorPosition] -join '') | Select-String -Pattern "\s+" -AllMatches).Matches
if ( $matches ) {
$cursorPosition = $matches[-1].Index - 1
}
}
$words = $words[0..$cursorPosition] -join '' -split "\s+"
if ( $words.Count -ge 2 ) {
pyenv completions $words[1] | where { $_ -match $wordToComplete }
} else {
pyenv commands | where { $_ -match $wordToComplete }
}
}
Register-ArgumentCompleter -Native -CommandName pyenv -ScriptBlock $scriptblock

View File

@ -76,27 +76,23 @@ export PYENV_DIR
shopt -s nullglob shopt -s nullglob
_PYENV_INSTALL_PREFIX="$(abs_dirname "$0")" bin_path="$(abs_dirname "$0")"
_PYENV_INSTALL_PREFIX="${_PYENV_INSTALL_PREFIX%/*}" for plugin_bin in "${bin_path%/*}"/plugins/*/bin; do
export _PYENV_INSTALL_PREFIX
for plugin_bin in "${_PYENV_INSTALL_PREFIX}"/plugins/*/bin; do
PATH="${plugin_bin}:${PATH}" PATH="${plugin_bin}:${PATH}"
done done
# PYENV_ROOT can be set to anything, so it may happen to be equal to the base path above, # PYENV_ROOT can be set to anything, so it may happen to be equal to the base path above,
# resulting in duplicate PATH entries # resulting in duplicate PATH entries
if [ "${_PYENV_INSTALL_PREFIX}" != "$PYENV_ROOT" ]; then if [ "${bin_path%/*}" != "$PYENV_ROOT" ]; then
for plugin_bin in "${PYENV_ROOT}"/plugins/*/bin; do for plugin_bin in "${PYENV_ROOT}"/plugins/*/bin; do
PATH="${plugin_bin}:${PATH}" PATH="${plugin_bin}:${PATH}"
done done
fi fi
export PATH="${_PYENV_INSTALL_PREFIX}/libexec:${PATH}" export PATH="${bin_path}:${PATH}"
PYENV_HOOK_PATH="${PYENV_HOOK_PATH}:${PYENV_ROOT}/pyenv.d" PYENV_HOOK_PATH="${PYENV_HOOK_PATH}:${PYENV_ROOT}/pyenv.d"
if [ "${_PYENV_INSTALL_PREFIX}" != "$PYENV_ROOT" ]; then if [ "${bin_path%/*}" != "$PYENV_ROOT" ]; then
# Add pyenv's own `pyenv.d` unless pyenv was cloned to PYENV_ROOT # Add pyenv's own `pyenv.d` unless pyenv was cloned to PYENV_ROOT
PYENV_HOOK_PATH="${PYENV_HOOK_PATH}:${_PYENV_INSTALL_PREFIX}/pyenv.d" PYENV_HOOK_PATH="${PYENV_HOOK_PATH}:${bin_path%/*}/pyenv.d"
fi fi
PYENV_HOOK_PATH="${PYENV_HOOK_PATH}:/usr/etc/pyenv.d:/usr/local/etc/pyenv.d:/etc/pyenv.d:/usr/lib/pyenv/hooks" PYENV_HOOK_PATH="${PYENV_HOOK_PATH}:/usr/etc/pyenv.d:/usr/local/etc/pyenv.d:/etc/pyenv.d:/usr/lib/pyenv/hooks"
for plugin_hook in "${PYENV_ROOT}/plugins/"*/etc/pyenv.d; do for plugin_hook in "${PYENV_ROOT}/plugins/"*/etc/pyenv.d; do

View File

@ -12,7 +12,7 @@
set -e set -e
[ -n "$PYENV_DEBUG" ] && set -x [ -n "$PYENV_DEBUG" ] && set -x
version="2.6.18" version="2.4.23"
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

@ -29,17 +29,8 @@ if [ -z "$PYENV_COMMAND" ]; then
exit 1 exit 1
fi fi
if [[ -n $_PYENV_SHIM_PATH ]]; then
PROGRAM="$(echo "$PYENV_COMMAND" | tr a-z- A-Z_ | sed 's/[^A-Z0-9_]/_/g')"
NR_PYENV_SHIM_PATHS_PROGRAM="_PYENV_SHIM_PATHS_${PROGRAM}"
export -- "$NR_PYENV_SHIM_PATHS_PROGRAM=$_PYENV_SHIM_PATH${!NR_PYENV_SHIM_PATHS_PROGRAM:+:${!NR_PYENV_SHIM_PATHS_PROGRAM}}"
unset PROGRAM NR_PYENV_SHIM_PATHS_PROGRAM
unset _PYENV_SHIM_PATH
fi
PYENV_COMMAND_PATH="$(pyenv-which "$PYENV_COMMAND")" PYENV_COMMAND_PATH="$(pyenv-which "$PYENV_COMMAND")"
PYENV_BIN_PATH="${PYENV_COMMAND_PATH%/*}" PYENV_BIN_PATH="${PYENV_COMMAND_PATH%/*}"
export PYENV_VERSION export PYENV_VERSION
OLDIFS="$IFS" OLDIFS="$IFS"

View File

@ -15,44 +15,44 @@ if [ "$1" = "--complete" ]; then
echo bash echo bash
echo fish echo fish
echo ksh echo ksh
echo pwsh
echo zsh echo zsh
exit exit
fi fi
mode="help" mode="help"
no_rehash=""
no_push_path=""
for args in "$@"
do
if [ "$args" = "-" ]; then
mode="print"
shift
fi
while [ "$#" -gt 0 ]; do if [ "$args" = "--path" ]; then
case "$1" in mode="path"
-) shift
mode="print" fi
;;
--path) if [ "$args" = "--detect-shell" ]; then
mode="path" mode="detect-shell"
;; shift
--detect-shell) fi
mode="detect-shell"
;; if [ "$args" = "--no-push-path" ]; then
--no-push-path) no_push_path=1
no_push_path=1 shift
;; fi
--no-rehash)
no_rehash=1 if [ "$args" = "--no-rehash" ]; then
;; no_rehash=1
*) shift
shell="$1" fi
;;
esac
shift
done done
# If shell is not provided, detect it. shell="$1"
if [ -z "$shell" ]; then if [ -z "$shell" ]; then
if shell=$(tr '\0' ' ' 2>/dev/null </proc/"$PPID"/cmdline);then shell="$(ps -p "$PPID" -o 'args=' 2>/dev/null || true)"
:
else
shell=$(ps p "$PPID" -o 'args=' 2>/dev/null || true)
fi
shell="${shell%% *}" shell="${shell%% *}"
shell="${shell##-}" shell="${shell##-}"
shell="${shell:-$SHELL}" shell="${shell:-$SHELL}"
@ -60,6 +60,8 @@ if [ -z "$shell" ]; then
shell="${shell%%-*}" shell="${shell%%-*}"
fi fi
root="${0%/*}/.."
function main() { function main() {
case "$mode" in case "$mode" in
"help") "help")
@ -103,10 +105,6 @@ function detect_profile() {
profile_explain="~/.bash_profile if it exists, otherwise ~/.profile" profile_explain="~/.bash_profile if it exists, otherwise ~/.profile"
rc='~/.bashrc' rc='~/.bashrc'
;; ;;
pwsh )
profile='~/.config/powershell/profile.ps1'
rc='~/.config/powershell/profile.ps1'
;;
zsh ) zsh )
profile='~/.zprofile' profile='~/.zprofile'
rc='~/.zshrc' rc='~/.zshrc'
@ -152,18 +150,9 @@ function help_() {
echo "# Load pyenv automatically by appending" echo "# Load pyenv automatically by appending"
echo "# the following to ~/.config/fish/config.fish:" echo "# the following to ~/.config/fish/config.fish:"
echo echo
echo 'pyenv init - fish | source' echo 'pyenv init - | source'
echo echo
;; ;;
pwsh )
echo '# Load pyenv automatically by appending'
echo "# the following to $profile :"
echo
echo '$Env:PYENV_ROOT="$Env:HOME/.pyenv"'
echo 'if (Test-Path -LP "$Env:PYENV_ROOT/bin" -PathType Container) {'
echo ' $Env:PATH="$Env:PYENV_ROOT/bin:$Env:PATH" }'
echo 'iex ((pyenv init -) -join "`n")'
;;
* ) * )
echo '# Load pyenv automatically by appending' echo '# Load pyenv automatically by appending'
echo -n "# the following to " echo -n "# the following to "
@ -177,7 +166,7 @@ function help_() {
echo echo
echo 'export PYENV_ROOT="$HOME/.pyenv"' echo 'export PYENV_ROOT="$HOME/.pyenv"'
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 -)"'
;; ;;
esac esac
echo echo
@ -200,11 +189,6 @@ function print_path() {
print_path_prepend_shims print_path_prepend_shims
echo 'end' echo 'end'
;; ;;
pwsh )
echo 'if ( $Env:PATH -notmatch "'"${PYENV_ROOT}/shims"'" ) {'
print_path_prepend_shims
echo '}'
;;
* ) * )
echo 'if [[ ":$PATH:" != *'\':"${PYENV_ROOT}"/shims:\''* ]]; then' echo 'if [[ ":$PATH:" != *'\':"${PYENV_ROOT}"/shims:\''* ]]; then'
print_path_prepend_shims print_path_prepend_shims
@ -218,10 +202,6 @@ function print_path() {
echo 'set -eg PATH[$pyenv_index]; end; set -e pyenv_index' echo 'set -eg PATH[$pyenv_index]; end; set -e pyenv_index'
print_path_prepend_shims print_path_prepend_shims
;; ;;
pwsh )
echo '$Env:PATH="$(($Env:PATH -split '"':'"' | where { -not ($_ -match '"'${PYENV_ROOT}/shims'"') }) -join '"':'"')"'
print_path_prepend_shims
;;
* ) * )
# Some distros (notably Debian-based) set Bash's SSH_SOURCE_BASHRC compilation option # Some distros (notably Debian-based) set Bash's SSH_SOURCE_BASHRC compilation option
# that makes it source `bashrc` under SSH even when not interactive. # that makes it source `bashrc` under SSH even when not interactive.
@ -246,9 +226,6 @@ function print_path_prepend_shims() {
fish ) fish )
echo 'set -gx PATH '\'"${PYENV_ROOT}/shims"\'' $PATH' echo 'set -gx PATH '\'"${PYENV_ROOT}/shims"\'' $PATH'
;; ;;
pwsh )
echo '$Env:PATH="'"${PYENV_ROOT}"'/shims:$Env:PATH"'
;;
* ) * )
echo 'export PATH="'"${PYENV_ROOT}"'/shims:${PATH}"' echo 'export PATH="'"${PYENV_ROOT}"'/shims:${PATH}"'
;; ;;
@ -260,9 +237,6 @@ function print_env() {
fish ) fish )
echo "set -gx PYENV_SHELL $shell" echo "set -gx PYENV_SHELL $shell"
;; ;;
pwsh )
echo '$Env:PYENV_SHELL="'"$shell"'"'
;;
* ) * )
echo "export PYENV_SHELL=$shell" echo "export PYENV_SHELL=$shell"
;; ;;
@ -270,29 +244,15 @@ function print_env() {
} }
function print_completion() { function print_completion() {
completion="${_PYENV_INSTALL_PREFIX}/completions/pyenv.${shell}" completion="${root}/completions/pyenv.${shell}"
if [ -r "$completion" ]; then if [ -r "$completion" ]; then
case "$shell" in echo "source '$completion'"
pwsh )
echo "iex (gc $completion -Raw)"
;;
* )
echo "source '$completion'"
;;
esac
fi fi
} }
function print_rehash() { function print_rehash() {
if [ -z "$no_rehash" ]; then if [ -z "$no_rehash" ]; then
case "$shell" in echo 'command pyenv rehash 2>/dev/null'
pwsh )
echo '& pyenv rehash'
;;
* )
echo 'command pyenv rehash'
;;
esac
fi fi
} }
@ -300,63 +260,52 @@ function print_shell_function() {
commands=(`pyenv-commands --sh`) commands=(`pyenv-commands --sh`)
case "$shell" in case "$shell" in
fish ) fish )
echo \ cat <<EOS
'function pyenv function pyenv
set command $argv[1] set command \$argv[1]
set -e argv[1] set -e argv[1]
switch "$command" switch "\$command"
case '"${commands[*]}"' case ${commands[*]}
source (pyenv "sh-$command" $argv|psub) source (pyenv "sh-\$command" \$argv|psub)
case "*" case '*'
command pyenv "$command" $argv command pyenv "\$command" \$argv
end end
end' end
;;
pwsh )
cat <<EOS
function pyenv {
\$command=""
if ( \$args.Count -gt 0 ) {
\$command, \$args = \$args
}
if ( ("${commands[*]}" -split ' ') -contains \$command ) {
\$shell_cmds = (& (get-command -commandtype application pyenv) sh-\$command \$args)
if ( \$shell_cmds.Count -gt 0 ) {
iex (\$shell_cmds -join "\`n")
}
} else {
& (get-command -commandtype application pyenv) \$command \$args
}
}
EOS EOS
;; ;;
ksh | ksh93 | mksh ) ksh | ksh93 | mksh )
echo \ cat <<EOS
'function pyenv { function pyenv {
typeset command=${1:-}' typeset command
EOS
;; ;;
* ) * )
echo \ cat <<EOS
'pyenv() { pyenv() {
local command=${1:-}' local command
EOS
;; ;;
esac esac
if [ "$shell" != "fish" ] && [ "$shell" != "pwsh" ]; then if [ "$shell" != "fish" ]; then
IFS="|" IFS="|"
echo \ cat <<EOS
' [ "$#" -gt 0 ] && shift command="\${1:-}"
case "$command" in if [ "\$#" -gt 0 ]; then
'"${commands[*]:-/}"') shift
eval "$(pyenv "sh-$command" "$@")" fi
case "\$command" in
${commands[*]:-/})
eval "\$(pyenv "sh-\$command" "\$@")"
;; ;;
*) *)
command pyenv "$command" "$@" command pyenv "\$command" "\$@"
;; ;;
esac esac
}' }
EOS
fi fi
} }

View File

@ -10,8 +10,6 @@ PROTOTYPE_SHIM_PATH="${SHIM_PATH}/.pyenv-shim"
# Create the shims directory if it doesn't already exist. # Create the shims directory if it doesn't already exist.
mkdir -p "$SHIM_PATH" mkdir -p "$SHIM_PATH"
declare last_acquire_error
acquire_lock() { acquire_lock() {
# Ensure only one instance of pyenv-rehash is running at a time by # Ensure only one instance of pyenv-rehash is running at a time by
# setting the shell's `noclobber` option and attempting to write to # setting the shell's `noclobber` option and attempting to write to
@ -19,11 +17,15 @@ acquire_lock() {
# to stderr and exit with a non-zero status. # to stderr and exit with a non-zero status.
local ret local ret
set -o noclobber set -o noclobber
last_acquire_error="$( { ( echo -n > "$PROTOTYPE_SHIM_PATH"; ) 2>&1 1>&3 3>&1-; } 3>&1)" || ret=1 echo > "$PROTOTYPE_SHIM_PATH" 2>| /dev/null || ret=1
set +o noclobber set +o noclobber
[ -z "${ret}" ] [ -z "${ret}" ]
} }
# If we were able to obtain a lock, register a trap to clean up the
# prototype shim when the process exits.
trap release_lock EXIT
remove_prototype_shim() { remove_prototype_shim() {
rm -f "$PROTOTYPE_SHIM_PATH" rm -f "$PROTOTYPE_SHIM_PATH"
} }
@ -33,46 +35,26 @@ release_lock() {
} }
if [ ! -w "$SHIM_PATH" ]; then if [ ! -w "$SHIM_PATH" ]; then
echo "pyenv: cannot rehash: $SHIM_PATH isn't writable" >&2 echo "pyenv: cannot rehash: $SHIM_PATH isn't writable"
exit 1 exit 1
fi fi
declare acquired tested_for_other_write_errors unset acquired
declare start=$SECONDS start=$SECONDS
PYENV_REHASH_TIMEOUT=${PYENV_REHASH_TIMEOUT:-60} while (( SECONDS <= start + ${PYENV_REHASH_TIMEOUT:-60} )); do
while (( SECONDS <= start + PYENV_REHASH_TIMEOUT )); do if acquire_lock 2>/dev/null; then
if acquire_lock; then
acquired=1 acquired=1
# If we were able to obtain a lock, register a trap to clean up the
# prototype shim when the process exits.
trap release_lock EXIT
break break
else else
#Landlock sandbox subsystem in the Linux kernel returns false information in access() as of 6.14.0,
# making -w "$SHIM_PATH" not catch the fact that the shims dir is not writable in this case.
#Bash doesn't provide access to errno to check for non-EEXIST error code in acquire_lock.
#So check for writablity by trying to write to a different file,
# in a way that taxes the usual use case as little as possible.
if [[ -z $tested_for_other_write_errors ]]; then
( t="$(TMPDIR="$SHIM_PATH" mktemp)" && rm "$t" ) && tested_for_other_write_errors=1 ||
{ echo "pyenv: cannot rehash: $SHIM_PATH isn't writable" >&2; break; }
fi
# POSIX sleep(1) doesn't provide subsecond precision, but many others do # POSIX sleep(1) doesn't provide subsecond precision, but many others do
sleep 0.1 2>/dev/null || sleep 1 sleep 0.1 2>/dev/null || sleep 1
fi fi
done done
if [ -z "${acquired}" ]; then if [ -z "${acquired}" ]; then
if [[ -n $tested_for_other_write_errors ]]; then echo "pyenv: cannot rehash: $PROTOTYPE_SHIM_PATH exists"
echo "pyenv: cannot rehash: couldn't acquire lock"\
"$PROTOTYPE_SHIM_PATH for $PYENV_REHASH_TIMEOUT seconds. Last error message:" >&2
echo "$last_acquire_error" >&2
fi
exit 1 exit 1
fi fi
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
@ -88,10 +70,6 @@ set -e
program="\${0##*/}" program="\${0##*/}"
export PYENV_ROOT="$PYENV_ROOT" export PYENV_ROOT="$PYENV_ROOT"
SHIM_PATH=\${0%/*}
if [[ \$SHIM_PATH != "$PYENV_ROOT/shims" ]]; then
export _PYENV_SHIM_PATH="\$SHIM_PATH"
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"

View File

@ -11,17 +11,11 @@ shell="$(basename "${PYENV_SHELL:-$SHELL}")"
# When pyenv shell integration is enabled, delegate to pyenv-rehash, # When pyenv shell integration is enabled, delegate to pyenv-rehash,
# then tell the shell to empty its command lookup cache. # then tell the shell to empty its command lookup cache.
case "$shell" in pyenv-rehash
pwsh)
echo "& (get-command pyenv -commandtype application) rehash"
;;
*)
echo "command pyenv rehash"
esac
case "$shell" in case "$shell" in
fish | pwsh ) fish )
# no executable cache # no rehash support
;; ;;
* ) * )
echo "hash -r 2>/dev/null || true" echo "hash -r 2>/dev/null || true"

View File

@ -48,9 +48,6 @@ if [ "$versions" = "--unset" ]; then
echo 'set -gu PYENV_VERSION_OLD "$PYENV_VERSION"' echo 'set -gu PYENV_VERSION_OLD "$PYENV_VERSION"'
echo "set -e PYENV_VERSION" echo "set -e PYENV_VERSION"
;; ;;
pwsh )
echo '$Env:PYENV_VERSION, $Env:PYENV_VERSION_OLD = $null, $Env:PYENV_VERSION'
;;
* ) * )
echo 'PYENV_VERSION_OLD="${PYENV_VERSION-}"' echo 'PYENV_VERSION_OLD="${PYENV_VERSION-}"'
echo "unset PYENV_VERSION" echo "unset PYENV_VERSION"
@ -77,16 +74,6 @@ else
echo "pyenv: PYENV_VERSION_OLD is not set" >&2 echo "pyenv: PYENV_VERSION_OLD is not set" >&2
false false
end end
EOS
;;
pwsh )
cat <<EOS
if ( Get-Item -Path Env:\PYENV_VERSION* ) {
\$Env:PYENV_VERSION, \$Env:PYENV_VERSION_OLD = \$Env:PYENV_VERSION_OLD, \$Env:PYENV_VERSION
} else {
Write-Error "pyenv: Env:PYENV_VERSION_OLD is not set"
return \$false
}
EOS EOS
;; ;;
* ) * )
@ -122,9 +109,6 @@ if pyenv-prefix "${versions[@]}" >/dev/null; then
echo 'set -gu PYENV_VERSION_OLD "$PYENV_VERSION"' echo 'set -gu PYENV_VERSION_OLD "$PYENV_VERSION"'
echo "set -gx PYENV_VERSION \"$version\"" echo "set -gx PYENV_VERSION \"$version\""
;; ;;
pwsh )
echo '$Env:PYENV_VERSION, $Env:PYENV_VERSION_OLD = "'"${version}"'", $Env:PYENV_VERSION'
;;
* ) * )
echo 'PYENV_VERSION_OLD="${PYENV_VERSION-}"' echo 'PYENV_VERSION_OLD="${PYENV_VERSION-}"'
echo "export PYENV_VERSION=\"${version}\"" echo "export PYENV_VERSION=\"${version}\""

View File

@ -1,8 +1,9 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Summary: Show the current Python version(s) and its origin # Summary: Show the current Python version(s) and its origin
# Usage: pyenv version [--bare]
# #
# --bare show just the version name. An alias to `pyenv version-name' # Shows the currently selected Python version(s) and how it was
# selected. To obtain only the version string, use `pyenv
# version-name'.
set -e set -e
[ -n "$PYENV_DEBUG" ] && set -x [ -n "$PYENV_DEBUG" ] && set -x
@ -12,25 +13,8 @@ OLDIFS="$IFS"
IFS=: PYENV_VERSION_NAMES=($(pyenv-version-name)) || exitcode=$? IFS=: PYENV_VERSION_NAMES=($(pyenv-version-name)) || exitcode=$?
IFS="$OLDIFS" IFS="$OLDIFS"
unset bare
for arg; do
case "$arg" in
--complete )
echo --bare
exit ;;
--bare ) bare=1 ;;
* )
pyenv-help --usage version >&2
exit 1
;;
esac
done
for PYENV_VERSION_NAME in "${PYENV_VERSION_NAMES[@]}"; do for PYENV_VERSION_NAME in "${PYENV_VERSION_NAMES[@]}"; do
if [[ -n $bare ]]; then echo "$PYENV_VERSION_NAME (set by $(pyenv-version-origin))"
echo "$PYENV_VERSION_NAME"
else
echo "$PYENV_VERSION_NAME (set by $(pyenv-version-origin))"
fi
done done
exit $exitcode exit $exitcode

View File

@ -42,19 +42,15 @@ done
remove_from_path() { remove_from_path() {
local -a paths_to_remove local path_to_remove="$1"
IFS=: paths_to_remove=($1) local path_before
local path_to_remove path_before
local result=":${PATH//\~/$HOME}:" local result=":${PATH//\~/$HOME}:"
for path_to_remove in "${paths_to_remove[@]}"; do while [ "$path_before" != "$result" ]; do
while true; do path_before="$result"
path_before="$result" result="${result//:$path_to_remove:/:}"
result="${result//:$path_to_remove:/:}"
if [[ ${#path_before} == "${#result}" ]]; then break; fi
done
done done
result="${result:1:${#result}-2}" result="${result%:}"
echo "$result" echo "${result#:}"
} }
if [ -z "$PYENV_COMMAND" ]; then if [ -z "$PYENV_COMMAND" ]; then
@ -70,10 +66,8 @@ declare -a nonexistent_versions
for version in "${versions[@]}" "$system"; do for version in "${versions[@]}" "$system"; do
if [ "$version" = "system" ]; then if [ "$version" = "system" ]; then
PROGRAM="$(echo "$PYENV_COMMAND" | tr a-z- A-Z_ | sed 's/[^A-Z0-9_]/_/g')" PATH="$(remove_from_path "${PYENV_ROOT}/shims")"
NR_CUSTOM_SHIM_PATHS="_PYENV_SHIM_PATHS_$PROGRAM" PYENV_COMMAND_PATH="$(command -v "$PYENV_COMMAND" || true)"
SEARCH_PATH="$(remove_from_path "${PYENV_ROOT}/shims${!NR_CUSTOM_SHIM_PATHS:+:${!NR_CUSTOM_SHIM_PATHS}}")"
PYENV_COMMAND_PATH="$(PATH="$SEARCH_PATH" command -v "$PYENV_COMMAND" || true)"
else else
# $version may be a prefix to be resolved by pyenv-latest # $version may be a prefix to be resolved by pyenv-latest
version_path="$(pyenv-prefix "${version}" 2>/dev/null)" || \ version_path="$(pyenv-prefix "${version}" 2>/dev/null)" || \

View File

@ -14,7 +14,7 @@ pyenv lets you easily switch between multiple versions of Python\. It's simple,
.RS 15 .RS 15
.nf .nf
if command -v pyenv 1>/dev/null 2>&1; then\n if command -v pyenv 1>/dev/null 2>&1; then\n
eval "$(pyenv init - bash)" \n eval "$(pyenv init -)" \n
fi fi
.fi .fi
.RE .RE

View File

@ -138,17 +138,6 @@ would break all Pyenv-managed installations that depend on it.
You can use a [community plugin `fix-version`](https://github.com/pyenv/pyenv/wiki/Plugins#community-plugins) You can use a [community plugin `fix-version`](https://github.com/pyenv/pyenv/wiki/Plugins#community-plugins)
to fix installations in such a case. to fix installations in such a case.
##### MacPorts
MacPorts Homebrew is used to find dependency packages if `port` is found on `PATH` in MacOS.
Set `PYTHON_BUILD_USE_MACPORTS` or `PYTHON_BUILD_SKIP_MACPORTS` to override this default.
###### Interaction with Homebrew
If both Homebrew and MacPorts are installed and allowed to be used, Homebrew takes preference.
There first ecosystem where any of the required dependency packages is found is used.
##### Portage ##### Portage
In FreeBSD, if `pkg` is on PATH, Ports are searched for some dependencies that Configure is known to not search for via `pkg-config`. In FreeBSD, if `pkg` is on PATH, Ports are searched for some dependencies that Configure is known to not search for via `pkg-config`.
@ -175,9 +164,6 @@ You can set certain environment variables to control the build process.
* `PYTHON_BUILD_SKIP_HOMEBREW`, if set, will not search for libraries installed by Homebrew when it would normally will. * `PYTHON_BUILD_SKIP_HOMEBREW`, if set, will not search for libraries installed by Homebrew when it would normally will.
* `PYTHON_BUILD_USE_HOMEBREW`, if set, will search for libraries installed by Homebrew when it would normally not. * `PYTHON_BUILD_USE_HOMEBREW`, if set, will search for libraries installed by Homebrew when it would normally not.
* `PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA`, override the Homebrew OpenSSL formula to use. * `PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA`, override the Homebrew OpenSSL formula to use.
* `PYTHON_BUILD_TCLTK_FORMULA`, override the Homebrew Tcl/Tk formula to use.
* `PYTHON_BUILD_SKIP_MACPORTS`, if set, will not search for libraries installed by MacPorts when it would normally will.
* `PYTHON_BUILD_USE_MACPORTS`, if set, will search for libraries installed by MacPorts when it would normally not.
* `PYTHON_BUILD_ROOT` overrides the default location from where build definitions * `PYTHON_BUILD_ROOT` overrides the default location from where build definitions
in `share/python-build/` are looked up. in `share/python-build/` are looked up.
* `PYTHON_BUILD_DEFINITIONS` can be a list of colon-separated paths that get * `PYTHON_BUILD_DEFINITIONS` can be a list of colon-separated paths that get

View File

@ -256,6 +256,7 @@ for DEFINITION in "${DEFINITIONS[@]}"; do
# Display a more helpful message if the definition wasn't found. # Display a more helpful message if the definition wasn't found.
if [ "$STATUS" == "2" ]; then if [ "$STATUS" == "2" ]; then
{ candidates="$(definitions "$DEFINITION")" { candidates="$(definitions "$DEFINITION")"
here="$(dirname "${0%/*}")/../.."
if [ -n "$candidates" ]; then if [ -n "$candidates" ]; then
echo echo
echo "The following versions contain \`$DEFINITION' in the name:" echo "The following versions contain \`$DEFINITION' in the name:"
@ -265,13 +266,12 @@ for DEFINITION in "${DEFINITIONS[@]}"; do
echo "See all available versions with \`pyenv install --list'." echo "See all available versions with \`pyenv install --list'."
echo echo
echo -n "If the version you need is missing, try upgrading pyenv" echo -n "If the version you need is missing, try upgrading pyenv"
declare brew_prefix if [ "$here" != "${here#$(brew --prefix 2>/dev/null)}" ]; then
if brew_prefix="$(brew --prefix 2>/dev/null)" && [[ $_PYENV_INSTALL_PREFIX/ == "$brew_prefix/"* ]]; then
printf ":\n\n" printf ":\n\n"
echo " brew update && brew upgrade pyenv" echo " brew update && brew upgrade pyenv"
elif [ -d "${_PYENV_INSTALL_PREFIX}/.git" ]; then elif [ -d "${here}/.git" ]; then
printf ":\n\n" printf ":\n\n"
echo " cd ${_PYENV_INSTALL_PREFIX} && git pull && cd -" echo " cd ${here} && git pull && cd -"
else else
printf ".\n" printf ".\n"
fi fi

View File

@ -14,7 +14,7 @@
# -g/--debug Build a debug version # -g/--debug Build a debug version
# #
PYTHON_BUILD_VERSION="2.6.18" PYTHON_BUILD_VERSION="20180424"
OLDIFS="$IFS" OLDIFS="$IFS"
@ -27,6 +27,7 @@ shopt -s extglob
exec 3<&2 # preserve original stderr at fd 3 exec 3<&2 # preserve original stderr at fd 3
lib() { lib() {
parse_options() { parse_options() {
OPTIONS=() OPTIONS=()
@ -80,12 +81,7 @@ abs_dirname() {
cd "$cd_path" cd "$cd_path"
fi fi
name="${path##*/}" name="${path##*/}"
if [[ $name == ".." ]]; then path="$(resolve_link "$name" || true)"
cd ..
path="$PWD"
else
path="$(resolve_link "$name" || true)"
fi
done done
echo "$PWD" echo "$PWD"
@ -110,7 +106,7 @@ os_information() {
if type -p lsb_release >/dev/null; then if type -p lsb_release >/dev/null; then
lsb_release -sir | xargs echo lsb_release -sir | xargs echo
elif type -p sw_vers >/dev/null; then elif type -p sw_vers >/dev/null; then
echo "OS X ${_PYTHON_BUILD_CACHE_SW_VERS:=$(sw_vers -productVersion)}" echo "OS X $(sw_vers -productVersion)"
elif [ -r /etc/os-release ]; then elif [ -r /etc/os-release ]; then
source /etc/os-release source /etc/os-release
echo "$NAME" $VERSION_ID echo "$NAME" $VERSION_ID
@ -121,61 +117,22 @@ os_information() {
} }
is_mac() { is_mac() {
[ "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" = "Darwin" ] || return 1 [ "$(uname -s)" = "Darwin" ] || return 1
[ $# -eq 0 ] || [ "$(osx_version)" "$@" ] [ $# -eq 0 ] || [ "$(osx_version)" "$@" ]
} }
can_use_homebrew() { can_use_homebrew() {
if locked_in; then
locked_in homebrew && rc=$? || rc=$?; return $rc
fi
[[ -n "$PYTHON_BUILD_USE_HOMEBREW" && -n "$PYTHON_BUILD_SKIP_HOMEBREW" ]] && { [[ -n "$PYTHON_BUILD_USE_HOMEBREW" && -n "$PYTHON_BUILD_SKIP_HOMEBREW" ]] && {
echo "error: mutually exclusive environment variables PYTHON_BUILD_USE_HOMEBREW and PYTHON_BUILD_SKIP_HOMEBREW are set" >&3 echo "error: mutually exclusive environment variables PYTHON_BUILD_USE_HOMEBREW and PYTHON_BUILD_SKIP_HOMEBREW are set" >&3
exit 1 exit 1
} }
[[ -n "$PYTHON_BUILD_USE_HOMEBREW" ]] && return 0 [[ -n "$PYTHON_BUILD_USE_HOMEBREW" ]] && return 0
[[ -n "$PYTHON_BUILD_SKIP_HOMEBREW" ]] && return 1 [[ -n "$PYTHON_BUILD_SKIP_HOMEBREW" ]] && return 1
is_mac && command -v brew &>/dev/null && return 0 is_mac && return 0
# In Linux, if Pyenv itself is installed with Homebrew, # In Linux, if Pyenv itself is installed with Homebrew,
# we assume the user wants to take dependencies from there as well by default # we assume the user wants to take dependencies from there as well by default
local brew_prefix command -v brew &>/dev/null && [[ $(abs_dirname "${BASH_SOURCE}") == "$(abs_dirname "$(brew --prefix 2>/dev/null ||true)")"/* ]] && return 0
command -v brew &>/dev/null && \ return 1
# tests can have non-functional `brew' stub aliased to `false'
# in Bash 3.2, var="$(cmd)" errexits on failure even if part of a conditional chain
brew_prefix="$(brew --prefix || true)" && [[ -n "$brew_prefix" ]] && \
[[ $(abs_dirname "${BASH_SOURCE}") == "$(abs_dirname "${brew_prefix}")"/* ]] && \
{ lock_in homebrew; return 0; }
# do not check the same stuff multiple times
PYTHON_BUILD_SKIP_HOMEBREW=1; return 1
}
can_use_macports() {
if locked_in; then
locked_in macports && rc=$? || rc=$?; return $rc
fi
[[ -n "$PYTHON_BUILD_USE_MACPORTS" && -n "$PYTHON_BUILD_SKIP_MACPORTS" ]] && {
echo "error: mutually exclusive environment variables PYTHON_BUILD_USE_MACPORTS and PYTHON_BUILD_SKIP_MACPORTS are set" >&3
exit 1
}
[[ -n "$PYTHON_BUILD_USE_MACPORTS" ]] && return 0
[[ -n "$PYTHON_BUILD_SKIP_MACPORTS" ]] && return 1
is_mac && command -v port &>/dev/null && return 0
# do not check the same stuff multiple times
PYTHON_BUILD_SKIP_MACPORTS=1; return 1
}
locked_in() {
if [[ -z "$1" ]]; then
[[ -n $_PYTHON_BUILD_ECOSYSTEM_LOCKED_IN ]]
else
[[ $_PYTHON_BUILD_ECOSYSTEM_LOCKED_IN == "$1" ]]
fi
}
lock_in() {
_PYTHON_BUILD_ECOSYSTEM_LOCKED_IN=${1:?}
} }
# 9.1 -> 901 # 9.1 -> 901
@ -183,7 +140,7 @@ lock_in() {
# 10.10 -> 1010 # 10.10 -> 1010
osx_version() { osx_version() {
local -a ver local -a ver
IFS=. ver=( ${_PYTHON_BUILD_CACHE_SW_VERS:=$(sw_vers -productVersion)} ) IFS=. ver=( `sw_vers -productVersion` )
IFS="$OLDIFS" IFS="$OLDIFS"
echo $(( ${ver[0]}*100 + ${ver[1]} )) echo $(( ${ver[0]}*100 + ${ver[1]} ))
} }
@ -222,7 +179,7 @@ file_is_not_empty() {
num_cpu_cores() { num_cpu_cores() {
local num local num
case "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" in case "$(uname -s)" in
Darwin | *BSD ) Darwin | *BSD )
num="$(sysctl -n hw.ncpu 2>/dev/null || true)" num="$(sysctl -n hw.ncpu 2>/dev/null || true)"
;; ;;
@ -458,14 +415,7 @@ http_head_curl() {
} }
http_get_curl() { http_get_curl() {
local out; curl -q -o "${2:--}" -sSLf ${CURL_OPTS} "$1"
# Curl is also available as a snap. Snaps cannot read or write /tmp
# (files cannot be found, any write result is silently discarded).
local curl_is_snap;
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
curl -q -o "${out:--}" -sSLf ${CURL_OPTS} "$1" || return $?
if [[ -n $out && -n $curl_is_snap ]]; then mv "$out" "$2"; fi
} }
http_head_wget() { http_head_wget() {
@ -865,42 +815,15 @@ build_package_standard_build() {
local PACKAGE_LDFLAGS="${package_var_name}_LDFLAGS" local PACKAGE_LDFLAGS="${package_var_name}_LDFLAGS"
if [ "$package_var_name" = "PYTHON" ]; then if [ "$package_var_name" = "PYTHON" ]; then
if can_use_homebrew; then use_homebrew || true
use_custom_tcltk || use_homebrew_tcltk || true use_custom_tcltk || use_homebrew_tcltk || true
use_homebrew_readline || true use_homebrew_readline || use_freebsd_pkg || true
use_homebrew_ncurses || true use_homebrew_ncurses || true
if is_mac -ge 1014; then if is_mac -ge 1014; then
# While XCode SDK is "always available", use_xcode_sdk_zlib || use_homebrew_zlib || true
# still need a fallback in case we are using an alternate compiler else
use_xcode_sdk_zlib || use_homebrew_zlib || true use_homebrew_zlib || true
else
use_homebrew_zlib || true
fi
fi fi
if can_use_macports; then
use_custom_tcltk || true
use_macports_readline || true
use_macports_ncurses || true
if is_mac -ge 1014; then
# While XCode SDK is "always available",
# still need a fallback in case we are using an alternate compiler
use_xcode_sdk_zlib || use_homebrew_zlib || true
else
use_macports_zlib || true
fi
fi
if can_use_homebrew; then
use_homebrew || true
fi
if can_use_macports; then
use_macports || true
fi
if is_mac -ge 1014 && ! can_use_homebrew && ! can_use_macports; then
use_xcode_sdk_zlib || true
fi
use_freebsd_pkg || true
use_dsymutil || true use_dsymutil || true
use_free_threading || true use_free_threading || true
fi fi
@ -1048,7 +971,7 @@ build_package_micropython() {
} }
pypy_architecture() { pypy_architecture() {
case "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" in case "$(uname -s)" in
"Darwin" ) "Darwin" )
case "$(uname -m)" in case "$(uname -m)" in
"arm64" ) echo "osarm64" ;; "arm64" ) echo "osarm64" ;;
@ -1080,7 +1003,7 @@ pypy_architecture() {
} }
graalpy_architecture() { graalpy_architecture() {
case "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" in case "$(uname -s)" in
"Darwin" ) "Darwin" )
case "$(uname -m)" in case "$(uname -m)" in
"x86_64" ) echo "macos-amd64" ;; "x86_64" ) echo "macos-amd64" ;;
@ -1161,7 +1084,7 @@ build_package_pypy_builder() {
} }
activepython_architecture() { activepython_architecture() {
case "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" in case "$(uname -s)" in
"Darwin" ) echo "macosx10.9-i386-x86_64" ;; "Darwin" ) echo "macosx10.9-i386-x86_64" ;;
"Linux" ) "Linux" )
case "$(uname -m)" in case "$(uname -m)" in
@ -1181,7 +1104,7 @@ build_package_activepython() {
} }
anaconda_architecture() { anaconda_architecture() {
case "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" in case "$(uname -s)" in
"Darwin" ) "Darwin" )
case "$(uname -m)" in case "$(uname -m)" in
"arm64" ) echo "MacOSX-arm64" ;; "arm64" ) echo "MacOSX-arm64" ;;
@ -1237,8 +1160,8 @@ setup_builtin_patches() {
cat >"${package_name}.patch" cat >"${package_name}.patch"
HAS_PATCH=true HAS_PATCH=true
elif [[ -d "${package_patch_path}" ]]; then elif [[ -d "${package_patch_path}" ]]; then
{ find "${package_patch_path}" -maxdepth 1 -type f -print0 { find "${package_patch_path}" -maxdepth 1 -type f
} 2>/dev/null | sort -z | xargs -0 cat 1>"${package_name}.patch" } 2>/dev/null | sort | xargs cat 1>"${package_name}.patch"
HAS_PATCH=true HAS_PATCH=true
fi fi
} }
@ -1458,7 +1381,7 @@ require_osx_version() {
function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; } function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
local required_version="$@" local required_version="$@"
local osx_version="${_PYTHON_BUILD_CACHE_SW_VERS:=$(sw_vers -productVersion)}" local osx_version="$(sw_vers -productVersion)"
if [[ $(version $osx_version) -ge $(version $required_version) ]]; then if [[ $(version $osx_version) -ge $(version $required_version) ]]; then
return 0 return 0
fi fi
@ -1508,36 +1431,16 @@ use_homebrew() {
if command -v brew &>/dev/null; then if command -v brew &>/dev/null; then
local brew_prefix="$(brew --prefix 2>/dev/null || true)" local brew_prefix="$(brew --prefix 2>/dev/null || true)"
# /usr/local/lib:/usr/lib is the default library search path # /usr/local/lib:/usr/lib is the default library search path
if [[ -n $brew_prefix && ( ( $brew_prefix != "/usr" && $brew_prefix != "/usr/local" ) if [[ -n $brew_prefix && $brew_prefix != "/usr" && $brew_prefix != "/usr/local" ]]; then
#when -isysroot is passed to Apple CLang, /usr/(local) are excluded from the default search path
|| ( is_mac && osx_using_default_compiler && $CFLAGS =~ (^|\ )-isysroot\ ) ) ]]; then
export CPPFLAGS="${CPPFLAGS:+$CPPFLAGS }-I${brew_prefix}/include" export CPPFLAGS="${CPPFLAGS:+$CPPFLAGS }-I${brew_prefix}/include"
append_ldflags_libs "-L${brew_prefix}/lib -Wl,-rpath,${brew_prefix}/lib" append_ldflags_libs "-L${brew_prefix}/lib -Wl,-rpath,${brew_prefix}/lib"
lock_in homebrew
fi fi
fi fi
} }
use_macports() {
can_use_macports || return 1
local port_location="$(command -v port)"
if [ -n "$port_location" ]; then
local prefix="${port_location%/bin/port}"
export CPPFLAGS="-I${prefix}/include${CPPFLAGS:+ $CPPFLAGS}"
prepend_ldflags_libs "-L${prefix}/lib -Wl,-rpath,${prefix}/lib"
export PKG_CONFIG_PATH="$prefix/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
lock_in macports
fi
}
needs_yaml() { needs_yaml() {
if ! configured_with_package_dir "python" "yaml.h"; then ! configured_with_package_dir "python" "yaml.h" &&
if can_use_homebrew; then ! use_homebrew_yaml
use_homebrew_yaml && return 1
elif can_use_macports; then
use_macports_yaml && return 1
fi
fi
} }
use_homebrew_yaml() { use_homebrew_yaml() {
@ -1547,17 +1450,6 @@ use_homebrew_yaml() {
echo "python-build: use libyaml from homebrew" echo "python-build: use libyaml from homebrew"
export CPPFLAGS="-I$libdir/include${CPPFLAGS:+ $CPPFLAGS}" export CPPFLAGS="-I$libdir/include${CPPFLAGS:+ $CPPFLAGS}"
export LDFLAGS="-L$libdir/lib${LDFLAGS:+ ${LDFLAGS% }}" export LDFLAGS="-L$libdir/lib${LDFLAGS:+ ${LDFLAGS% }}"
lock_in homebrew
else
return 1
fi
}
use_macports_yaml() {
can_use_macports || return 1
if [[ $(port -q installed libyaml | awk '{print $3}') == "(active)" ]]; then
echo "python-build: use libyaml from MacPorts"
lock_in macports
else else
return 1 return 1
fi fi
@ -1565,14 +1457,14 @@ use_macports_yaml() {
use_freebsd_pkg() { use_freebsd_pkg() {
# check if FreeBSD # check if FreeBSD
if [ "FreeBSD" = "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" ]; then if [ "FreeBSD" = "$(uname -s)" ]; then
# use openssl if installed from Ports Collection # use openssl if installed from Ports Collection
if pkg info -e openssl; then if pkg info -e openssl; then
package_option python configure --with-openssl="/usr/local" package_option python configure --with-openssl="/usr/local"
fi fi
# check if 11-R or later # check if 11-R or later
release="${_PYTHON_BUILD_CACHE_UNAME_R:=$(uname -r)}" release="$(uname -r)"
if [ "${release%%.*}" -ge 11 ]; then if [ "${release%%.*}" -ge 11 ]; then
# Use packages from Ports Collection. # Use packages from Ports Collection.
# #
@ -1596,17 +1488,9 @@ use_freebsd_pkg() {
has_broken_mac_readline() { has_broken_mac_readline() {
# Mac OS X 10.4 has broken readline. # Mac OS X 10.4 has broken readline.
# https://github.com/pyenv/pyenv/issues/23 # https://github.com/pyenv/pyenv/issues/23
if ! is_mac || configured_with_package_dir "python" "readline/rlconf.h"; then is_mac &&
# Not applicable. ! configured_with_package_dir "python" "readline/rlconf.h" &&
return 1 ! use_homebrew_readline
fi
if can_use_homebrew; then
use_homebrew_readline && return 1
fi
if can_use_macports; then
use_macports_readline && return 1
fi
return 0
} }
use_homebrew_readline() { use_homebrew_readline() {
@ -1617,19 +1501,6 @@ use_homebrew_readline() {
echo "python-build: use readline from homebrew" echo "python-build: use readline from homebrew"
export CPPFLAGS="-I$libdir/include${CPPFLAGS:+ $CPPFLAGS}" export CPPFLAGS="-I$libdir/include${CPPFLAGS:+ $CPPFLAGS}"
export LDFLAGS="-L$libdir/lib${LDFLAGS:+ $LDFLAGS}" export LDFLAGS="-L$libdir/lib${LDFLAGS:+ $LDFLAGS}"
lock_in homebrew
else
return 1
fi
fi
}
use_macports_readline() {
can_use_macports || return 1
if ! configured_with_package_dir "python" "readline/rlconf.h"; then
if [[ $(port -q installed readline | awk '{print $3}') == "(active)" ]]; then
echo "python-build: use readline from MacPorts"
lock_in macports
else else
return 1 return 1
fi fi
@ -1643,17 +1514,6 @@ use_homebrew_ncurses() {
echo "python-build: use ncurses from homebrew" echo "python-build: use ncurses from homebrew"
export CPPFLAGS="-I$libdir/include${CPPFLAGS:+ $CPPFLAGS}" export CPPFLAGS="-I$libdir/include${CPPFLAGS:+ $CPPFLAGS}"
export LDFLAGS="-L$libdir/lib${LDFLAGS:+ $LDFLAGS}" export LDFLAGS="-L$libdir/lib${LDFLAGS:+ $LDFLAGS}"
lock_in homebrew
else
return 1
fi
}
use_macports_ncurses() {
can_use_macports || return 1
if [[ $(port -q installed ncurses | awk '{print $3}') == "(active)" ]]; then
echo "python-build: use ncurses from MacPorts"
lock_in macports
else else
return 1 return 1
fi fi
@ -1688,15 +1548,8 @@ build_package_mac_readline() {
has_broken_mac_openssl() { has_broken_mac_openssl() {
is_mac || return 1 is_mac || 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 [[ $openssl_version = "OpenSSL 0.9.8"?* || $openssl_version = "LibreSSL"* ]] &&
if can_use_homebrew; then ! use_homebrew_openssl
use_homebrew_openssl && return 1
fi
if can_use_macports; then
use_macports_openssl && return 1
fi
fi
return 0
} }
use_homebrew_openssl() { use_homebrew_openssl() {
@ -1715,28 +1568,7 @@ use_homebrew_openssl() {
export LDFLAGS="-L$ssldir/lib${LDFLAGS:+ $LDFLAGS}" export LDFLAGS="-L$ssldir/lib${LDFLAGS:+ $LDFLAGS}"
fi fi
export PKG_CONFIG_PATH="$ssldir/lib/pkgconfig/:${PKG_CONFIG_PATH}" export PKG_CONFIG_PATH="$ssldir/lib/pkgconfig/:${PKG_CONFIG_PATH}"
lock_in homebrew return
return 0
fi
done
return 1
}
use_macports_openssl() {
can_use_macports || return 1
command -v port >/dev/null || return 1
local port_location="$(command -v port)"
local prefix="${port_location%/bin/port}"
for openssl in ${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl}; do
if [[ $(port -q installed ${openssl} | awk '{print $3}') == "(active)" ]]; then
echo "python-build: use ${openssl} from MacPorts"
if [[ -n "${PYTHON_BUILD_CONFIGURE_WITH_OPENSSL:-}" ]]; then
# configure script of newer CPython versions support `--with-openssl`
# https://bugs.python.org/issue21541
package_option python configure --with-openssl="${prefix}"
fi
lock_in macports
return 0
fi fi
done done
return 1 return 1
@ -1769,16 +1601,8 @@ build_package_mac_openssl() {
local nokerberos local nokerberos
[[ "$1" != openssl-1.0.* ]] || nokerberos=1 [[ "$1" != openssl-1.0.* ]] || nokerberos=1
# switches introduced in OpenSSL 1.1.1
local notests
[[ $(openssl_version $1) -ge 10101 ]] && notests=1
# switches introduced in OpenSSL 3.2
local extra_no_features
[[ $(openssl_version $1) -ge 30200 ]] && extra_no_features=1
# Compile a shared lib with zlib dynamically linked. # Compile a shared lib with zlib dynamically linked.
package_option openssl configure --openssldir="$OPENSSLDIR" zlib-dynamic no-ssl3 shared ${nokerberos:+no-ssl2 no-krb5} ${extra_no_features:+no-docs no-apps} ${notests:+no-tests} package_option openssl configure --openssldir="$OPENSSLDIR" zlib-dynamic no-ssl3 shared ${nokerberos:+no-ssl2 no-krb5} no-docs no-apps no-tests
build_package_standard "$@" build_package_standard "$@"
@ -1788,16 +1612,6 @@ build_package_mac_openssl() {
security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain >> "$pem_file" security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain >> "$pem_file"
} }
# openssl-1.0.1k -> 10001
# openssl-3.2.1 -> 30201
openssl_version() {
local -a ver
IFS=- ver=( ${1:?} )
IFS=. ver=( ${ver[1]} )
[[ ${ver[2]} =~ ^([[:digit:]]+)[[:alpha:]]$ ]] && ver[2]="${BASH_REMATCH[1]}"
echo $(( ${ver[0]}*10000 + ${ver[1]}*100 + ${ver[2]} ))
}
# Post-install check that the openssl extension was built. # Post-install check that the openssl extension was built.
build_package_verify_openssl() { build_package_verify_openssl() {
"$RUBY_BIN" -e ' "$RUBY_BIN" -e '
@ -1839,90 +1653,50 @@ use_homebrew_zlib() {
local brew_zlib="$(brew --prefix zlib 2>/dev/null || true)" local brew_zlib="$(brew --prefix zlib 2>/dev/null || true)"
if [ -d "$brew_zlib" ]; then if [ -d "$brew_zlib" ]; then
echo "python-build: use zlib from homebrew" echo "python-build: use zlib from homebrew"
export CPPFLAGS="-I${brew_zlib}/include${CPPFLAGS:+ ${CPPFLAGS}}" export CFLAGS="-I${brew_zlib} ${CFLAGS}"
export LDFLAGS="-L${brew_zlib}/lib${LDFLAGS:+ ${LDFLAGS}}"
lock_in homebrew
rc=0
fi fi
} }
use_xcode_sdk_zlib() { use_xcode_sdk_zlib() {
# If a custom compiler is used, including XCode SDK will likely break it # If a custom compiler is used, including XCode SDK will likely break it
osx_using_default_compiler || return 1 [[ "${CC:-clang}" != "clang" || "$(command -v clang 2>/dev/null || true)" != "/usr/bin/clang" ]] && return 1
local xc_sdk_path="$(xcrun --show-sdk-path 2>/dev/null || true)"
local sdkroot="$(xcrun --sdk macosx --show-sdk-path 2>/dev/null || true)" if [ -d "$xc_sdk_path" ]; then
[[ -z ${sdkroot} || ! -d ${sdkroot} ]] && return 1 echo "python-build: use zlib from xcode sdk"
# Even though SDK's compiler uses the SDK dirs implicitly,
# Since Xcode 16 / macOS SDK 15, Apple tightened how the linker uses SDK content: # CPython's setup.py has to have nonstandard paths specified explicitly
# forcing -L "$SDK/usr/lib" now leads to odd link failures. # to search for zlib.h in them
echo "python-build: use zlib from xcode sdk" export CPPFLAGS="${CPPFLAGS:+$CPPFLAGS }-I${xc_sdk_path}/usr/include"
# Since 3.9.1 (bpo-41116), CPython's setup.py logic can search default SDK's sysroot itself if is_mac -ge 1100; then
# so we don't need to do anything export LDFLAGS="${LDFLAGS:+$LDFLAGS }-L${xc_sdk_path}/usr/lib"
# Since 2.7.12 and 3.5.2 (Issue #25136), distutils knows to look for Apple XCode 7+ stub libraries (.tbd) fi
# when searching in the SDK
# Since 2.7.4 and 3.2.1 (issue #7724), setup.py and distutils can search in the MacOS SDK when
# it's explicitly specified with -isysroot
#distutils.unixcompiler and setup.py specifically search CFLAGS for "-isysroot"
export CFLAGS="${CFLAGS:+$CFLAGS }-isysroot ${sdkroot}"
#while one can get away with adding it just to CFLAGS, this may cause linker failures
#if XCode is for a different major MacOS version (e.g. reported for XCode 12.4 on MacOS 10.15)
export LDFLAGS="${LDFLAGS:+$LDFLAGS }-isysroot ${sdkroot}"
return 0
}
osx_using_default_compiler() {
[[ "${CC:-clang}" == "clang" && "$(command -v clang 2>/dev/null || true)" == "/usr/bin/clang" ]]
}
use_macports_zlib() {
can_use_macports || return 1
if [[ $(port -q installed zlib | awk '{print $3}') == "(active)" ]]; then
echo "python-build: use zlib from MacPorts"
lock_in macports
else
return 1
fi fi
} }
use_homebrew_tcltk() { use_homebrew_tcltk() {
can_use_homebrew || return 1 can_use_homebrew || return 1
local tcltk_formula
# Since https://github.com/Homebrew/homebrew-core/commit/f10e88617b41555193c22fdcba6109fe82155ee2 (10.11.2024), # Since https://github.com/Homebrew/homebrew-core/commit/f10e88617b41555193c22fdcba6109fe82155ee2 (10.11.2024),
# tcl-tk is 9.0. It's supported in CPython since 3.14.0a1 (gh-124111) but is not officially supported as of 3.14.0 # tcl-tk is 9.0 which is not compatible with CPython as of this writing
# so we prefer 8 # but we'll keep it as backup for cases like non-updated Homebrew
for tcltk_formula in ${PYTHON_BUILD_TCLTK_FORMULA:-tcl-tk@8 tcl-tk}; do local tcltk
local tcltk_prefix="$(brew --prefix "${tcltk_formula}" 2>/dev/null || true)" for tcltk in "tcl-tk@8" "tcl-tk"; do
if [ -d "$tcltk_prefix" ]; then local tcltk_libdir="$(brew --prefix "${tcltk}" 2>/dev/null || true)"
echo "python-build: use ${tcltk_formula} from homebrew" if [ -d "$tcltk_libdir" ]; then
# In Homebrew Tcl/Tk 8.6.13, headers have been moved to the 'tcl-tk' subdir. echo "python-build: use tcl-tk from homebrew"
local tcltk_includes="$(sh -c 'cd '"$tcltk_prefix"'/lib; . ./tclConfig.sh; . ./tkConfig.sh; echo "$TCL_INCLUDE_SPEC $TK_INCLUDE_SPEC"')" if [[ -z "$PYTHON_BUILD_TCLTK_USE_PKGCONFIG" ]]; then
# Homebrew Tcl/Tk 9 is built with external libtommath. CPython's build as of 3.14.0 does not detect that and fails to link to tommath symbols local tcltk_version="$(sh -c '. '"$tcltk_libdir"'/lib/tclConfig.sh; echo $TCL_VERSION')"
local tcltk_cflags package_option python configure --with-tcltk-libs="-L$tcltk_libdir/lib -ltcl$tcltk_version -ltk$tcltk_version"
if sh -c '. '"$tcltk_prefix"'/lib/tclConfig.sh; echo "$TCL_DEFS"' | grep -qwFe '-DTCL_WITH_EXTERNAL_TOMMATH=1'; then # In Homebrew Tcl/Tk 8.6.13, headers have been moved to the 'tcl-tk' subdir.
tcltk_cflags="-DTCL_WITH_EXTERNAL_TOMMATH=1" # We're not using tclConfig.sh here 'cuz it produces the version-specific path to <brew prefix>/Cellar
# and we'd rather have rpath set to <brew prefix>/opt/<...> to allow micro release upgrades without rebuilding
# XXX: do use tclConfig.sh and translate the paths if more path shenanigans appear in later releases
if [ -d "$tcltk_libdir/include/tcl-tk" ]; then
package_option python configure --with-tcltk-includes="-I$tcltk_libdir/include/tcl-tk"
else
package_option python configure --with-tcltk-includes="-I$tcltk_libdir/include"
fi
fi fi
# For some reason, keg-only tcl-tk@8 successfully links with Tkinter without specifying rpath, with `/opt' rpath export PKG_CONFIG_PATH="${tcltk_libdir}/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
# so no need to translate /Cellar path to /opt path
local tcltk_libs="$(sh -c 'cd '"$tcltk_prefix"'/lib; . ./tclConfig.sh; . ./tkConfig.sh; echo "$TCL_LIB_SPEC $TK_LIB_SPEC"')"
# Since 2.7.6, 3.3.3, 3.4.0 (Issue #1584): --with-tcltk-includes + --with-tcltk-libs Configure options
# Since 3.11.0 (bpo-45847): `pkg-config` call, TCLTK_CFLAGS + TCLTK_LIBS override
if [[ -n "$PYTHON_BUILD_TCLTK_USE_PKGCONFIG" ]]; then
# pkg-config is not present out of the box in MacOS.
# There's no way to provide a fallback only if it's is not present
# and Configure's logic of detecting if it's present is complicated.
# So we just override it always
export TCLTK_CFLAGS="$tcltk_includes${tcltk_cflags:+ $tcltk_cflags}"
export TCLTK_LIBS="$tcltk_libs"
else
package_option python configure --with-tcltk-includes="$tcltk_includes"
package_option python configure --with-tcltk-libs="$tcltk_libs"
[[ -n $tcltk_cflags ]] && export CFLAGS="${tcltk_cflags}${CFLAGS:+ $CFLAGS}"
fi
#set in either case as a failsafe
export PKG_CONFIG_PATH="${tcltk_prefix}/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
lock_in homebrew
return 0 return 0
fi fi
done done
@ -2252,12 +2026,7 @@ build_package_verify_py313() {
# Post-install check for Python 3.14.x # Post-install check for Python 3.14.x
build_package_verify_py314() { build_package_verify_py314() {
build_package_verify_py313 "$1" "${2:-3.14}" build_package_verify_py313 "$1" "${2:-3.13}"
}
# Post-install check for Python 3.15.x
build_package_verify_py315() {
build_package_verify_py314 "$1" "${2:-3.15}"
} }
# Post-install check for Python 3.x rolling release scripts # Post-install check for Python 3.x rolling release scripts
@ -2468,13 +2237,11 @@ if [ -n "$noexec" ]; then
fi fi
if [ -z "$MAKE" ]; then if [ -z "$MAKE" ]; then
if [ "FreeBSD" = "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" ]; then if [ "FreeBSD" = "$(uname -s)" ]; then
if [ "$(echo $1 | sed 's/-.*$//')" = "jruby" ]; then if [ "$(echo $1 | sed 's/-.*$//')" = "jruby" ]; then
export MAKE="gmake" export MAKE="gmake"
else else
# var assignment inside $() does not propagate due to being in subshell if [ "$(uname -r | sed 's/[^[:digit:]].*//')" -lt 10 ]; then
: "${_PYTHON_BUILD_CACHE_UNAME_R:=$(uname -r)}"
if [ "$(echo "$_PYTHON_BUILD_CACHE_UNAME_R" | sed 's/[^[:digit:]].*//')" -lt 10 ]; then
export MAKE="gmake" export MAKE="gmake"
else else
export MAKE="make" export MAKE="make"
@ -2653,12 +2420,6 @@ if [ -z "${GET_PIP_URL}" ]; then
3.6 | 3.6.* | pypy3.6 | pypy3.6-* ) 3.6 | 3.6.* | pypy3.6 | pypy3.6-* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/3.6/get-pip.py" GET_PIP_URL="https://bootstrap.pypa.io/pip/3.6/get-pip.py"
;; ;;
3.7 | 3.7.* | pypy3.7 | pypy3.7-* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/3.7/get-pip.py"
;;
3.8 | 3.8.* | pypy3.8 | pypy3.8-* | pyston* )
GET_PIP_URL="https://bootstrap.pypa.io/pip/3.8/get-pip.py"
;;
* ) * )
GET_PIP_URL="https://bootstrap.pypa.io/get-pip.py" GET_PIP_URL="https://bootstrap.pypa.io/get-pip.py"
;; ;;
@ -2669,7 +2430,7 @@ fi
# Set MACOSX_DEPLOYMENT_TARGET from the product version of OS X (#219, #220) # Set MACOSX_DEPLOYMENT_TARGET from the product version of OS X (#219, #220)
if is_mac; then if is_mac; then
if [ -z "${MACOSX_DEPLOYMENT_TARGET}" ]; then if [ -z "${MACOSX_DEPLOYMENT_TARGET}" ]; then
MACOS_VERSION="${_PYTHON_BUILD_CACHE_SW_VERS:=$(sw_vers -productVersion)}" MACOS_VERSION="$(sw_vers -productVersion 2>/dev/null || true)"
MACOS_VERSION_ARRAY=(${MACOS_VERSION//\./ }) MACOS_VERSION_ARRAY=(${MACOS_VERSION//\./ })
if [ "${#MACOS_VERSION_ARRAY[@]}" -ge 2 ]; then if [ "${#MACOS_VERSION_ARRAY[@]}" -ge 2 ]; then
export MACOSX_DEPLOYMENT_TARGET="${MACOS_VERSION_ARRAY[0]}.${MACOS_VERSION_ARRAY[1]}" export MACOSX_DEPLOYMENT_TARGET="${MACOS_VERSION_ARRAY[0]}.${MACOS_VERSION_ARRAY[1]}"

View File

@ -1 +0,0 @@
/venv

View File

@ -1,589 +0,0 @@
#!/usr/bin/env python3
"""Script to add CPython releases.
Checks the CPython 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.
"""
import argparse
import dataclasses
import hashlib
import io
import itertools
import logging
import operator
import pathlib
import pprint
import re
import sys
import typing
import urllib.parse
import jc
import more_itertools
import packaging.version
import requests
import requests_html
import sortedcontainers
import tqdm
logger = logging.getLogger(__name__)
CUTOFF_VERSION=packaging.version.Version('3.9')
EXCLUDED_VERSIONS= {
packaging.version.Version("3.9.3") #recalled upstream
}
here = pathlib.Path(__file__).resolve()
OUT_DIR: pathlib.Path = here.parent.parent / "share" / "python-build"
T_THUNK=\
'''export PYTHON_BUILD_FREE_THREADING=1
source "${BASH_SOURCE[0]%t}"'''
def adapt_script(version: packaging.version.Version,
previous_version: packaging.version.Version) -> typing.Union[pathlib.Path, None]:
previous_version_path = OUT_DIR.joinpath(str(previous_version))
with previous_version_path.open("r", encoding='utf-8') as f:
script = f.readlines()
result = io.StringIO()
for line in script:
if m:=re.match(r'\s*install_package\s+"(?P<package>Python-\S+)"\s+'
r'"(?P<url>\S+)"\s+.*\s+verify_py(?P<verify_py_suffix>\d+)\s+.*$',
line):
existing_url_path = urllib.parse.urlparse(m.group('url')).path
try:
matched_download = more_itertools.one(
item for item in VersionDirectory.available[version].downloads
if existing_url_path.endswith(item.extension))
except ValueError:
logger.error(f'Cannot match existing URL path\'s {existing_url_path} extension '
f'to available downloads {VersionDirectory.available[version].downloads}')
return
new_package_name, new_package_url = matched_download.package_name, matched_download.url
new_package_hash = Url.sha256_url(new_package_url, VersionDirectory.session)
verify_py_suffix = str(version.major)+str(version.minor)
line = Re.sub_groups(m,
package=new_package_name,
url=new_package_url+'#'+new_package_hash,
verify_py_suffix=verify_py_suffix)
elif m:=re.match(r'\s*install_package\s+"(?P<package>openssl-\S+)"\s+'
r'"(?P<url>\S+)"\s.*$',
line):
item = VersionDirectory.openssl.get_store_latest_release()
line = Re.sub_groups(m,
package=item.package_name,
url=item.url + '#' + item.hash)
elif m:=re.match(r'\s*install_package\s+"(?P<package>readline-\S+)"\s+'
r'"(?P<url>\S+)"\s.*$',
line):
item = VersionDirectory.readline.get_store_latest_release()
line = Re.sub_groups(m,
package=item.package_name,
url=item.url + '#' + item.hash)
result.write(line)
result_path = OUT_DIR.joinpath(str(version))
logger.info(f"Writing {result_path}")
result_path.write_text(result.getvalue(), encoding='utf-8')
result.close()
return result_path
def add_version(version: packaging.version.Version):
previous_version = VersionDirectory.existing.pick_previous_version(version).version
is_prerelease_upgrade = previous_version.major==version.major\
and previous_version.minor==version.minor\
and previous_version.micro==version.micro
logger.info(f"Adding {version} based on {previous_version}"
+ (" (prerelease upgrade)" if is_prerelease_upgrade else ""))
VersionDirectory.available.get_store_available_source_downloads(version)
new_path = adapt_script(version,
previous_version)
if not new_path:
return False
VersionDirectory.existing.append(_CPythonExistingScriptInfo(version,str(new_path)))
cleanup_prerelease_upgrade(is_prerelease_upgrade, previous_version)
handle_t_thunks(version, previous_version, is_prerelease_upgrade)
print(version)
return True
def cleanup_prerelease_upgrade(
is_prerelease_upgrade: bool,
previous_version: packaging.version.Version)\
-> None:
if is_prerelease_upgrade:
previous_version_path = OUT_DIR / str(previous_version)
logger.info(f'Deleting {previous_version_path}')
previous_version_path.unlink()
del VersionDirectory.existing[previous_version]
def handle_t_thunks(version, previous_version, is_prerelease_upgrade):
if (version.major, version.minor) >= (3, 13):
# an old thunk may have older version-specific code
# so it's safer to write a known version-independent template
thunk_path = OUT_DIR.joinpath(str(version) + "t")
logger.info(f"Writing {thunk_path}")
thunk_path.write_text(T_THUNK, encoding='utf-8')
if is_prerelease_upgrade:
previous_thunk_path = OUT_DIR.joinpath(str(previous_version) + "t")
logger.info(f"Deleting {previous_thunk_path}")
previous_thunk_path.unlink()
Arguments: argparse.Namespace
def main():
global Arguments
Arguments = parse_args()
logging.basicConfig(level=logging.DEBUG if Arguments.verbose else logging.INFO)
cached_session=requests_html.HTMLSession()
global VersionDirectory
VersionDirectory = _VersionDirectory(cached_session)
VersionDirectory.existing.populate()
VersionDirectory.available.populate()
for initial_release in (v for v in frozenset(VersionDirectory.available.keys())
if v.micro == 0 and v not in VersionDirectory.existing):
# may actually be a prerelease
VersionDirectory.available.get_store_available_source_downloads(initial_release, True)
del initial_release
versions_to_add = sorted(VersionDirectory.available.keys() - VersionDirectory.existing.keys())
logger.info("Versions to add:\n"+pprint.pformat(versions_to_add))
result = False
for version_to_add in versions_to_add:
result = add_version(version_to_add) or result
return int(not result)
def parse_args():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"-d", "--dry-run", action="store_true",
help="Do not write scripts, just report them to stdout",
)
parser.add_argument(
"-v", "--verbose", action="store_true", default=0,
help="Increase verbosity of logging",
)
parsed = parser.parse_args()
return parsed
T = typing.TypeVar('T', bound=object)
K = typing.TypeVar('K', bound=typing.Hashable)
class KeyedList(typing.List[T], typing.Mapping[K, T]):
key_field: str
item_init: typing.Callable[..., T] = None
def __init__(self, seq: typing.Union[typing.Iterable[T], None] = None):
super().__init__()
self._map = {}
if seq is not None:
self.__iadd__(seq)
# read
def __getitem__(self, key: K) -> T:
return self._map[key]
def __contains__(self, key: K):
return key in self._map
def keys(self) -> typing.AbstractSet[K]:
return self._map.keys()
# write
def append(self, item: T) -> None:
key = self._getkey(item)
if key in self:
raise ValueError(f"Key '{key:r}' already present")
super().append(item)
self._map[key] = item
def __iadd__(self, other: typing.Iterable[T]):
for item in other:
self.append(item)
return self
def __delitem__(self, key: K):
super().remove(self[key])
del self._map[key]
def clear(self):
super().__delitem__(slice(None,None))
self._map.clear()
# read-write
def get_or_create(self, key: K, **kwargs):
try:
return self[key]
except KeyError as e:
if self.item_init is None:
raise AttributeError("'item_init' must be set to use automatic item creation") from e
kwargs[self.key_field] = key
item = self.item_init(**kwargs)
self.append(item)
return item
# info
def __repr__(self):
return self.__class__.__name__ + "([" + ", ".join(repr(i) for i in self) + "])"
# private
def _getkey(self, item: T) -> K:
return getattr(item, self.key_field)
del T, K
@dataclasses.dataclass(frozen=True)
class _CPythonAvailableVersionDownloadInfo:
extension: str
package_name: str
url: str
class _CPythonAvailableVersionDownloadsDirectory(KeyedList[_CPythonAvailableVersionDownloadInfo, str]):
key_field = "extension"
@dataclasses.dataclass(frozen=True)
class _CPythonAvailableVersionInfo:
version: packaging.version.Version
download_page_url: str
downloads: _CPythonAvailableVersionDownloadsDirectory = dataclasses.field(
default_factory=lambda:_CPythonAvailableVersionDownloadsDirectory()
)
class CPythonAvailableVersionsDirectory(KeyedList[_CPythonAvailableVersionInfo, packaging.version.Version]):
key_field = "version"
_session: requests.Session
item_init = _CPythonAvailableVersionInfo
def __init__(self, session: requests.Session, seq=None):
super().__init__(seq)
self._session = session
def populate(self):
"""
Fetch remote versions
"""
logger.info("Fetching available CPython versions")
for name, url in DownloadPage.enum_download_entries(
"https://www.python.org/ftp/python/",
r'^(\d+.*)/$', self._session,
make_name= lambda m: m.group(1)
):
v = packaging.version.Version(name)
if v < CUTOFF_VERSION or v in EXCLUDED_VERSIONS:
continue
logger.debug(f'Available version: {name} ({v}), {url}')
self.append(_CPythonAvailableVersionInfo(
v,
url
))
def get_store_available_source_downloads(self, version, refine_mode=False):
entry = self[version]
if entry.downloads:
#already retrieved
return
additional_versions_found =\
CPythonAvailableVersionsDirectory(self._session) if refine_mode else None
exact_download_found = False
for name, url in DownloadPage.enum_download_entries(
entry.download_page_url,
r'Python-.*\.(tar\.xz|tgz)$',
self._session):
m = re.match(r'(?P<package>Python-(?P<version>.*))\.(?P<extension>tar\.xz|tgz)$', name)
download_version = packaging.version.Version(m.group("version"))
if download_version != version:
if not refine_mode:
raise ValueError(f"Unexpectedly found a download {name} for {download_version} "
f"at page {entry.download_page_url} for {version}")
entry_to_fill = additional_versions_found.get_or_create(
download_version,
download_page_url=entry.download_page_url
)
else:
exact_download_found = True
entry_to_fill = entry
entry_to_fill.downloads.append(_CPythonAvailableVersionDownloadInfo(
m.group("extension"), m.group('package'), url
))
if not exact_download_found:
actual_version = max(additional_versions_found.keys())
logger.debug(f"Refining available version {version} to {actual_version}")
del self[version]
self.append(
additional_versions_found[
actual_version
])
class _CPythonExistingScriptInfo(typing.NamedTuple):
version: packaging.version.Version
filename: str
class CPythonExistingScriptsDirectory(KeyedList[_CPythonExistingScriptInfo, packaging.version.Version]):
key_field = "version"
_filename_pattern = r'^\d+\.\d+(?:(t?)(-\w+)|(.\d+((?:a|b|rc)\d)?(t?)))$'
def populate(self):
"""
Enumerate existing installation scripts in share/python-build/ by pattern
"""
logger.info(f"Enumerating existing versions in {OUT_DIR}")
for entry_name in (p.name for p in OUT_DIR.iterdir() if p.is_file()):
if (not (m := re.match(self._filename_pattern, entry_name))
or m.group(1) == 't' or m.group(5) == 't'):
continue
try:
v = packaging.version.Version(entry_name)
if v < CUTOFF_VERSION:
continue
# branch tip scrpts are different from release scripts and thus unusable as a pattern
if v.dev is not None:
continue
logger.debug(f"Existing version {v}")
self.append(_CPythonExistingScriptInfo(v, entry_name))
except ValueError as e:
logger.error(f"Unable to parse existing version {entry_name}: {e}")
def pick_previous_version(self,
version: packaging.version.Version) \
-> _CPythonExistingScriptInfo:
return max(v for v in self if v.version < version)
class _OpenSSLVersionInfo(typing.NamedTuple):
version: packaging.version.Version
package_name: str
url: str
hash: str
class OpenSSLVersionsDirectory(KeyedList[_OpenSSLVersionInfo, packaging.version.Version]):
key_field = "version"
def get_store_latest_release(self) \
-> _OpenSSLVersionInfo:
if self:
#already retrieved
return self[max(self.keys())]
j = requests.get("https://api.github.com/repos/openssl/openssl/releases/latest").json()
# noinspection PyTypeChecker
# urlparse can parse str as well as bytes
shasum_url = more_itertools.one(
asset['browser_download_url']
for asset in j['assets']
if urllib.parse.urlparse(asset['browser_download_url']).path.split('/')[-1].endswith('.sha256')
)
shasum_text = requests.get(shasum_url).text
shasum_data = jc.parse("hashsum", shasum_text, quiet=True)[0]
package_hash, package_filename = shasum_data["hash"], shasum_data["filename"]
del shasum_data, shasum_text, shasum_url
# OpenSSL Github repo has tag names "openssl-<version>" as of this writing like we need
# but let's not rely on that
# splitext doesn't work with a chained extension, it only splits off the last one
package_name, package_version_str = re.match(r"([^-]+-(.*?))\.\D", package_filename).groups()
package_version = packaging.version.Version(package_version_str)
package_url = more_itertools.one(
asset['browser_download_url']
for asset in j['assets']
if urllib.parse.urlparse(asset['browser_download_url']).path.split('/')[-1] == package_filename
)
result = _OpenSSLVersionInfo(package_version, package_name, package_url, package_hash)
self.append(result)
return result
class _ReadlineVersionInfo(typing.NamedTuple):
version : packaging.version.Version
package_name : str
url : str
hash : str
class ReadlineVersionsDirectory(KeyedList[_ReadlineVersionInfo, packaging.version.Version]):
key_field = "version"
def get_store_latest_release(self):
if not self:
self._store_latest_release()
return self._latest_release()
def _store_latest_release(self):
candidates = ReadlineVersionsDirectory()
pattern = r'(?P<package_name>readline-(?P<version>\d+(?:\.\d+)+)).tar\.gz$'
for name, url in DownloadPage.enum_download_entries(
'https://ftpmirror.gnu.org/readline/', pattern, VersionDirectory.session):
m = re.match(pattern, name)
version = packaging.version.Version(m.group('version'))
candidates.append(_ReadlineVersionInfo(
version,
m.group('package_name'),
url,
""
))
max_item = candidates._latest_release()
hash_ = Url.sha256_url(max_item.url, VersionDirectory.session)
result = _ReadlineVersionInfo(
max_item.version,
max_item.package_name,
max_item.url,
hash_)
self.append(result)
return result
def _latest_release(self):
return self[max(self.keys())]
class _VersionDirectory:
def __init__(self, session):
self.existing = CPythonExistingScriptsDirectory()
self.available = CPythonAvailableVersionsDirectory(session)
self.openssl = OpenSSLVersionsDirectory()
self.readline = ReadlineVersionsDirectory()
self.session = session
VersionDirectory : _VersionDirectory
class DownloadPage:
class _DownloadPageEntry(typing.NamedTuple):
name: str
url: str
@classmethod
def enum_download_entries(cls, url, pattern, session=None,
make_name = lambda m: m.string ) \
-> typing.Generator[_DownloadPageEntry, None, None]:
"""
Enum download entries in a standard Apache directory page
(incl. CPython download page https://www.python.org/ftp/python/)
or a GNU mirror directory page
(https://ftpmirror.gnu.org/<package>/ destinations)
"""
if session is None:
session = requests_html.HTMLSession()
response = session.get(url)
page = response.html
table = page.find("pre", first=True)
# some GNU mirrors format entries as a table
# (e.g. https://mirrors.ibiblio.org/gnu/readline/)
if table is None:
table = page.find("table", first=True)
links = table.find("a")
for link in links:
href = link.attrs['href']
# CPython entries are directories
name = link.text
# skip directory entries
if not (m:=re.match(pattern, name)):
continue
name = make_name(m)
yield cls._DownloadPageEntry(name, urllib.parse.urljoin(response.url, href))
class Re:
@dataclasses.dataclass
class _interval:
group: typing.Union[int, str, None]
start: int
end: int
@staticmethod
def sub_groups(match: re.Match,
/, *args: [typing.AnyStr],
**kwargs: [typing.AnyStr])\
-> typing.AnyStr:
repls={i:repl for i,repl in enumerate(args) if repl is not None}
repls.update({n:repl for n,repl in kwargs.items() if repl is not None})
intervals: sortedcontainers.SortedList[Re._interval]=\
sortedcontainers.SortedKeyList(key=operator.attrgetter("start","end"))
for group_id in itertools.chain(range(1,len(match.groups())), match.groupdict().keys()):
if group_id not in repls:
continue
if match.start(group_id) == -1:
continue
intervals.add(Re._interval(group_id,match.start(group_id),match.end(group_id)))
del group_id
last_interval=Re._interval(None,0,0)
result=""
for interval in intervals:
if interval.start < last_interval.end:
raise ValueError(f"Cannot replace intersecting matches "
f"for groups {last_interval.group} and {interval.group} "
f"(position {interval.start})")
if interval.end == interval.start and \
last_interval.start == last_interval.end == interval.start:
raise ValueError(f"Cannot replace consecutive zero-length matches "
f"for groups {last_interval.group} and {interval.group} "
f"(position {interval.start})")
result+=match.string[last_interval.end:interval.start]+repls[interval.group]
last_interval = interval
result+=match.string[last_interval.end:]
return result
class Url:
@staticmethod
def sha256_url(url, session=None):
if session is None:
session = requests_html.HTMLSession()
logger.info(f"Downloading and computing hash of {url}")
h=hashlib.sha256()
r=session.get(url,stream=True)
total_bytes=int(r.headers.get('content-length',0)) or float('inf')
with tqdm.tqdm(total=total_bytes, unit='B', unit_scale=True, unit_divisor=1024) as t:
for c in r.iter_content(1024):
t.update(len(c))
h.update(c)
return h.hexdigest()
if __name__ == "__main__":
sys.exit(main())

View File

@ -11,18 +11,15 @@ Also ignores sub-patch releases if that major.minor.patch already exists,
but otherwise, takes the latest sub-patch release for given OS/arch. but otherwise, takes the latest sub-patch release for given OS/arch.
Assumes all miniconda3 releases < 4.7 default to python 3.6, and anything else 3.7. Assumes all miniconda3 releases < 4.7 default to python 3.6, and anything else 3.7.
""" """
import logging
import re
import string
import sys
import textwrap import textwrap
from argparse import ArgumentParser from argparse import ArgumentParser
from collections import defaultdict from collections import defaultdict
from dataclasses import dataclass
from enum import Enum from enum import Enum
from functools import total_ordering from functools import total_ordering
from pathlib import Path from pathlib import Path
from typing import NamedTuple, List, Optional, DefaultDict, Dict from typing import NamedTuple, List, Optional, DefaultDict, Dict
import logging
import string
import requests_html import requests_html
@ -32,11 +29,7 @@ CONDA_REPO = "https://repo.anaconda.com"
MINICONDA_REPO = CONDA_REPO + "/miniconda" MINICONDA_REPO = CONDA_REPO + "/miniconda"
ANACONDA_REPO = CONDA_REPO + "/archive" ANACONDA_REPO = CONDA_REPO + "/archive"
auto_accept_tos_fmt="""export CONDA_PLUGINS_AUTO_ACCEPT_TOS=true
""".strip()
install_script_fmt = """ install_script_fmt = """
{auto_accept_tos}
case "$(anaconda_architecture 2>/dev/null || true)" in case "$(anaconda_architecture 2>/dev/null || true)" in
{install_lines} {install_lines}
* ) * )
@ -109,37 +102,21 @@ class Suffix(StrEnum):
NONE = "" NONE = ""
PyVersion = None class PyVersion(StrEnum):
class PyVersionMeta(type): PY27 = "py27"
def __getattr__(self, name): PY36 = "py36"
"""Generate PyVersion.PYXXX on demand to future-proof it""" PY37 = "py37"
if PyVersion is not None: PY38 = "py38"
return PyVersion(name.lower()) PY39 = "py39"
return super(PyVersionMeta,self).__getattr__(self, name) PY310 = "py310"
PY311 = "py311"
@dataclass(frozen=True)
class PyVersion(metaclass=PyVersionMeta):
major: str
minor: str
def __init__(self, value):
(major, minor) = re.match(r"py(\d)(\d+)", value).groups()
object.__setattr__(self, "major", major)
object.__setattr__(self, "minor", minor)
@property
def value(self):
return f"py{self.major}{self.minor}"
def version(self): def version(self):
return f"{self.major}.{self.minor}" first, *others = self.value[2:]
return f"{first}.{''.join(others)}"
def version_info(self): def version_info(self):
return (self.major, self.minor) return tuple(int(n) for n in self.version().split("."))
def __str__(self):
return self.value
@total_ordering @total_ordering
@ -213,17 +190,10 @@ class CondaVersion(NamedTuple):
# https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-python.html # https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-python.html
if v < (4, 7): if v < (4, 7):
return PyVersion.PY36 return PyVersion.PY36
if v < (4, 8):
return PyVersion.PY37
else: else:
# since 4.8, Miniconda specifies versions explicitly in the file name return PyVersion.PY37
raise ValueError("Miniconda 4.8+ is supposed to specify a Python version explicitly")
if self.flavor == "anaconda": if self.flavor == "anaconda":
# https://www.anaconda.com/docs/tools/anaconda-org/release-notes # https://docs.anaconda.com/free/anaconda/reference/release-notes/
if v >= (2025,6):
return PyVersion.PY313
if v >= (2024,6):
return PyVersion.PY312
if v >= (2023,7): if v >= (2023,7):
return PyVersion.PY311 return PyVersion.PY311
if v >= (2023,3): if v >= (2023,3):
@ -240,13 +210,6 @@ class CondaVersion(NamedTuple):
raise ValueError(self.flavor) raise ValueError(self.flavor)
def requires_tos_accept(self):
"""
requires to accept TOS for installation
"""
return self.flavor == Flavor.MINICONDA \
and self.version_str.info() >= (25,)
class CondaSpec(NamedTuple): class CondaSpec(NamedTuple):
tflavor: TFlavor tflavor: TFlavor
@ -283,9 +246,8 @@ class CondaSpec(NamedTuple):
SupportedArch(arch), SupportedArch(arch),
md5, md5,
repo, repo,
py_ver
) )
if py_version is None and py_ver is None and ver != "latest": if py_version is None:
spec = spec.with_py_version(spec.version.default_py_version()) spec = spec.with_py_version(spec.version.default_py_version())
return spec return spec
@ -315,8 +277,7 @@ def make_script(specs: List[CondaSpec]):
return install_script_fmt.format( return install_script_fmt.format(
install_lines="\n".join(install_lines), install_lines="\n".join(install_lines),
tflavor=specs[0].tflavor, tflavor=specs[0].tflavor,
auto_accept_tos = auto_accept_tos_fmt if specs[0].version.requires_tos_accept() else "" )
).lstrip()
def get_existing_condas(name): def get_existing_condas(name):
@ -335,8 +296,8 @@ def get_existing_condas(name):
if v.version_str != "latest": if v.version_str != "latest":
logger.debug("Found existing %(name)s version %(v)s", locals()) logger.debug("Found existing %(name)s version %(v)s", locals())
yield v yield v
except ValueError as e: except ValueError:
logger.error("Unable to parse existing version %s: %s", entry_name, e) logger.error("Unable to parse existing version %s", entry_name)
def get_available_condas(name, repo): def get_available_condas(name, repo):
@ -387,12 +348,19 @@ if __name__ == "__main__":
help="Do not write scripts, just report them to stdout", help="Do not write scripts, just report them to stdout",
) )
parser.add_argument( parser.add_argument(
"-v", "--verbose", action="store_true", default=0, "-v", "--verbose", action="count", default=0,
help="Increase verbosity of logging", help="Increase verbosity of logging",
) )
parsed = parser.parse_args() parsed = parser.parse_args()
logging.basicConfig(level=logging.DEBUG if parsed.verbose else logging.INFO) log_level = {
0: logging.WARNING,
1: logging.INFO,
2: logging.DEBUG,
}.get(parsed.verbose, logging.DEBUG)
logging.basicConfig(level=log_level)
if parsed.verbose < 3:
logging.getLogger("requests").setLevel(logging.WARNING)
existing_versions = set() existing_versions = set()
available_specs = set() available_specs = set()

View File

@ -11,17 +11,8 @@ logger = logging.getLogger(__name__)
logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO')) logging.basicConfig(level=os.environ.get('LOGLEVEL', 'INFO'))
MINIFORGE_REPO = 'conda-forge/miniforge' MINIFORGE_REPO = 'conda-forge/miniforge'
DISTRIBUTIONS = ['miniforge'] PYTHON_VERSION = '310'
DISTRIBUTIONS_PRE25 = ['miniforge', 'mambaforge'] DISTRIBUTIONS = ['miniforge', 'mambaforge']
SKIPPED_RELEASES = [
'4.13.0-0', #has no Mambaforge. We already generated scripts for Miniforge
'22.11.1-0', #MacOS packages are broken (have broken dep tarballs, downloading them fails with 403)
'22.11.1-1', #MacOS packages are broken (have broken dep tarballs, downloading them fails with 403)
'22.11.1-2', #MacOS packages are broken (have broken dep tarballs, downloading them fails with 403)
'25.3.0-0', #marked as prerelease, no Linux version
'25.11.0-0', #regression reported in constructor, re-released as 25.11.0-1 with hotfix bumping to constructor>=3.14 (was >=3.12, 3.13 implicit)
]
install_script_fmt = """ install_script_fmt = """
case "$(anaconda_architecture 2>/dev/null || true)" in case "$(anaconda_architecture 2>/dev/null || true)" in
@ -47,7 +38,7 @@ here = Path(__file__).resolve()
out_dir: Path = here.parent.parent / "share" / "python-build" out_dir: Path = here.parent.parent / "share" / "python-build"
def download_sha(url): def download_sha(url):
logger.info('Downloading SHA file %(url)s', locals()) logger.debug('Downloading SHA file %(url)s', locals())
tup = tuple(reversed(requests.get(url).text.replace('./', '').rstrip().split())) tup = tuple(reversed(requests.get(url).text.replace('./', '').rstrip().split()))
logger.debug('Got %(tup)s', locals()) logger.debug('Got %(tup)s', locals())
return tup return tup
@ -65,7 +56,7 @@ def create_spec(filename, sha, url):
'filename': filename, 'filename': filename,
'sha': sha, 'sha': sha,
'url': url, 'url': url,
'py_version': py_version(version), 'py_version': PYTHON_VERSION,
'flavor': flavor, 'flavor': flavor,
'os': os, 'os': os,
'arch': arch, 'arch': arch,
@ -76,36 +67,16 @@ def create_spec(filename, sha, url):
return spec return spec
def version_tuple(version):
return tuple(int(part) for part in version.split('-')[0].split("."))
def py_version(version):
"""Suffix for `verify_pyXXX` to call in the generated build script"""
version_tuple_ = version_tuple(version)
# current version: mentioned under https://github.com/conda-forge/miniforge?tab=readme-ov-file#requirements-and-installers
# transition points:
# 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
if version_tuple_ >= (24,5):
# yes, they jumped from 3.10 directly to 3.12
# https://github.com/conda-forge/miniforge/commit/bddad0baf22b37cfe079e47fd1680fdfb2183590
return "312"
if version_tuple_ >= (4,14):
return "310"
raise ValueError("Bundled Python version unknown for release `%s'"%version)
def supported(filename): def supported(filename):
return ('pypy' not in filename) and ('Windows' not in filename) return ('pypy' not in filename) and ('Windows' not in filename)
def add_version(release, distributions): def add_version(release):
tag_name = release['tag_name'] tag_name = release['tag_name']
download_urls = { f['name']: f['browser_download_url'] for f in release['assets'] } download_urls = { f['name']: f['browser_download_url'] for f in release['assets'] }
# can assume that sha files are named similar to release files so can also check supported(on their names) shas = dict([download_sha(url) for (name, url) in download_urls.items() if name.endswith('.sha256') and tag_name in name])
shas = dict([download_sha(url) for (name, url) in download_urls.items() if name.endswith('.sha256') and supported(os.path.basename(name)) and tag_name in name])
specs = [create_spec(filename, sha, download_urls[filename]) for (filename, sha) in shas.items() if supported(filename)] specs = [create_spec(filename, sha, download_urls[filename]) for (filename, sha) in shas.items() if supported(filename)]
for distribution in DISTRIBUTIONS:
for distribution in distributions:
distribution_specs = [spec for spec in specs if distribution in spec['flavor'].lower()] distribution_specs = [spec for spec in specs if distribution in spec['flavor'].lower()]
count = len(distribution_specs) count = len(distribution_specs)
@ -124,25 +95,18 @@ def add_version(release, distributions):
else: else:
logger.info('Did not find specs for %(distribution)s', locals()) logger.info('Did not find specs for %(distribution)s', locals())
for release in requests.get(f'https://api.github.com/repos/{MINIFORGE_REPO}/releases').json():
version = release['tag_name']
def main(): logger.info('Looking for %(version)s in %(out_dir)s', locals())
for release in requests.get(f'https://api.github.com/repos/{MINIFORGE_REPO}/releases').json():
version = release['tag_name']
if version in SKIPPED_RELEASES: # This release has no mambaforge artifacts which causes the next check to always trigger.
continue # Build scripts for miniforge3-4.13.0-0 have already been generated.
# Assuming this was a fluke, we don't yet need to implement proactively checking all releases for contents
# or ignoring a release if _any_ of the flavors is already present in Pyenv.
if version == '4.13.0-0':
continue
logger.info('Looking for %(version)s in %(out_dir)s', locals()) if any(not list(out_dir.glob(f'{distribution}*-{version}')) for distribution in DISTRIBUTIONS):
logger.info('Downloading %(version)s', locals())
# mambaforge is retired https://github.com/conda-forge/miniforge/releases/tag/24.11.2-0 add_version(release)
if version_tuple(version) >= (24, 11, 2):
distributions = DISTRIBUTIONS
else:
distributions = DISTRIBUTIONS_PRE25
if any(not list(out_dir.glob(f'{distribution}*-{version}')) for distribution in distributions):
logger.info('Downloading %(version)s', locals())
add_version(release, distributions)
if __name__ == '__main__':
main()

View File

@ -1,9 +1 @@
more_itertools
requests-html requests-html
fake_useragent<2
lxml[html_clean]
packaging
requests
sortedcontainers
tqdm
jc @ git+https://github.com/native-api/jc@haslib_mode

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,9 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-3.2.4" "https://github.com/openssl/openssl/releases/download/openssl-3.2.4/openssl-3.2.4.tar.gz#b23ad7fd9f73e43ad1767e636040e88ba7c9e5775bfa5618436a0dd2c17c3716" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.10.17" "https://www.python.org/ftp/python/3.10.17/Python-3.10.17.tar.xz#4c68050f049d1b4ac5aadd0df5f27941c0350d2a9e7ab0907ee5eb5225d9d6b0" standard verify_py310 copy_python_gdb ensurepip
else
install_package "Python-3.10.17" "https://www.python.org/ftp/python/3.10.17/Python-3.10.17.tgz#8fcda0fbdc131859a4a4223abb925fd522a77e3fb3b52c46cea5f3bc2ae0cd9f" standard verify_py310 copy_python_gdb ensurepip
fi

View File

@ -1,9 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-3.2.4" "https://github.com/openssl/openssl/releases/download/openssl-3.2.4/openssl-3.2.4.tar.gz#b23ad7fd9f73e43ad1767e636040e88ba7c9e5775bfa5618436a0dd2c17c3716" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.10.18" "https://www.python.org/ftp/python/3.10.18/Python-3.10.18.tar.xz#ae665bc678abd9ab6a6e1573d2481625a53719bc517e9a634ed2b9fefae3817f" standard verify_py310 copy_python_gdb ensurepip
else
install_package "Python-3.10.18" "https://www.python.org/ftp/python/3.10.18/Python-3.10.18.tgz#1b19ab802518eb36a851f5ddef571862c7a31ece533109a99df6d5af0a1ceb99" standard verify_py310 copy_python_gdb ensurepip
fi

View File

@ -1,9 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-3.2.4" "https://github.com/openssl/openssl/releases/download/openssl-3.2.4/openssl-3.2.4.tar.gz#b23ad7fd9f73e43ad1767e636040e88ba7c9e5775bfa5618436a0dd2c17c3716" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.10.19" "https://www.python.org/ftp/python/3.10.19/Python-3.10.19.tar.xz#c8f4a596572201d81dd7df91f70e177e19a70f1d489968b54b5fbbf29a97c076" standard verify_py310 copy_python_gdb ensurepip
else
install_package "Python-3.10.19" "https://www.python.org/ftp/python/3.10.19/Python-3.10.19.tgz#a078fb2d7a216071ebbe2e34b5f5355dd6b6e9b0cd1bacc4a41c63990c5a0eec" standard verify_py310 copy_python_gdb ensurepip
fi

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1n" "https://www.openssl.org/source/openssl-1.1.1n.tar.gz#40dceb51a4f6a5275bde0e6bf20ef4b91bfc32ed57c0552e2e8e15463372b17a" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1o" "https://www.openssl.org/source/openssl-1.1.1o.tar.gz#9384a2b0570dd80358841464677115df785edb941c71211f75076d72fe6b438f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline install_package "readline-8.1" "https://ftpmirror.gnu.org/readline/readline-8.1.tar.gz#f8ceb4ee131e3232226a17f51b164afc46cd0b9e6cef344be87c65962cb82b02" mac_readline --if has_broken_mac_readline

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1 export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-1.1.1k" "https://www.openssl.org/source/openssl-1.1.1k.tar.gz#892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1k" "https://www.openssl.org/source/openssl-1.1.1k.tar.gz#892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5" mac_openssl --if has_broken_mac_openssl

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1 export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-1.1.1q" "https://www.openssl.org/source/openssl-1.1.1q.tar.gz#d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1q" "https://www.openssl.org/source/openssl-1.1.1q.tar.gz#d7939ce614029cdff0b6c20f0e2e5703158a489a72b2507b8bd51bf8c8fd10ca" mac_openssl --if has_broken_mac_openssl

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1 export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-1.1.1s" "https://www.openssl.org/source/openssl-1.1.1s.tar.gz#c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1s" "https://www.openssl.org/source/openssl-1.1.1s.tar.gz#c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa" mac_openssl --if has_broken_mac_openssl

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.2.4" "https://github.com/openssl/openssl/releases/download/openssl-3.2.4/openssl-3.2.4.tar.gz#b23ad7fd9f73e43ad1767e636040e88ba7c9e5775bfa5618436a0dd2c17c3716" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.11.12" "https://www.python.org/ftp/python/3.11.12/Python-3.11.12.tar.xz#849da87af4df137710c1796e276a955f7a85c9f971081067c8f565d15c352a09" standard verify_py311 copy_python_gdb ensurepip
else
install_package "Python-3.11.12" "https://www.python.org/ftp/python/3.11.12/Python-3.11.12.tgz#379c9929a989a9d65a1f5d854e011f4872b142259f4fc0a8c4062d2815ed7fba" standard verify_py311 copy_python_gdb ensurepip
fi

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.2.4" "https://github.com/openssl/openssl/releases/download/openssl-3.2.4/openssl-3.2.4.tar.gz#b23ad7fd9f73e43ad1767e636040e88ba7c9e5775bfa5618436a0dd2c17c3716" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.11.13" "https://www.python.org/ftp/python/3.11.13/Python-3.11.13.tar.xz#8fb5f9fbc7609fa822cb31549884575db7fd9657cbffb89510b5d7975963a83a" standard verify_py311 copy_python_gdb ensurepip
else
install_package "Python-3.11.13" "https://www.python.org/ftp/python/3.11.13/Python-3.11.13.tgz#0f1a22f4dfd34595a29cf69ee7ea73b9eff8b1cc89d7ab29b3ab0ec04179dad8" standard verify_py311 copy_python_gdb ensurepip
fi

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.2.4" "https://github.com/openssl/openssl/releases/download/openssl-3.2.4/openssl-3.2.4.tar.gz#b23ad7fd9f73e43ad1767e636040e88ba7c9e5775bfa5618436a0dd2c17c3716" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.11.14" "https://www.python.org/ftp/python/3.11.14/Python-3.11.14.tar.xz#8d3ed8ec5c88c1c95f5e558612a725450d2452813ddad5e58fdb1a53b1209b78" standard verify_py311 copy_python_gdb ensurepip
else
install_package "Python-3.11.14" "https://www.python.org/ftp/python/3.11.14/Python-3.11.14.tgz#563d2a1b2a5ba5d5409b5ecd05a0e1bf9b028cf3e6a6f0c87a5dc8dc3f2d9182" standard verify_py311 copy_python_gdb ensurepip
fi

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1 export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-1.1.1s" "https://www.openssl.org/source/openssl-1.1.1s.tar.gz#c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1s" "https://www.openssl.org/source/openssl-1.1.1s.tar.gz#c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa" mac_openssl --if has_broken_mac_openssl

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1 export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-1.1.1s" "https://www.openssl.org/source/openssl-1.1.1s.tar.gz#c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1s" "https://www.openssl.org/source/openssl-1.1.1s.tar.gz#c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa" mac_openssl --if has_broken_mac_openssl

View File

@ -1,4 +1,4 @@
prefer_openssl3 prefer_openssl11
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1 export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-1.1.1s" "https://www.openssl.org/source/openssl-1.1.1s.tar.gz#c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa" mac_openssl --if has_broken_mac_openssl install_package "openssl-1.1.1s" "https://www.openssl.org/source/openssl-1.1.1s.tar.gz#c5ac01e760ee6ff0dab61d6b2bbd30146724d063eb322180c6f18a6f74e4b6aa" mac_openssl --if has_broken_mac_openssl

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.1.2" "https://www.openssl.org/source/openssl-3.1.2.tar.gz#a0ce69b8b97ea6a35b96875235aa453b966ba3cba8af2de23657d8b6767d6539" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.1.2" "https://www.openssl.org/source/openssl-3.1.2.tar.gz#a0ce69b8b97ea6a35b96875235aa453b966ba3cba8af2de23657d8b6767d6539" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.1.2" "https://www.openssl.org/source/openssl-3.1.2.tar.gz#a0ce69b8b97ea6a35b96875235aa453b966ba3cba8af2de23657d8b6767d6539" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.1.2" "https://www.openssl.org/source/openssl-3.1.2.tar.gz#a0ce69b8b97ea6a35b96875235aa453b966ba3cba8af2de23657d8b6767d6539" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.3.3" "https://github.com/openssl/openssl/releases/download/openssl-3.3.3/openssl-3.3.3.tar.gz#712590fd20aaa60ec75d778fe5b810d6b829ca7fb1e530577917a131f9105539" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.12.10" "https://www.python.org/ftp/python/3.12.10/Python-3.12.10.tar.xz#07ab697474595e06f06647417d3c7fa97ded07afc1a7e4454c5639919b46eaea" standard verify_py312 copy_python_gdb ensurepip
else
install_package "Python-3.12.10" "https://www.python.org/ftp/python/3.12.10/Python-3.12.10.tgz#15d9c623abfd2165fe816ea1fb385d6ed8cf3c664661ab357f1782e3036a6dac" standard verify_py312 copy_python_gdb ensurepip
fi

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.5.1" "https://github.com/openssl/openssl/releases/download/openssl-3.5.1/openssl-3.5.1.tar.gz#529043b15cffa5f36077a4d0af83f3de399807181d607441d734196d889b641f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.12.11" "https://www.python.org/ftp/python/3.12.11/Python-3.12.11.tar.xz#c30bb24b7f1e9a19b11b55a546434f74e739bb4c271a3e3a80ff4380d49f7adb" standard verify_py312 copy_python_gdb ensurepip
else
install_package "Python-3.12.11" "https://www.python.org/ftp/python/3.12.11/Python-3.12.11.tgz#7b8d59af8216044d2313de8120bfc2cc00a9bd2e542f15795e1d616c51faf3d6" standard verify_py312 copy_python_gdb ensurepip
fi

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.5.1" "https://github.com/openssl/openssl/releases/download/openssl-3.5.1/openssl-3.5.1.tar.gz#529043b15cffa5f36077a4d0af83f3de399807181d607441d734196d889b641f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.12.12" "https://www.python.org/ftp/python/3.12.12/Python-3.12.12.tar.xz#fb85a13414b028c49ba18bbd523c2d055a30b56b18b92ce454ea2c51edc656c4" standard verify_py312 copy_python_gdb ensurepip
else
install_package "Python-3.12.12" "https://www.python.org/ftp/python/3.12.12/Python-3.12.12.tgz#487c908ddf4097a1b9ba859f25fe46d22ccaabfb335880faac305ac62bffb79b" standard verify_py312 copy_python_gdb ensurepip
fi

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.2.1" "https://www.openssl.org/source/openssl-3.2.1.tar.gz#83c7329fe52c850677d75e5d0b0ca245309b97e8ecbcfdc1dfdc4ab9fac35b39" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.2.1" "https://www.openssl.org/source/openssl-3.2.1.tar.gz#83c7329fe52c850677d75e5d0b0ca245309b97e8ecbcfdc1dfdc4ab9fac35b39" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.2.1" "https://www.openssl.org/source/openssl-3.2.1.tar.gz#83c7329fe52c850677d75e5d0b0ca245309b97e8ecbcfdc1dfdc4ab9fac35b39" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.2.1" "https://www.openssl.org/source/openssl-3.2.1.tar.gz#83c7329fe52c850677d75e5d0b0ca245309b97e8ecbcfdc1dfdc4ab9fac35b39" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.2.2" "https://www.openssl.org/source/openssl-3.2.2.tar.gz#197149c18d9e9f292c43f0400acaba12e5f52cacfe050f3d199277ea738ec2e7" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.2.2" "https://www.openssl.org/source/openssl-3.2.2.tar.gz#197149c18d9e9f292c43f0400acaba12e5f52cacfe050f3d199277ea738ec2e7" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.3.1" "https://www.openssl.org/source/openssl-3.3.1.tar.gz#777cd596284c883375a2a7a11bf5d2786fc5413255efab20c50d6ffe6d020b7e" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.3.1" "https://www.openssl.org/source/openssl-3.3.1.tar.gz#777cd596284c883375a2a7a11bf5d2786fc5413255efab20c50d6ffe6d020b7e" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.3.2" "https://github.com/openssl/openssl/releases/download/openssl-3.3.2/openssl-3.3.2.tar.gz#2e8a40b01979afe8be0bbfb3de5dc1c6709fedb46d6c89c10da114ab5fc3d281" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.3.2" "https://github.com/openssl/openssl/releases/download/openssl-3.3.2/openssl-3.3.2.tar.gz#2e8a40b01979afe8be0bbfb3de5dc1c6709fedb46d6c89c10da114ab5fc3d281" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.3.2" "https://github.com/openssl/openssl/releases/download/openssl-3.3.2/openssl-3.3.2.tar.gz#2e8a40b01979afe8be0bbfb3de5dc1c6709fedb46d6c89c10da114ab5fc3d281" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.3.2" "https://github.com/openssl/openssl/releases/download/openssl-3.3.2/openssl-3.3.2.tar.gz#2e8a40b01979afe8be0bbfb3de5dc1c6709fedb46d6c89c10da114ab5fc3d281" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.3.2" "https://github.com/openssl/openssl/releases/download/openssl-3.3.2/openssl-3.3.2.tar.gz#2e8a40b01979afe8be0bbfb3de5dc1c6709fedb46d6c89c10da114ab5fc3d281" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.3.2" "https://github.com/openssl/openssl/releases/download/openssl-3.3.2/openssl-3.3.2.tar.gz#2e8a40b01979afe8be0bbfb3de5dc1c6709fedb46d6c89c10da114ab5fc3d281" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,8 +1,7 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1 export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
export PYTHON_BUILD_CONFIGURE_WITH_DSYMUTIL=1 export PYTHON_BUILD_CONFIGURE_WITH_DSYMUTIL=1
install_package "openssl-3.5.1" "https://www.openssl.org/source/openssl-3.5.1.tar.gz#529043b15cffa5f36077a4d0af83f3de399807181d607441d734196d889b641f" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.3.0" "https://www.openssl.org/source/openssl-3.3.0.tar.gz#53e66b043322a606abf0087e7699a0e033a37fa13feb9742df35c3a33b18fb02" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline install_package "readline-8.0" "https://ftpmirror.gnu.org/readline/readline-8.0.tar.gz#e339f51971478d369f8a053a330a190781acb9864cf4c541060f12078948e461" mac_readline --if has_broken_mac_readline
install_git "Python-3.13-dev" "https://github.com/python/cpython" 3.13 standard verify_py313 copy_python_gdb ensurepip install_git "Python-3.13-dev" "https://github.com/python/cpython" 3.13 standard verify_py313 copy_python_gdb ensurepip

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.3.2" "https://github.com/openssl/openssl/releases/download/openssl-3.3.2/openssl-3.3.2.tar.gz#2e8a40b01979afe8be0bbfb3de5dc1c6709fedb46d6c89c10da114ab5fc3d281" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.3.2" "https://github.com/openssl/openssl/releases/download/openssl-3.3.2/openssl-3.3.2.tar.gz#2e8a40b01979afe8be0bbfb3de5dc1c6709fedb46d6c89c10da114ab5fc3d281" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,6 +1,5 @@
prefer_openssl3 prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1 export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.4.0" "https://github.com/openssl/openssl/releases/download/openssl-3.4.0/openssl-3.4.0.tar.gz#e15dda82fe2fe8139dc2ac21a36d4ca01d5313c75f99f46c4e8a27709b7294bf" mac_openssl --if has_broken_mac_openssl install_package "openssl-3.4.0" "https://github.com/openssl/openssl/releases/download/openssl-3.4.0/openssl-3.4.0.tar.gz#e15dda82fe2fe8139dc2ac21a36d4ca01d5313c75f99f46c4e8a27709b7294bf" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then if has_tar_xz_support; then

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.6.0" "https://github.com/openssl/openssl/releases/download/openssl-3.6.0/openssl-3.6.0.tar.gz#b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "http://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.10" "https://www.python.org/ftp/python/3.13.10/Python-3.13.10.tar.xz#bc673c04375a1a3f0808c27ba8f0411ab811ad390a8740318ccb9c60fad8fd77" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.10" "https://www.python.org/ftp/python/3.13.10/Python-3.13.10.tgz#de5930852e95ba8c17b56548e04648470356ac47f7506014664f8f510d7bd61b" standard verify_py313 copy_python_gdb ensurepip
fi

View File

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

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.6.0" "https://github.com/openssl/openssl/releases/download/openssl-3.6.0/openssl-3.6.0.tar.gz#b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "http://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.11" "https://www.python.org/ftp/python/3.13.11/Python-3.13.11.tar.xz#16ede7bb7cdbfa895d11b0642fa0e523f291e6487194d53cf6d3b338c3a17ea2" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.11" "https://www.python.org/ftp/python/3.13.11/Python-3.13.11.tgz#03cfedbe06ce21bc44ce09245e091a77f2fee9ec9be5c52069048a181300b202" standard verify_py313 copy_python_gdb ensurepip
fi

View File

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

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.4.0" "https://github.com/openssl/openssl/releases/download/openssl-3.4.0/openssl-3.4.0.tar.gz#e15dda82fe2fe8139dc2ac21a36d4ca01d5313c75f99f46c4e8a27709b7294bf" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.13.2" "https://www.python.org/ftp/python/3.13.2/Python-3.13.2.tar.xz#d984bcc57cd67caab26f7def42e523b1c015bbc5dc07836cf4f0b63fa159eb56" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.2" "https://www.python.org/ftp/python/3.13.2/Python-3.13.2.tgz#b8d79530e3b7c96a5cb2d40d431ddb512af4a563e863728d8713039aa50203f9" standard verify_py313 copy_python_gdb ensurepip
fi

View File

@ -1,2 +0,0 @@
export PYTHON_BUILD_FREE_THREADING=1
source "$(dirname "${BASH_SOURCE[0]}")"/3.13.2

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.4.1" "https://github.com/openssl/openssl/releases/download/openssl-3.4.1/openssl-3.4.1.tar.gz#002a2d6b30b58bf4bea46c43bdd96365aaf8daa6c428782aa4feee06da197df3" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.13.3" "https://www.python.org/ftp/python/3.13.3/Python-3.13.3.tar.xz#40f868bcbdeb8149a3149580bb9bfd407b3321cd48f0be631af955ac92c0e041" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.3" "https://www.python.org/ftp/python/3.13.3/Python-3.13.3.tgz#988d735a6d33568cbaff1384a65cb22a1fb18a9ecb73d43ef868000193ce23ed" standard verify_py313 copy_python_gdb ensurepip
fi

View File

@ -1,2 +0,0 @@
export PYTHON_BUILD_FREE_THREADING=1
source "$(dirname "${BASH_SOURCE[0]}")"/3.13.3

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.4.1" "https://github.com/openssl/openssl/releases/download/openssl-3.4.1/openssl-3.4.1.tar.gz#002a2d6b30b58bf4bea46c43bdd96365aaf8daa6c428782aa4feee06da197df3" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.13.4" "https://www.python.org/ftp/python/3.13.4/Python-3.13.4.tar.xz#27b15a797562a2971dce3ffe31bb216042ce0b995b39d768cf15f784cc757365" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.4" "https://www.python.org/ftp/python/3.13.4/Python-3.13.4.tgz#2666038f1521b7a8ec34bf2997b363778118d6f3979282c93723e872bcd464e0" standard verify_py313 copy_python_gdb ensurepip
fi

View File

@ -1,2 +0,0 @@
export PYTHON_BUILD_FREE_THREADING=1
source "$(dirname "${BASH_SOURCE[0]}")"/3.13.4

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.5.1" "https://github.com/openssl/openssl/releases/download/openssl-3.5.1/openssl-3.5.1.tar.gz#529043b15cffa5f36077a4d0af83f3de399807181d607441d734196d889b641f" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.2" "https://ftpmirror.gnu.org/readline/readline-8.2.tar.gz#3feb7171f16a84ee82ca18a36d7b9be109a52c04f492a053331d7d1095007c35" mac_readline --if has_broken_mac_readline
if has_tar_xz_support; then
install_package "Python-3.13.5" "https://www.python.org/ftp/python/3.13.5/Python-3.13.5.tar.xz#93e583f243454e6e9e4588ca2c2662206ad961659863277afcdb96801647d640" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.5" "https://www.python.org/ftp/python/3.13.5/Python-3.13.5.tgz#e6190f52699b534ee203d9f417bdbca05a92f23e35c19c691a50ed2942835385" standard verify_py313 copy_python_gdb ensurepip
fi

View File

@ -1,2 +0,0 @@
export PYTHON_BUILD_FREE_THREADING=1
source "$(dirname "${BASH_SOURCE[0]}")"/3.13.5

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.5.2" "https://github.com/openssl/openssl/releases/download/openssl-3.5.2/openssl-3.5.2.tar.gz#c53a47e5e441c930c3928cf7bf6fb00e5d129b630e0aa873b08258656e7345ec" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "http://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.6" "https://www.python.org/ftp/python/3.13.6/Python-3.13.6.tar.xz#17ba5508819d8736a14fbfc47d36e184946a877851b2e9c4b6c43acb44a3b104" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.6" "https://www.python.org/ftp/python/3.13.6/Python-3.13.6.tgz#6cf50672cc03928488817d45af24bc927a48f910fe7893d6f388130e59ba98d7" standard verify_py313 copy_python_gdb ensurepip
fi

View File

@ -1,2 +0,0 @@
export PYTHON_BUILD_FREE_THREADING=1
source "$(dirname "${BASH_SOURCE[0]}")"/3.13.6

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.5.2" "https://github.com/openssl/openssl/releases/download/openssl-3.5.2/openssl-3.5.2.tar.gz#c53a47e5e441c930c3928cf7bf6fb00e5d129b630e0aa873b08258656e7345ec" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "http://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.7" "https://www.python.org/ftp/python/3.13.7/Python-3.13.7.tar.xz#5462f9099dfd30e238def83c71d91897d8caa5ff6ebc7a50f14d4802cdaaa79a" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.7" "https://www.python.org/ftp/python/3.13.7/Python-3.13.7.tgz#6c9d80839cfa20024f34d9a6dd31ae2a9cd97ff5e980e969209746037a5153b2" standard verify_py313 copy_python_gdb ensurepip
fi

View File

@ -1,2 +0,0 @@
export PYTHON_BUILD_FREE_THREADING=1
source "$(dirname "${BASH_SOURCE[0]}")"/3.13.7

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.6.0" "https://github.com/openssl/openssl/releases/download/openssl-3.6.0/openssl-3.6.0.tar.gz#b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "http://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.8" "https://www.python.org/ftp/python/3.13.8/Python-3.13.8.tar.xz#b9910730526b298299b46b35595ced9055722df60c06ad6301f6a4e2c728a252" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.8" "https://www.python.org/ftp/python/3.13.8/Python-3.13.8.tgz#06108fe96f4089b7d9e0096cb4ca9c81ddcd5135f779a7de94cf59abcaa4b53f" standard verify_py313 copy_python_gdb ensurepip
fi

View File

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

View File

@ -1,10 +0,0 @@
prefer_openssl3
export PYTHON_BUILD_CONFIGURE_WITH_OPENSSL=1
export PYTHON_BUILD_TCLTK_USE_PKGCONFIG=1
install_package "openssl-3.6.0" "https://github.com/openssl/openssl/releases/download/openssl-3.6.0/openssl-3.6.0.tar.gz#b6a5f44b7eb69e3fa35dbf15524405b44837a481d43d81daddde3ff21fcbb8e9" mac_openssl --if has_broken_mac_openssl
install_package "readline-8.3" "http://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.9" "https://www.python.org/ftp/python/3.13.9/Python-3.13.9.tar.xz#ed5ef34cda36cfa2f3a340f07cac7e7814f91c7f3c411f6d3562323a866c5c66" standard verify_py313 copy_python_gdb ensurepip
else
install_package "Python-3.13.9" "https://www.python.org/ftp/python/3.13.9/Python-3.13.9.tgz#c4c066af19c98fb7835d473bebd7e23be84f6e9874d47db9e39a68ee5d0ce35c" standard verify_py313 copy_python_gdb ensurepip
fi

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